Support array result include sequence action (#92)

diff --git a/README.md b/README.md
index 20e97b2..c0406b2 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,21 @@
 '#!/bin/bash
 echo "{\"message\":\"Hello World\"}"' > exec
 ```
+
+For the return result, not only support `dictionary` but also support `array`
+```
+echo \
+'#!/bin/bash
+echo '["a", "b"]'' > exec
+```
+
+And support array result for sequence action as well, the first action's array result can be used as next action's input parameter
+```
+echo \
+'#!/bin/bash
+echo $1' > exec
+```
+
 ```
 chmod +x exec
 zip myAction.zip exec
diff --git a/core/actionProxy/actionproxy.py b/core/actionProxy/actionproxy.py
index 1812918..d174ce0 100644
--- a/core/actionProxy/actionproxy.py
+++ b/core/actionProxy/actionproxy.py
@@ -135,7 +135,7 @@
         def error(msg):
             # fall through (exception and else case are handled the same way)
             sys.stdout.write('%s\n' % msg)
-            return (502, {'error': 'The action did not return a dictionary.'})
+            return (502, {'error': 'The action did not return a dictionary or array.'})
 
         try:
             input = json.dumps(args)
@@ -186,7 +186,7 @@
 
         try:
             json_output = json.loads(lastLine)
-            if isinstance(json_output, dict):
+            if isinstance(json_output, dict) or isinstance(json_output, list):
                 return (200, json_output)
             else:
                 return error(lastLine)
@@ -258,7 +258,7 @@
 
 def run(message=None):
     def error():
-        response = flask.jsonify({'error': 'The action did not receive a dictionary as an argument.'})
+        response = flask.jsonify({'error': 'The action did not receive a dictionary or array as an argument.'})
         response.status_code = 404
         return complete(response)
 
@@ -269,7 +269,7 @@
         return error()
     else:
         args = message.get('value', {}) if message else {}
-        if not isinstance(args, dict):
+        if not (isinstance(args, dict) or isinstance(args, list)):
             return error()
 
     if runner.verify():
diff --git a/tests/src/test/scala/runtime/actionContainers/ActionProxyContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/ActionProxyContainerTests.scala
index acf83b9..97e6227 100644
--- a/tests/src/test/scala/runtime/actionContainers/ActionProxyContainerTests.scala
+++ b/tests/src/test/scala/runtime/actionContainers/ActionProxyContainerTests.scala
@@ -227,7 +227,7 @@
       initCode should be(200)
       val (runCode, out) = c.run(JsNull)
       runCode should be(502)
-      out should be(Some(JsObject("error" -> JsString("The action did not return a dictionary."))))
+      out should be(Some(JsObject("error" -> JsString("The action did not return a dictionary or array."))))
     }
 
     checkStreams(out, err, {
@@ -270,4 +270,37 @@
       runRes.get.fields.get("pwd_cmd") shouldBe Some(JsString("/action"))
     }
   }
+
+  it should "support return array result" in {
+    withActionContainer() { c =>
+      val code = """
+                   |#!/bin/bash
+                   |echo '["a", "b"]'
+                 """.stripMargin.trim
+
+      val (initCode, initRes) = c.init(initPayload(code))
+      initCode should be(200)
+
+      val (runCode, runRes) = c.runForJsArray(runPayload(JsObject()))
+      runCode should be(200)
+      runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
+    }
+  }
+
+  it should "support array as input param" in {
+    withActionContainer() { c =>
+      val code = """
+                   |#!/bin/bash
+                   |arr=$1
+                   |echo $arr
+                 """.stripMargin.trim
+
+      val (initCode, initRes) = c.init(initPayload(code))
+      initCode should be(200)
+
+      val (runCode, runRes) = c.runForJsArray(runPayload(JsArray(JsString("a"), JsString("b"))))
+      runCode should be(200)
+      runRes shouldBe Some(JsArray(JsString("a"), JsString("b")))
+    }
+  }
 }