SLING-9751 allow multi line commands
diff --git a/src/main/java/org/apache/sling/pipes/internal/CommandExecutorImpl.java b/src/main/java/org/apache/sling/pipes/internal/CommandExecutorImpl.java
index ade81a2..198e94d 100644
--- a/src/main/java/org/apache/sling/pipes/internal/CommandExecutorImpl.java
+++ b/src/main/java/org/apache/sling/pipes/internal/CommandExecutorImpl.java
@@ -79,6 +79,7 @@
     static final String WHITE_SPACE_SEPARATOR = "\\s";
     static final String COMMENT_PREFIX = "#";
     static final String SEPARATOR = "|";
+    static final String LINE_SEPARATOR = " ";
     static final String PARAMS = "@";
     static final String KEY_VALUE_SEP = "=";
     static final String FIRST_TOKEN = "first";
@@ -128,17 +129,24 @@
             InputStream is = request.getRequestParameter(REQ_PARAM_FILE).getInputStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
             String line;
+            StringBuilder cmdBuilder = new StringBuilder();
             while ((line = reader.readLine()) != null) {
                 if (isCommandCandidate(line)) {
-                    cmds.add(line);
+                    cmdBuilder.append(LINE_SEPARATOR + line.trim());
+                } else if (cmdBuilder.length() > 0){
+                    cmds.add(cmdBuilder.toString().trim());
+                    cmdBuilder = new StringBuilder();
                 }
             }
+            if (cmdBuilder.length() > 0) {
+                cmds.add(cmdBuilder.toString().trim());
+            }
         }
         return cmds;
     }
 
     @Override
-    protected void doPost(@NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws ServletException, IOException {
+    protected void doPost(@NotNull SlingHttpServletRequest request, @NotNull SlingHttpServletResponse response) throws IOException {
         String currentCommand = null;
         PrintWriter writer = response.getWriter();
         try {
diff --git a/src/test/java/org/apache/sling/pipes/internal/CommandExecutorImplTest.java b/src/test/java/org/apache/sling/pipes/internal/CommandExecutorImplTest.java
index 346b346..769a06f 100644
--- a/src/test/java/org/apache/sling/pipes/internal/CommandExecutorImplTest.java
+++ b/src/test/java/org/apache/sling/pipes/internal/CommandExecutorImplTest.java
@@ -174,15 +174,19 @@
     }
 
     @Test
-    public void testFileCommandServlet() throws IOException, ServletException {
+    public void testMultipeLineGetCommandLine() throws IOException, ServletException {
         Map<String, Object> params = new HashMap<>();
-        params.put(CommandExecutorImpl.REQ_PARAM_FILE, IOUtils.toString(getClass().getResourceAsStream("/testcommand"
+        params.put(CommandExecutorImpl.REQ_PARAM_FILE, IOUtils.toString(getClass().getResourceAsStream("/commandsFormats"
             + ".txt"), "UTF-8"));
-        String response = testServlet(params);
-        assertEquals("{\"items\":[\"/content/beatles/john\",\"/content/beatles/paul\","
-            + "\"/content/beatles/georges\",\"/content/beatles/ringo\"],"
-            + "\"size\":4}\n"
-            + "{\"items\":[\"/content/beatles/ringo/jcr:content\"],\"size\":1}\n", response);
+        MockSlingHttpServletRequest request = context.request();
+        request.setParameterMap(params);
+        request.setMethod("POST");
+        List<String> cmdList = commands.getCommandList(context.request());
+        assertEquals(4, cmdList.size());
+        for (int i = 0; i < 3; i ++) {
+            assertEquals("echo /content | $ /apps/pipes-it/fruit | children nt:unstructured", cmdList.get(i));
+        }
+        assertEquals ("echo /content | write one=foo nested/two=foo nested/three=foo", cmdList.get(3));
     }
 
     @Test
@@ -196,4 +200,16 @@
             + "\"/content/fruits/apple/isnota/pea\",\"/content/fruits/apple/isnota/plum\","
             + "\"/content/fruits/apple/isnota/carrot\"],\"size\":5}\n", response);
     }
+
+    @Test
+    public void testFileCommandServlet() throws IOException, ServletException {
+        Map<String, Object> params = new HashMap<>();
+        params.put(CommandExecutorImpl.REQ_PARAM_FILE, IOUtils.toString(getClass().getResourceAsStream("/testcommand"
+            + ".txt"), "UTF-8"));
+        String response = testServlet(params);
+        assertEquals("{\"items\":[\"/content/beatles/john\",\"/content/beatles/paul\","
+            + "\"/content/beatles/georges\",\"/content/beatles/ringo\"],"
+            + "\"size\":4}\n"
+            + "{\"items\":[\"/content/beatles/ringo/jcr:content\"],\"size\":1}\n", response);
+    }
 }
\ No newline at end of file
diff --git a/src/test/resources/commandsFormats.txt b/src/test/resources/commandsFormats.txt
new file mode 100644
index 0000000..505ce48
--- /dev/null
+++ b/src/test/resources/commandsFormats.txt
@@ -0,0 +1,30 @@
+#
+# 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.
+
+echo /content | $ /apps/pipes-it/fruit | children nt:unstructured
+
+echo /content
+| $ /apps/pipes-it/fruit
+| children nt:unstructured
+
+echo /content |
+$ /apps/pipes-it/fruit |
+children nt:unstructured
+
+echo /content |
+write one=foo
+nested/two=foo
+nested/three=foo
\ No newline at end of file