diff --git a/settings.gradle b/settings.gradle
index 1955feb..868fcd7 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -8,6 +8,7 @@
 include 'core:pythonAction'
 include 'core:python2Action'
 include 'core:swift3Action'
+include 'core:swift3.1.1Action'
 include 'core:javaAction'
 
 include 'tools:cli'
diff --git a/tests/build.gradle b/tests/build.gradle
index 21ab9f8..f80e47e 100644
--- a/tests/build.gradle
+++ b/tests/build.gradle
@@ -32,6 +32,7 @@
     ':core:python2Action:distDocker',
     ':core:javaAction:distDocker',
     ':core:swift3Action:distDocker',
+    ':core:swift3.1.1Action:distDocker',
     ':sdk:docker:distDocker',
     ':tests:dat:blackbox:badaction:distDocker',
     ':tests:dat:blackbox:badproxy:distDocker'
diff --git a/tests/src/test/scala/actionContainers/ActionContainer.scala b/tests/src/test/scala/actionContainers/ActionContainer.scala
index 4f00e7c..f74f3c4 100644
--- a/tests/src/test/scala/actionContainers/ActionContainer.scala
+++ b/tests/src/test/scala/actionContainers/ActionContainer.scala
@@ -178,11 +178,11 @@
         val f = for (
             entity <- Marshal(content).to[MessageEntity];
             request = HttpRequest(method = HttpMethods.POST, uri = uri, entity = entity);
-            response <- AkkaHttpUtils.singleRequest(request, 60.seconds, retryOnTCPErrors = true);
+            response <- AkkaHttpUtils.singleRequest(request, 90.seconds, retryOnTCPErrors = true);
             responseBody <- Unmarshal(response.entity).to[String]
         ) yield (response.status.intValue, Try(responseBody.parseJson.asJsObject).toOption)
 
-        Await.result(f, 1.minute)
+        Await.result(f, 90.seconds)
     }
 
     private class ActionContainerImpl() extends ActionContainer {
diff --git a/tests/src/test/scala/actionContainers/SwiftActionContainerTests.scala b/tests/src/test/scala/actionContainers/SwiftActionContainerTests.scala
deleted file mode 100644
index c07ef75..0000000
--- a/tests/src/test/scala/actionContainers/SwiftActionContainerTests.scala
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package actionContainers
-
-import java.io.File
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-
-import ActionContainer.withContainer
-import common.WskActorSystem
-import spray.json.JsObject
-import spray.json.JsString
-import common.TestUtils
-
-@RunWith(classOf[JUnitRunner])
-class SwiftActionContainerTests extends BasicActionRunnerTests with WskActorSystem {
-
-    // note: "out" will likely not be empty in some swift build as the compiler
-    // prints status messages and there doesn't seem to be a way to quiet them
-    val enforceEmptyOutputStream = false
-    lazy val swiftContainerImageName = "swift3action"
-    lazy val envCode = makeEnvCode("ProcessInfo.processInfo")
-
-    def makeEnvCode(processInfo: String) = ("""
-         |func main(args: [String: Any]) -> [String: Any] {
-         |     let env = """ + processInfo + """.environment
-         |     var a = "???"
-         |     var b = "???"
-         |     var c = "???"
-         |     var d = "???"
-         |     var e = "???"
-         |     var f = "???"
-         |     if let v : String = env["__OW_API_HOST"] {
-         |         a = "\(v)"
-         |     }
-         |     if let v : String = env["__OW_API_KEY"] {
-         |         b = "\(v)"
-         |     }
-         |     if let v : String = env["__OW_NAMESPACE"] {
-         |         c = "\(v)"
-         |     }
-         |     if let v : String = env["__OW_ACTION_NAME"] {
-         |         d = "\(v)"
-         |     }
-         |     if let v : String = env["__OW_ACTIVATION_ID"] {
-         |         e = "\(v)"
-         |     }
-         |     if let v : String = env["__OW_DEADLINE"] {
-         |         f = "\(v)"
-         |     }
-         |     return ["api_host": a, "api_key": b, "namespace": c, "action_name": d, "activation_id": e, "deadline": f]
-         |}
-         """).stripMargin
-
-    lazy val errorCode = """
-                | // You need an indirection, or swiftc detects the div/0
-                | // at compile-time. Smart.
-                | func div(x: Int, y: Int) -> Int {
-                |     return x/y
-                | }
-                | func main(args: [String: Any]) -> [String: Any] {
-                |     return [ "divBy0": div(x:5, y:0) ]
-                | }
-            """.stripMargin
-
-    // Helpers specific to swift actions
-    override def withActionContainer(env: Map[String, String] = Map.empty)(code: ActionContainer => Unit) = {
-        withContainer(swiftContainerImageName, env)(code)
-    }
-
-    behavior of swiftContainerImageName
-
-    // remove this test: it will not even compile under Swift 3 anymore
-    // so it should not be possible to write an action that does not return
-    // a [String:Any]
-    /*testNotReturningJson(
-        """
-        |func main(args: [String: Any]) -> String {
-        |    return "not a json object"
-        |}
-        """.stripMargin)
-    */
-
-    testEcho(Seq {
-        ("swift", """
-         | import Foundation
-         |
-         | extension FileHandle : TextOutputStream {
-         |     public func write(_ string: String) {
-         |         guard let data = string.data(using: .utf8) else { return }
-         |         self.write(data)
-         |     }
-         | }
-         |
-         | func main(args: [String: Any]) -> [String: Any] {
-         |     print("hello stdout")
-         |     var standardError = FileHandle.standardError
-         |     print("hello stderr", to: &standardError)
-         |     return args
-         | }
-        """.stripMargin)
-    })
-
-    testUnicode(Seq {
-        ("swift", """
-         | func main(args: [String: Any]) -> [String: Any] {
-         |     if let str = args["delimiter"] as? String {
-         |         let msg = "\(str) ☃ \(str)"
-         |         print(msg)
-         |         return [ "winter" : msg ]
-         |     } else {
-         |         return [ "error" : "no delimiter" ]
-         |     }
-         | }
-         """.stripMargin.trim)
-    })
-
-    testEnv(Seq {
-        ("swift", envCode)
-    }, enforceEmptyOutputStream)
-
-    it should "support actions using non-default entry points" in {
-        withActionContainer() { c =>
-            val code = """
-                | func niam(args: [String: Any]) -> [String: Any] {
-                |     return [ "result": "it works" ]
-                | }
-                |""".stripMargin
-
-            val (initCode, initRes) = c.init(initPayload(code, main = "niam"))
-            initCode should be(200)
-
-            val (_, runRes) = c.run(runPayload(JsObject()))
-            runRes.get.fields.get("result") shouldBe Some(JsString("it works"))
-        }
-    }
-
-    it should "return some error on action error" in {
-        val (out, err) = withActionContainer() { c =>
-            val code = errorCode
-
-            val (initCode, _) = c.init(initPayload(code))
-            initCode should be(200)
-
-            val (runCode, runRes) = c.run(runPayload(JsObject()))
-            runCode should be(502)
-
-            runRes shouldBe defined
-            runRes.get.fields.get("error") shouldBe defined
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-
-    it should "log compilation errors" in {
-        val (out, err) = withActionContainer() { c =>
-            val code = """
-              | 10 PRINT "Hello!"
-              | 20 GOTO 10
-            """.stripMargin
-
-            val (initCode, _) = c.init(initPayload(code))
-            initCode should not be (200)
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e.toLowerCase should include("error")
-        })
-    }
-
-    it should "support application errors" in {
-        val (out, err) = withActionContainer() { c =>
-            val code = """
-                | func main(args: [String: Any]) -> [String: Any] {
-                |     return [ "error": "sorry" ]
-                | }
-            """.stripMargin
-
-            val (initCode, _) = c.init(initPayload(code))
-            initCode should be(200)
-
-            val (runCode, runRes) = c.run(runPayload(JsObject()))
-            runCode should be(200) // action writer returning an error is OK
-
-            runRes shouldBe defined
-            runRes should be(Some(JsObject("error" -> JsString("sorry"))))
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-
-    it should "support support multiple files in a zip file" in {
-        val zip = new File(TestUtils.getTestActionFilename("multiSwift.zip")).toPath
-        val code = ResourceHelpers.readAsBase64(zip)
-
-        val (out, err) = withActionContainer() { c =>
-            val (initCode, initRes) = c.init(initPayload(code))
-            initCode should be(200)
-
-            val args = JsObject()
-            val (runCode, runRes) = c.run(runPayload(args))
-
-            runCode should be(200)
-            runRes.get shouldBe JsObject("greeting" -> (JsString("Hello stranger!")))
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-            	if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-
-    it should "support pre-compiled binary in a zip file" in {
-        val zip = new File(TestUtils.getTestActionFilename("helloSwift.zip")).toPath
-        val code = ResourceHelpers.readAsBase64(zip)
-
-        val (out, err) = withActionContainer() { c =>
-            val (initCode, initRes) = c.init(initPayload(code))
-            initCode should be(200)
-
-            val args = JsObject()
-            val (runCode, runRes) = c.run(runPayload(args))
-
-            runCode should be(200)
-            runRes.get shouldBe JsObject("greeting" -> (JsString("Hello stranger!")))
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-
-    it should "properly use KituraNet and Dispatch" in {
-        val (out, err) = withActionContainer() { c =>
-            val code = """
-                | import KituraNet
-                | import Foundation
-                | import Dispatch
-                | func main(args:[String: Any]) -> [String:Any] {
-                |       let retries = 3
-                |       var resp = [String:Any]()
-                |       var attempts = 0
-                |       if let url = args["getUrl"] as? String {
-                |           while attempts < retries {
-                |               let group = DispatchGroup()
-                |               let queue = DispatchQueue.global(qos: .default)
-                |               group.enter()
-                |               queue.async {
-                |                   HTTP.get(url, callback: { response in
-                |                       if let response = response {
-                |                           do {
-                |                               var jsonData = Data()
-                |                               try response.readAllData(into: &jsonData)
-                |                               if let dic = WhiskJsonUtils.jsonDataToDictionary(jsonData: jsonData) {
-                |                                   resp = dic
-                |                               } else {
-                |                                   resp = ["error":"response from server is not JSON"]
-                |                               }
-                |                           } catch {
-                |                              resp["error"] = error.localizedDescription
-                |                           }
-                |                       }
-                |                       group.leave()
-                |                   })
-                |               }
-                |            switch group.wait(timeout: DispatchTime.distantFuture) {
-                |                case DispatchTimeoutResult.success:
-                |                    resp["attempts"] = attempts
-                |                    return resp
-                |                case DispatchTimeoutResult.timedOut:
-                |                    attempts = attempts + 1
-                |            }
-                |        }
-                |     }
-                |     return ["status":"Exceeded \(retries) attempts, aborting."]
-                | }
-            """.stripMargin
-
-            val (initCode, _) = c.init(initPayload(code))
-
-            initCode should be(200)
-
-            val argss = List(
-                JsObject("getUrl" -> JsString("https://openwhisk.ng.bluemix.net/api/v1")))
-
-            for (args <- argss) {
-                val (runCode, out) = c.run(runPayload(args))
-                runCode should be(200)
-            }
-        }
-
-        // in side try catch finally print (out file)
-        // in catch block an error has occurred, get docker logs and print
-        // throw
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-
-    it should "make Watson SDKs available to action authors" in {
-        val (out, err) = withActionContainer() { c =>
-            val code = """
-                | import RestKit
-                | import WeatherCompanyData
-                | import AlchemyVision
-                |
-                | func main(args: [String:Any]) -> [String:Any] {
-                |     return ["message": "I compiled and was able to import Watson SDKs"]
-                | }
-            """.stripMargin
-
-            val (initCode, _) = c.init(initPayload(code))
-
-            initCode should be(200)
-
-            val (runCode, out) = c.run(runPayload(JsObject()))
-            runCode should be(200)
-        }
-
-        checkStreams(out, err, {
-            case (o, e) =>
-                if (enforceEmptyOutputStream) o shouldBe empty
-                e shouldBe empty
-        })
-    }
-}
