diff --git a/Protocols.md b/Protocols.md
new file mode 100644
index 0000000..01a91a9
--- /dev/null
+++ b/Protocols.md
@@ -0,0 +1,113 @@
+# Protocols
+
+Many of these protocols are documented elsewhere, however this document is with the source code and so hopefully uptodate.
+
+There is also published documentation at the following locations which may lag the code and this document. This document wont
+reproduce the information in the following locations, but will note differences when they are discovered.
+
+https://sling.apache.org/documentation/bundles/manipulating-content-the-slingpostservlet-servlets-post.html
+https://cwiki.apache.org/confluence/display/SLING/Chunked+File+Upload+Support
+
+# Request Processing.
+
+In general a request is processed by the Sling Engine encapsulating the data in Sling API interfaces. See the above locations
+for more information on how that works.
+
+# Uploads
+
+The default Sling Post servlets support both streamed and non streamed uploads. Non streamed uploads are processed by the
+Sling Engine request processing mechanisms before the information is passed to the the Servlet. While this is more flexible
+as the client developer does not have to think about the order of the parameters, it is less efficient as file bodies must
+be read completely before processing. This leads to more IO. Streaming uploads on the other hand read the request stream
+as it is send from the client and process it as it is read. This avoids some of the additional IO, but requires more attention
+to detain by a client developer as the parts of the post must arrive in teh correct order. Streaming is the preference method
+of upload where large files are involved.
+
+# Non streamed uploads.
+
+## Whole body uploads.
+
+See https://sling.apache.org/documentation/bundles/manipulating-content-the-slingpostservlet-servlets-post.html
+no known variance from the published documentation.
+
+## Sling Chunked body uploads.
+
+Note "Chunked" in this context is a special Sling protocol represented in request parameters intended to allow the client
+to upload chunks of a file to Sling. The protocol protects agains multiple clients perfoming an upload on the same resource, 
+but does not support multiple clients performing chunked uploads at the same time. Multiple requests are used, multiple chunks cannont
+generally be sent in a single request.
+See https://cwiki.apache.org/confluence/display/SLING/Chunked+File+Upload+Support.
+
+Chunked uploads are supported by writing the data to special sub nodes of the nt:resource node and when the chunks are complete the subnodes are
+read back in sequence creating the final binary. If chunks are send in the wrong order, the chunk is rejected.
+
+The definition of the chunknode differs from the published documentation.
+
+        // node type to store chunk
+        // offset: offset of chunk in file
+        // jcr:data: binary of chunk
+        [sling:chunk] > nt:hierarchyNode
+          primaryitem jcr:data
+          - sling:offset  (long) mandatory
+          - jcr:data (binary) mandatory
+          
+         //-----------------------------------------------------------------------------
+         // Mixin node type to identify that a node has chunks
+         // sling:fileLength : length of complete file
+         // sling:length : cumulative length of all uploaded chunks
+        [sling:chunks]
+          mixin
+          - sling:fileLength (long)
+          - sling:length (long)
+          + * (sling:chunk) multiple
+
+
+
+# Streamed uploads
+
+Streamed uploads were implemented under the following issues.
+
+https://issues.apache.org/jira/browse/SLING-5948
+https://issues.apache.org/jira/browse/SLING-6017
+https://issues.apache.org/jira/browse/SLING-6027
+
+For streaming to work the Sling Engine must not read the parts of the request. This is achieved by appending a request parameter 
+to the URL "uploadmode=stream" or adding a Header "Sling-uploadmode: stream". When that is done the Sling Engine does not 
+read the request, but provides a Iterator<Parts> in a request attribute (request-parts-iterator) that will provide each part as it
+is sent from the client. In this mode the SlingDefaultPost Servlet invokes the StreamedUploadOperation which iterates through the Parts.
+
+The StreamedUploadOperation does not support the standard Sling Post protocol. Any node that need to be created with non standard properties 
+or structure should be created in a seperate POST. If the node PrimaryType needs to be non standard, that POST operation should be before
+any upload is performed.
+
+## Full body streamed uploads.
+
+Full body streamed uploads are performed by a normal file upload. The name of the part is used as the File name. The location of the POST is the parent 
+resource which should already exist. If the name of the part is "*" then the supplied name of the file upload is used as the name of the resource. This is 
+the same as non streamed full body uploads. The behaviour is specific to Sling and may not be the same as adopeted by other systems.
+
+## Chunked streamed uploads.
+
+Chunked streamed upload are also supported with some subtle variations. Since the length of a body part cant be known until it has been fully streamed, a streaming
+chunked upload must specify the length of the body part prior to sending the body part. This can be achieved by in one of 3 ways. Sending a <name>@PartLength form field prior
+to the part to indicate the length of the Part. Setting a Content-Length header on the part itself, or using a Content-Range header on the part itself. If all of these are missing,
+processing assumes that the body part is the last body part in the file and truncates the file to that length, processing all parts so far.
+Unlike the non streamed chunked upload protocol, the streamed upload protocol can accept multiple body parts in 1 request. Each body part
+must be immediately preceded by the correct request parameters. (ie new @Offset if using Form fields).
+
+### Via request parameters.
+
+The standard Sling Chunked Upload protocol uses request parameters of the form <name>@Length indicating the final length
+of the file and <name>@Offset indicating the offset of the next body part and <name>@PartLength to indicate the 
+length of the part. <name>@PartLength is in addition to the nonstreamed protocol. <name> is the name of the body part 
+that follows. If any of these parameters are present in the request when a part is encountered, chunked processing is performed. 
+The chunk processing will detect when all the chunks have been send and perform final processing.
+
+### Via Content-Range headers
+
+Content Range headers are a part of the Http 1.1 Standard documented at https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html section 14.16. 
+If Content Range headers are provided on each Body part they are used in prefence to the propriatary Sling Chunk Upload protocol. This approach 
+is used by other resuable and chunked upload apis notably the Google Drive API. If content range headers are used, each part is self contained
+and no other request parameters or headers are are required. There is an expectation that a content range header will use the form
+"Content-Range: bytes 1234-2345/6789" specifying the full lenght and not the form  "Content-Range: bytes 1234-2345/*" which implies a length of 2345.
+
diff --git a/README.txt b/README.txt
index ca88f5b..594cc5d 100644
--- a/README.txt
+++ b/README.txt
@@ -25,3 +25,6 @@
 
 See the Subversion documentation for other source control features.
 
+
+
+
diff --git a/developer-tests/README.md b/developer-tests/README.md
new file mode 100644
index 0000000..bd318a5
--- /dev/null
+++ b/developer-tests/README.md
@@ -0,0 +1,12 @@
+# Developer test scripts.
+
+Testing POST behaviour can involve a lot of curl commands or browser work, expecially with file uploads. 
+This folder contains test scripts that verify the behaviour of this bundle in a running Sling instance. 
+They are not intended as a replacement for unit tests or integration tests, but rather a quick way to allow
+a developer to verify behaviour and be in control of the test being run.
+
+## testFileUploads.sh
+run in parent as sh developer-tests/testFileUploads.sh <testfile> and it will upload that file using non streamed, 
+ streamed, and streaming chunked protocols to the Sling server on localhost:8080 as admin:admin. It will also download 
+ the file and diff it against the local copy to ensure no changes. Chunks are 20kb each, so a large file will generate a
+ large number of small chunks. Dont try and test a GB file without editing the script to increase the chunk size.
\ No newline at end of file
diff --git a/developer-tests/testFileUploads.sh b/developer-tests/testFileUploads.sh
new file mode 100644
index 0000000..0179a5e
--- /dev/null
+++ b/developer-tests/testFileUploads.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+#
+# 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.
+
+set -e
+mkdir -p target
+cd target
+echo Creating file via normal non streamed upload
+cp $1 P1060839.jpg
+curl -v -F P1060839.jpg=@P1060839.jpg http://admin:admin@localhost:8080/content/test
+curl http://admin:admin@localhost:8080/content/test/P1060839.jpg > P1060839_up.jpg 
+echo Checking normal upload.
+diff P1060839.jpg P1060839_up.jpg 
+
+echo Creating file via normal non streamed upload
+cp P1060839.jpg  SP1060839.jpg  
+curl -v -H "Sling-uploadmode: stream" -F key1=value1 -F *=@SP1060839.jpg -F PSP1060839.jpg=@SP1060839.jpg -F key2=admin2 http://admin:admin@localhost:8080/content/test
+curl http://admin:admin@localhost:8080/content/test/PSP1060839.jpg > PSP1060839_up.jpg 
+curl http://admin:admin@localhost:8080/content/test/SP1060839.jpg > SP1060839_up.jpg 
+diff P1060839.jpg PSP1060839_up.jpg
+diff P1060839.jpg SP1060839_up.jpg
+
+echo Checking chunked upload in 50k blocks.
+rm -f P1060839_chunk*
+split -b 20k P1060839.jpg  P1060839_chunk
+offset=0
+length=`wc -c P1060839.jpg | sed "s/ *\([0-9]*\) .*/\1/"`
+for i in P1060839_chunk*; do
+   size=`wc -c $i  | sed "s/ *\([0-9]*\) .*/\1/"`
+   curl -v -H "Sling-uploadmode: stream" -F CP1060839.jpg@Length=$length -F CP1060839.jpg@PartLength=$size -F CP1060839.jpg@Offset=$offset -F CP1060839.jpg=@$i http://admin:admin@localhost:8080/content/test
+   let offset=offset+size
+done
+curl http://admin:admin@localhost:8080/content/test/CP1060839.jpg > CP1060839_up.jpg
+diff -u P1060839.jpg CP1060839_up.jpg
diff --git a/pom.xml b/pom.xml
index ec97e97..600b6a0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -86,6 +86,8 @@
                 <excludes>
                   <exclude>src/main/resources/org/apache/sling/servlets/post/HtmlResponse.html</exclude>
                   <exclude>src/main/resources/org/apache/sling/servlets/post/HtmlNoGoBackResponse.html</exclude>
+                  <exclude>developer-tests/README.md</exclude>
+                  <exclude>Protocols.md</exclude>
                 </excludes>
               </configuration>
             </plugin>
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/helper/ResourceIteratorInputStream.java b/src/main/java/org/apache/sling/servlets/post/impl/helper/ResourceIteratorInputStream.java
new file mode 100644
index 0000000..3e6603e
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlets/post/impl/helper/ResourceIteratorInputStream.java
@@ -0,0 +1,71 @@
+/*
+ * 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 org.apache.sling.servlets.post.impl.helper;
+
+import org.apache.sling.api.resource.Resource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+
+/**
+ * An input stream that reads from a list of resources that can be adapted into input streams.
+ */
+public class ResourceIteratorInputStream extends InputStream {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ResourceIteratorInputStream.class);
+    private int n;
+    private InputStream currentStream;
+    private final Iterator<Resource> iterator;
+    private int streamNo = 0;
+
+    public ResourceIteratorInputStream(Iterator<Resource> iterator) {
+        this.iterator = iterator;
+        while(iterator.hasNext()) {
+            currentStream = iterator.next().adaptTo(InputStream.class);
+            if ( currentStream != null) {
+                n = 0;
+                streamNo = 1;
+                return;
+            }
+        }
+        throw new IllegalArgumentException("Resource iterator does not contain any resources that can be adapted to an input stream.");
+    }
+
+    @Override
+    public int read() throws IOException {
+        int i = currentStream.read();
+        while ( i == -1 ) {
+            if ( iterator.hasNext()) {
+                LOGGER.debug("Stream {} provided {} bytes. ",streamNo, n);
+                currentStream = iterator.next().adaptTo(InputStream.class);
+                streamNo++;
+                n = 0;
+                if (currentStream != null) {
+                    i = currentStream.read();
+                }
+            } else {
+                LOGGER.debug("Last Stream {} provided {} bytes. ",streamNo, n);
+                return -1;
+            }
+        }
+        n++;
+        return i;
+    }
+}
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/helper/StreamedChunk.java b/src/main/java/org/apache/sling/servlets/post/impl/helper/StreamedChunk.java
new file mode 100644
index 0000000..757c363
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlets/post/impl/helper/StreamedChunk.java
@@ -0,0 +1,426 @@
+/*
+ * 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 org.apache.sling.servlets.post.impl.helper;
+
+import org.apache.sling.api.resource.ModifiableValueMap;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.servlets.post.Modification;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.Part;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Supports streamed uploads including where the stream is made up of partial body parts.
+ * The behaviour is documented here https://cwiki.apache.org/confluence/display/SLING/Chunked+File+Upload+Support, adding the ability
+ * to define a body part with a Content-Range header on the part. Since the body parts are streamed there are some restrictions. If the
+ * length of a body part is missing from either the Content-Range header or a Content-Length header in the Part, then the length of the part is
+ * assumed to be the rest of the body to make the total length of the upload that specified in earlier Content-Range headers or a @Length property.
+ *
+ * When using only Content-Range headers (see the HTTP 1.1 spec) the Content-Range header must be complete and applied to the Part of the body.
+ * The length of the full file must be specified and be the same on all body parts, and the body parts must be sent in order. This is a restriction
+ * of the Sling Chunked File Upload protocol. When the total uploaded equals the file length the chunked uploads are processed to generate the final upload.
+ *
+ * When using request parameters, the most recent request parameters are used for @Completed, @Offset and @Length. When using request parameters if the
+ * Content-Length header is missing from the body Part, then the Body part is assumed to be the final body part. Then the total uploaded equals the value of
+ * the @Length parameter or a @Completed parameter is present, then the body parts are joined into a single body part.
+ *
+ * Consolidating body parts will cause all body parts to be read from the DS, which will incure 3x the IO of a non body part or chunked upload. For FS DS the IO may be from
+ * OS level disk cache. For other styles of DS the IO may consume more resources. Chunked or Body part uploads are not as efficient as whole body uploads and should
+ * be avoided wherever possible. This could be avoided if Oak would expose a seekable OutputStream, or allow writes to Binaries to specify and offset.
+ *
+ *
+ *
+ */
+public class StreamedChunk {
+    private static final String NT_RESOURCE = "nt:resource";
+    private static final String JCR_LASTMODIFIED = "jcr:lastModified";
+    private static final String JCR_MIMETYPE = "jcr:mimeType";
+    private static final String JCR_DATA = "jcr:data";
+    private static final String JCR_CONTENT = "jcr:content";
+    private static final String JCR_PRIMARY_TYPE = "jcr:primaryType";
+    private static final String SLING_CHUNKS_LENGTH = "sling:length";
+    private static final String SLING_FILE_LENGTH = "sling:fileLength";
+    private static final String JCR_MIXIN_TYPES = "jcr:mixinTypes";
+    private static final String SLING_CHUNK_MIXIN = "sling:chunks";
+    private static final String SLING_CHUNK_NT = "sling:chunk";
+    private static final String SLING_OFFSET = "sling:offset";
+    private static final String MT_APP_OCTET = "application/octet-stream";
+    private static final Logger LOGGER = LoggerFactory.getLogger(StreamedChunk.class);
+
+    private final long offset;
+    private final long chunkLength;
+    private final long fileLength;
+    private final Part part;
+    private final Map<String, List<String>> formFields;
+    private ServletContext servletContext;
+    private final boolean completed;
+    private final boolean chunked;
+    private final String chunkResourceName;
+
+    /**
+     * Construct a chunk from the part and form fields. Once constructed it is immutable exposing a store method to store the chunk.
+     * If the part does not represent a chunk then the class behaves as if the chunk is a upload of 1 chunk (ie the whole file).
+     * @param part the current part, not read other than headers.
+     * @param formFields form fields encountered in teh request stream prior to this part.
+     * @param servletContext the current servlet context needed to resolve mimetypes.
+     */
+    public StreamedChunk(Part part, Map<String, List<String>> formFields, ServletContext servletContext) {
+        this.part = part;
+        this.formFields = formFields;
+        this.servletContext = servletContext;
+
+        String contentRangeHeader = part.getHeader("Content-Range");
+        String contentLengthHeader = part.getHeader("Content-Length");
+        if ( contentRangeHeader != null ) {
+            ContentRange contentRange = new ContentRange(contentRangeHeader);
+            fileLength = contentRange.length;
+            offset = contentRange.offset;
+            chunkLength = contentRange.range;
+            chunked = true;
+
+        } else if ( formFields.containsKey(part.getName()+"@Length") && formFields.containsKey(part.getName()+"@Offset")) {
+            fileLength = Long.parseLong(lastFrom(formFields.get(part.getName() + "@Length")));
+            offset = Long.parseLong(lastFrom(formFields.get(part.getName() + "@Offset")));
+            if (contentLengthHeader != null) {
+                chunkLength = Long.parseLong(contentLengthHeader);
+            } else if ( formFields.containsKey(part.getName() + "@PartLength")) {
+                chunkLength = Long.parseLong(lastFrom(formFields.get(part.getName() + "@PartLength")));
+            } else {
+                // must assume the chunk contains all the data.
+                LOGGER.info("No part length specified assuming this is the final part of the chunked upload.");
+                chunkLength = fileLength - offset;
+            }
+            chunked = true;
+        } else {
+            offset = 0;
+            if (contentLengthHeader != null) {
+                fileLength =  Long.parseLong(contentLengthHeader);
+                chunkLength = fileLength;
+            } else {
+                fileLength = -1;
+                chunkLength = -1;
+            }
+            chunked = false;
+
+        }
+        chunkResourceName = "chunk_"+offset+"-"+(offset+chunkLength);
+        completed = ((offset+chunkLength) == fileLength) || formFields.containsKey(part.getName()+"@Completed");
+        LOGGER.debug(" chunkResourceName {},  chunked {},completed {},  fileLength {}, chunkLength {}, offset {} ",
+                new Object[]{chunkResourceName, chunked, completed, fileLength, chunkLength, offset});
+    }
+
+    /**
+     * Store the chunk in a file resource under a jcr:content sub node. The method does not commit the resource resolver. The caller
+     * must perform the commit. If the stream is a stream of body parts and the parts are complete, the store operation will commit
+     * the body part but leave the consolitation of all parts to be committed by the caller. ie, always call resourceResolver.commit() after
+     * calling this method.
+     * @param fileResource the file request.
+     * @param changes changes that were made.
+     * @return the jcr:content sub node.
+     * @throws PersistenceException
+     */
+    public Resource store(Resource fileResource, List<Modification> changes) throws PersistenceException {
+        Resource result = fileResource.getChild(JCR_CONTENT);
+        if (result != null) {
+            updateState(result, changes);
+        } else {
+            result = initState(fileResource, changes);
+        }
+        storeChunk(result, changes);
+        return result;
+    }
+
+
+    /**
+     * The last element of strings.
+     * @param strings a non null non zero string array.
+     * @return the last element.
+     */
+    private String lastFrom(List<String> strings) {
+        return strings.get(strings.size()-1);
+    }
+
+    /**
+     * Update the state of the content resource to reflect a new body part being streamd.
+     * @param contentResource the content resource
+     * @param changes changes made.
+     * @throws IllegalStateException if the contentResource is not consistent with the part being streamed.
+     * @throws PersistenceException if the part cant be streamed.
+     */
+    private void updateState(Resource contentResource, List<Modification> changes) throws IllegalStateException, PersistenceException {
+        final ModifiableValueMap vm = contentResource.adaptTo(ModifiableValueMap.class);
+        if ( vm == null ) {
+            throw new PersistenceException("Resource at " + contentResource.getPath() + " is not modifiable.");
+        }
+        vm.put(JCR_LASTMODIFIED, Calendar.getInstance());
+        vm.put(JCR_MIMETYPE, getContentType(part));
+        if (chunked) {
+            if ( vm.containsKey(SLING_FILE_LENGTH)) {
+                long previousFileLength = (Long) vm.get(SLING_FILE_LENGTH, Long.class);
+                if (previousFileLength != fileLength) {
+                    throw new IllegalStateException("Chunk file length has changed while cunks were being uploaded expected " + previousFileLength + " chunk contained  " + fileLength);
+                }
+            }
+            long previousChunksLength = 0;
+            if ( vm.containsKey(SLING_CHUNKS_LENGTH)) {
+                previousChunksLength = (Long) vm.get(SLING_CHUNKS_LENGTH, Long.class);
+                if (previousChunksLength != offset) {
+                    throw new IllegalStateException("Chunks recieved out of order, was expecting chunk starting at " + offset + " found last chunk ending at " + previousChunksLength);
+                }
+            }
+            vm.put(SLING_CHUNKS_LENGTH, previousChunksLength + chunkLength);
+            vm.put(JCR_MIXIN_TYPES, SLING_CHUNK_MIXIN);
+        } else {
+            try {
+                vm.put(JCR_DATA, part.getInputStream());
+            } catch (IOException e) {
+                throw new PersistenceException("Error while retrieving inputstream from request part.", e);
+            }
+        }
+    }
+
+    /**
+     * Initialise the state of the jcr:content sub resource.
+     * @param fileResource the fileResource parent resource.
+     * @param changes changes that were made.
+     * @return the content resource.
+     * @throws PersistenceException
+     */
+    private Resource initState(Resource fileResource, List<Modification> changes) throws PersistenceException {
+        Map<String, Object> resourceProps = new HashMap<String, Object>();
+        resourceProps.put(JCR_PRIMARY_TYPE, NT_RESOURCE);
+        resourceProps.put(JCR_LASTMODIFIED, Calendar.getInstance());
+        resourceProps.put(JCR_MIMETYPE, getContentType(part));
+
+        if (chunked) {
+            resourceProps.put(SLING_CHUNKS_LENGTH, chunkLength);
+            resourceProps.put(SLING_FILE_LENGTH, fileLength);
+            resourceProps.put(JCR_MIXIN_TYPES, SLING_CHUNK_MIXIN);
+            // add a zero size file to satisfy JCR constraints.
+            resourceProps.put(JCR_DATA, new ByteArrayInputStream(new byte[0]));
+        } else {
+            try {
+                resourceProps.put(JCR_DATA, part.getInputStream());
+            } catch (IOException e) {
+                throw new PersistenceException("Error while retrieving inputstream from request part.", e);
+            }
+        }
+
+        Resource result = fileResource.getResourceResolver().create(fileResource, JCR_CONTENT, resourceProps);
+        for( String key : resourceProps.keySet()) {
+            changes.add(Modification.onModified(result.getPath() + '/' + key));
+        }
+        return result;
+    }
+
+    /**
+     * Store the chunk in a chunked resource. If not chunked does nothing.
+     * @param contentResource
+     * @param changes
+     * @throws PersistenceException
+     */
+    private void storeChunk(Resource contentResource, List<Modification> changes) throws PersistenceException {
+        if (chunked) {
+            Map<String, Object> chunkProperties = new HashMap<String, Object>();
+            chunkProperties.put(JCR_PRIMARY_TYPE, SLING_CHUNK_NT);
+            chunkProperties.put(SLING_OFFSET, offset);
+            try {
+                chunkProperties.put(JCR_DATA, part.getInputStream());
+            } catch (IOException e) {
+                throw new PersistenceException("Error while retrieving inputstream from request part.", e);
+            }
+            LOGGER.debug("Creating chunk at {} with properties {}  ", chunkResourceName, chunkProperties);
+            Resource chunkResource = contentResource.getResourceResolver().create(contentResource, chunkResourceName, chunkProperties);
+
+
+            for (String key : chunkProperties.keySet()) {
+                changes.add(Modification.onModified(chunkResource.getPath() + '/' + key));
+            }
+
+
+            processChunks(contentResource, changes);
+        }
+
+    }
+
+    /**
+     * process all chunks formed so far to create the final body.
+     * @param contentResource
+     * @param changes
+     * @throws PersistenceException
+     */
+    private void processChunks(Resource contentResource, List<Modification> changes) throws PersistenceException {
+        if (completed) {
+
+            // have to commit before processing chunks.
+            contentResource.getResourceResolver().commit();
+            ModifiableValueMap vm = contentResource.adaptTo(ModifiableValueMap.class);
+            vm.put("jcr:data", getChunksInputStream(contentResource));
+            // might have to commit before removing chunk data, depending on if the InputStream still works.
+            removeChunkData(contentResource, vm);
+        }
+    }
+
+    /**
+     * remove chunk data.
+     * @param contentResource
+     * @param vm
+     * @throws PersistenceException
+     */
+    private void removeChunkData(Resource contentResource, ModifiableValueMap vm) throws PersistenceException {
+        for ( Resource r : contentResource.getChildren()) {
+            if (r.isResourceType(SLING_CHUNK_NT)) {
+                r.getResourceResolver().delete(r);
+            }
+        }
+        vm.remove(SLING_CHUNKS_LENGTH);
+        vm.remove(SLING_FILE_LENGTH);
+    }
+
+    /**
+     * Create an input stream that will read though the chunks in order.
+     * @param contentResource
+     * @return
+     */
+    private InputStream getChunksInputStream(Resource contentResource) {
+        List<Resource> chunkResources = new ArrayList<Resource>();
+        for ( Resource r : contentResource.getChildren()) {
+            if (r.isResourceType(SLING_CHUNK_NT)) {
+                chunkResources.add(r);
+            }
+        }
+        Collections.sort(chunkResources, new Comparator<Resource>() {
+            @Override
+            public int compare(Resource o1, Resource o2) {
+                long offset1 = o1.adaptTo(ValueMap.class).get(SLING_OFFSET, Long.class);
+                long offset2 = o2.adaptTo(ValueMap.class).get(SLING_OFFSET, Long.class);
+                return (int) (offset1 - offset2);
+            }
+        });
+        if ( LOGGER.isDebugEnabled()) {
+            LOGGER.debug("Finishing Chunk upload at {} consolidating {} chunks into one file of  ",
+                    new Object[]{
+                            contentResource.getPath(),
+                            chunkResources.size(),
+                            contentResource.adaptTo(ValueMap.class).get(SLING_CHUNKS_LENGTH)
+                    });
+            LOGGER.debug("Content Resource Properties {} ", contentResource.adaptTo(ValueMap.class));
+            for (Resource r : chunkResources) {
+                LOGGER.debug("Chunk {} properties {} ", r.getPath(), r.adaptTo(ValueMap.class));
+            }
+        }
+        return new ResourceIteratorInputStream(chunkResources.iterator());
+    }
+
+    /**
+     * Get the content type of the part.
+     * @param part
+     * @return
+     */
+    private String getContentType(final Part part) {
+        String contentType = part.getContentType();
+        if (contentType != null) {
+            int idx = contentType.indexOf(';');
+            if (idx > 0) {
+                contentType = contentType.substring(0, idx);
+            }
+        }
+        if (contentType == null || contentType.equals(MT_APP_OCTET)) {
+            // try to find a better content type
+            ServletContext ctx = this.servletContext;
+            if (ctx != null) {
+                contentType = ctx.getMimeType(part.getSubmittedFileName());
+            }
+            if (contentType == null || contentType.equals(MT_APP_OCTET)) {
+                contentType = MT_APP_OCTET;
+            }
+        }
+        return contentType;
+    }
+
+    /**
+     * Parses Content-Range headers according to spec https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html section 14.16
+     *
+     *     Content-Range = "Content-Range" ":" content-range-spec
+     * content-range-spec      = byte-content-range-spec
+     * byte-content-range-spec = bytes-unit SP
+     *                           byte-range-resp-spec "/"
+     *                           ( instance-length | "*" )
+     * byte-range-resp-spec = (first-byte-pos "-" last-byte-pos)
+     *                          | "*"
+     * instance-length = 1*DIGIT
+     *
+     * eg
+     * bytes 0-1233/1234
+     * bytes 500-1233/1234
+     * bytes 500-1233/*
+     *
+     * According to https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.12 "bytes" is the only valid range unit.
+     */
+    public static class ContentRange {
+        private static final Pattern rangePattern = Pattern.compile("bytes\\s([0-9]+)-([0-9]+)\\/([0-9]*)(\\**)");
+        public long length;
+        public long offset;
+        public long range;
+
+
+        public ContentRange(String contentRangeHeader) {
+            Matcher m = rangePattern.matcher(contentRangeHeader);
+            if ( m.find() ) {
+                offset = Long.parseLong(m.group(1));
+                long end = Long.parseLong(m.group(2));
+                range = end-offset+1;
+                if ("*".equals(m.group(4))) {
+                    length = -1;
+                } else {
+                    length = Long.parseLong(m.group(3));
+                    if ( offset > length ) {
+                        throw new IllegalArgumentException("Range header "+contentRangeHeader+" is invalid, offset beyond end.");
+                    }
+                    if ( end > length ) {
+                        throw new IllegalArgumentException("Range header "+contentRangeHeader+" is invalid, range end beyond end.");
+                    }
+                    if ( range > length ) {
+                        throw new IllegalArgumentException("Range header "+contentRangeHeader+" is invalid, range greater than length.");
+                    }
+                }
+                if ( offset > end ) {
+                    throw new IllegalArgumentException("Range header "+contentRangeHeader+" is invalid, offset beyond end of range.");
+                }
+            } else {
+                throw new IllegalArgumentException("Range header "+contentRangeHeader+" is invalid");
+            }
+        }
+    }
+}
diff --git a/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java b/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
index a227601..067ba20 100644
--- a/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
+++ b/src/main/java/org/apache/sling/servlets/post/impl/operations/StreamedUploadOperation.java
@@ -20,7 +20,6 @@
 import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.util.Text;
 import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.resource.ModifiableValueMap;
 import org.apache.sling.api.resource.PersistenceException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
@@ -28,6 +27,7 @@
 import org.apache.sling.servlets.post.AbstractPostOperation;
 import org.apache.sling.servlets.post.Modification;
 import org.apache.sling.servlets.post.PostResponse;
+import org.apache.sling.servlets.post.impl.helper.StreamedChunk;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -36,7 +36,6 @@
 import javax.servlet.http.Part;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -58,12 +57,6 @@
 public class StreamedUploadOperation extends AbstractPostOperation {
     private static final Logger LOG = LoggerFactory.getLogger(StreamedUploadOperation.class);
     public static final String NT_FILE = "nt:file";
-    public static final String NT_RESOURCE = "nt:resource";
-    public static final String JCR_LASTMODIFIED = "jcr:lastModified";
-    public static final String JCR_MIMETYPE = "jcr:mimeType";
-    public static final String JCR_DATA = "jcr:data";
-    private static final String MT_APP_OCTET = "application/octet-stream";
-    private static final String JCR_CONTENT = "jcr:content";
     private ServletContext servletContext;
 
     public void setServletContext(final ServletContext servletContext) {
@@ -167,33 +160,10 @@
         }
 
 
-
-        Map<String, Object> resourceProps = new HashMap<String, Object>();
-        resourceProps.put("jcr:primaryType", NT_RESOURCE);
-        resourceProps.put(JCR_LASTMODIFIED, Calendar.getInstance());
-        // TODO: Should all the formFields be added to the prop map ?
-        resourceProps.put(JCR_MIMETYPE, getContentType(part));
-        try {
-            resourceProps.put(JCR_DATA, part.getInputStream());
-        } catch (IOException e) {
-            throw new PersistenceException("Error while retrieving inputstream from request part.", e);
-        }
-        Resource result = fileResource.getChild(JCR_CONTENT);
-        if ( result != null ) {
-            final ModifiableValueMap vm = result.adaptTo(ModifiableValueMap.class);
-            if ( vm == null ) {
-                throw new PersistenceException("Resource at " + fileResource.getPath() + '/' + JCR_CONTENT + " is not modifiable.");
-            }
-            vm.putAll(resourceProps);
-        } else {
-            result = parentResource.getResourceResolver().create(fileResource, JCR_CONTENT, resourceProps);
-        }
-        // Commit must be called to perform to cause streaming so the next part can be found.
+        StreamedChunk chunk = new StreamedChunk(part, formFields, servletContext);
+        Resource result = chunk.store(fileResource, changes);
         result.getResourceResolver().commit();
 
-        for( String key : resourceProps.keySet()) {
-            changes.add(Modification.onModified(result.getPath() + '/' + key));
-        }
     }
 
     /**
@@ -235,31 +205,6 @@
     }
 
 
-    /**
-     * Get the content type of the part.
-     * @param part
-     * @return
-     */
-    private String getContentType(final Part part) {
-        String contentType = part.getContentType();
-        if (contentType != null) {
-            int idx = contentType.indexOf(';');
-            if (idx > 0) {
-                contentType = contentType.substring(0, idx);
-            }
-        }
-        if (contentType == null || contentType.equals(MT_APP_OCTET)) {
-            // try to find a better content type
-            ServletContext ctx = this.servletContext;
-            if (ctx != null) {
-                contentType = ctx.getMimeType(part.getSubmittedFileName());
-            }
-            if (contentType == null || contentType.equals(MT_APP_OCTET)) {
-                contentType = MT_APP_OCTET;
-            }
-        }
-        return contentType;
-    }
 
 
 
diff --git a/src/test/java/org/apache/sling/servlets/post/impl/helper/ResourceIteratorInputStreamTest.java b/src/test/java/org/apache/sling/servlets/post/impl/helper/ResourceIteratorInputStreamTest.java
new file mode 100644
index 0000000..e91a020
--- /dev/null
+++ b/src/test/java/org/apache/sling/servlets/post/impl/helper/ResourceIteratorInputStreamTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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 org.apache.sling.servlets.post.impl.helper;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.commons.testing.sling.MockResource;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created by ieb on 06/09/2016.
+ */
+public class ResourceIteratorInputStreamTest {
+
+    @Test
+    public void test() throws IOException {
+        List<Resource> resources = new ArrayList<Resource>();
+        for (int i = 0; i < 10; i++ ) {
+            final int initialState = i;
+            final InputStream in = new InputStream() {
+                private int state = initialState;
+                @Override
+                public int read() throws IOException {
+                    return state--;
+                }
+            };
+            resources.add(new MockResource(null,null,null){
+                @Override
+                public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+                    if (InputStream.class.equals(type)) {
+                        return (AdapterType) in;
+                    }
+                    return super.adaptTo(type);
+                }
+
+                @Override
+                public String getName() {
+                    return "chunk-"+(initialState*100)+"-"+(((initialState+1)*100)-1);
+                }
+            });
+        }
+        ResourceIteratorInputStream resourceIteratorInputStream = new ResourceIteratorInputStream(resources.iterator());
+        int expected = 0;
+        int cycle = 0;
+        for(int i = resourceIteratorInputStream.read(); i >= 0; i = resourceIteratorInputStream.read()) {
+            Assert.assertEquals(expected, i);
+            if ( expected == 0 ) {
+                cycle++;
+                expected=cycle;
+            } else {
+                expected--;
+            }
+        }
+        Assert.assertEquals(10,cycle);
+    }
+}
diff --git a/src/test/java/org/apache/sling/servlets/post/impl/helper/StreamedChunkTest.java b/src/test/java/org/apache/sling/servlets/post/impl/helper/StreamedChunkTest.java
new file mode 100644
index 0000000..414704c
--- /dev/null
+++ b/src/test/java/org/apache/sling/servlets/post/impl/helper/StreamedChunkTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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 org.apache.sling.servlets.post.impl.helper;
+
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Created by ieb on 06/09/2016.
+ */
+public class StreamedChunkTest {
+
+    @Test
+    public void testContentRange() {
+        checkRange("bytes 0-1234/1235", 0, 1235, 1235);
+        checkRange("bytes 10-123/1235", 10,123-10+1,1235);
+        checkRange("bytes 12-123/*", 12, 123 - 12+1, -1);
+        checkInvalidRange("byte 10-123/1234"); // byte is not valid.
+        checkInvalidRange("bytes 1000-123/1234"); // offset before end
+        checkInvalidRange("bytes 1000-12300/1234"); // end before length
+        checkInvalidRange("bytes 1000-12300/big"); // big not valid
+        checkInvalidRange("bytes 1000-12300/"); // no length
+        checkInvalidRange("bytes 1000-12300"); // no length
+    }
+
+    private void checkInvalidRange(String rangeHeader) {
+        try {
+            StreamedChunk.ContentRange cr = new StreamedChunk.ContentRange(rangeHeader);
+            Assert.fail("Should have rejected "+rangeHeader);
+        } catch (IllegalArgumentException e) {
+            // ok
+        }
+    }
+
+    private void checkRange(String rangeHeader, long offset, long range, long length) {
+        StreamedChunk.ContentRange cr = new StreamedChunk.ContentRange(rangeHeader);
+        Assert.assertEquals(offset,cr.offset);
+        Assert.assertEquals(range,cr.range);
+        Assert.assertEquals(length,cr.length);
+
+    }
+
+}
diff --git a/src/test/java/org/apache/sling/servlets/post/impl/operations/MockPart.java b/src/test/java/org/apache/sling/servlets/post/impl/operations/MockPart.java
index 01cc13a..a48d753 100644
--- a/src/test/java/org/apache/sling/servlets/post/impl/operations/MockPart.java
+++ b/src/test/java/org/apache/sling/servlets/post/impl/operations/MockPart.java
@@ -34,12 +34,13 @@
     private String contentType;
     private InputStream inputStream;
 
-    public MockPart(String name, String contentType, String submittedFileName, long size, InputStream inputStream) {
+    public MockPart(String name, String contentType, String submittedFileName, long size, InputStream inputStream, Map<String, Object> headers) {
         this.name = name;
         this.contentType = contentType;
         this.submittedFileName = submittedFileName;
         this.size = size;
         this.inputStream = inputStream;
+        this.headers = headers;
     }
 
     @Override
diff --git a/src/test/java/org/apache/sling/servlets/post/impl/operations/MockRealResource.java b/src/test/java/org/apache/sling/servlets/post/impl/operations/MockRealResource.java
index ae1d5eb..a6e9eb7 100644
--- a/src/test/java/org/apache/sling/servlets/post/impl/operations/MockRealResource.java
+++ b/src/test/java/org/apache/sling/servlets/post/impl/operations/MockRealResource.java
@@ -24,6 +24,9 @@
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ValueMap;
 
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
 import java.util.Iterator;
 import java.util.Map;
 
@@ -34,21 +37,28 @@
     private final ResourceResolver resourceResolver;
     private final String path;
     private final String resourceType;
+    private final String name;
+    private final String parentPath;
     private MockValueMap properties = new MockValueMap();
 
     public MockRealResource(ResourceResolver resourceResolver, String path, String resourceType) {
         this.resourceResolver = resourceResolver;
         this.path = path;
         this.resourceType = resourceType;
+        this.name = path.substring(path.lastIndexOf('/'));
+        this.parentPath = path.substring(0,path.lastIndexOf('/'));
     }
 
     public MockRealResource(ResourceResolver resourceResolver, String path, String resourceType, Map<String, Object> properties) {
         this.resourceResolver = resourceResolver;
         this.path = path;
+        this.name = path.substring(path.lastIndexOf('/')+1);
+        this.parentPath = path.substring(0,path.lastIndexOf('/'));
         this.resourceType = resourceType;
         this.properties.putAll(properties);
     }
 
+
     @Override
     public String getPath() {
         return path;
@@ -56,22 +66,21 @@
 
     @Override
     public String getName() {
-        return null;
+        return name;
     }
 
     @Override
     public Resource getParent() {
-        return null;
+        return resourceResolver.getResource(parentPath);
     }
 
     @Override
     public Iterator<Resource> listChildren() {
-        return null;
+        return resourceResolver.listChildren(this);
     }
 
-    @Override
-    public Iterable<Resource> getChildren() {
-        return null;
+    @Override    public Iterable<Resource> getChildren() {
+        return resourceResolver.getChildren(this);
     }
 
     @Override
@@ -91,7 +100,7 @@
 
     @Override
     public boolean isResourceType(String s) {
-        return false;
+        return s.equals(resourceType);
     }
 
     @Override
@@ -109,6 +118,18 @@
         if (ValueMap.class.isAssignableFrom(aClass)) {
             return (AdapterType) properties;
         }
+        if (InputStream.class.isAssignableFrom(aClass) && properties.containsKey("jcr:data")) {
+            Object o = properties.get("jcr:data");
+            if (o instanceof InputStream) {
+                return (AdapterType) o;
+            } else {
+                try {
+                    return (AdapterType) new ByteArrayInputStream(String.valueOf(properties.get("jcr:data")).getBytes("UTF-8"));
+                } catch (UnsupportedEncodingException e) {
+                    throw new RuntimeException("Cant convert UTF-8 to byte[]");
+                }
+            }
+        }
         return null;
     }
 }
diff --git a/src/test/java/org/apache/sling/servlets/post/impl/operations/StreamingUploadOperationTest.java b/src/test/java/org/apache/sling/servlets/post/impl/operations/StreamingUploadOperationTest.java
index 33d98da..8dd2a62 100644
--- a/src/test/java/org/apache/sling/servlets/post/impl/operations/StreamingUploadOperationTest.java
+++ b/src/test/java/org/apache/sling/servlets/post/impl/operations/StreamingUploadOperationTest.java
@@ -48,6 +48,7 @@
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 import java.util.Calendar;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -73,7 +74,7 @@
     @Test
     public void test() throws RepositoryException, UnsupportedEncodingException {
         List<Modification> changes = new ArrayList<Modification>();
-        PostResponse ressponse = new AbstractPostResponse() {
+        PostResponse response = new AbstractPostResponse() {
             @Override
             protected void doSend(HttpServletResponse response) throws IOException {
 
@@ -91,11 +92,11 @@
         };
 
         List<Part> partsList = new ArrayList<Part>();
-        partsList.add(new MockPart("formfield1", null, null, 0, new ByteArrayInputStream("testformfield1".getBytes("UTF-8"))));
-        partsList.add(new MockPart("formfield2", null, null, 0, new ByteArrayInputStream("testformfield2".getBytes("UTF-8"))));
-        partsList.add(new MockPart("test1.txt", "text/plain", "test1bad.txt", 4, new ByteArrayInputStream("test".getBytes("UTF-8"))));
-        partsList.add(new MockPart("*", "text/plain2", "test2.txt", 8, new ByteArrayInputStream("test1234".getBytes("UTF-8"))));
-        partsList.add(new MockPart("badformfield2", null, null, 0, new ByteArrayInputStream("testbadformfield2".getBytes("UTF-8"))));
+        partsList.add(new MockPart("formfield1", null, null, 0, new ByteArrayInputStream("testformfield1".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        partsList.add(new MockPart("formfield2", null, null, 0, new ByteArrayInputStream("testformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        partsList.add(new MockPart("test1.txt", "text/plain", "test1bad.txt", 4, new ByteArrayInputStream("test".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        partsList.add(new MockPart("*", "text/plain2", "test2.txt", 8, new ByteArrayInputStream("test1234".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        partsList.add(new MockPart("badformfield2", null, null, 0, new ByteArrayInputStream("testbadformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
         final Iterator<Part> partsIterator = partsList.iterator();
         final Map<String, Resource> repository = new HashMap<String, Resource>();
         final ResourceResolver resourceResolver = new MockResourceResolver() {
@@ -191,7 +192,7 @@
                 return resourceResolver;
             }
         };
-        streamedUplodOperation.doRun(request, ressponse, changes);
+        streamedUplodOperation.doRun(request, response, changes);
 
 
         {
@@ -241,4 +242,439 @@
 
 
     }
+
+    @Test
+    public void testParts() throws RepositoryException, UnsupportedEncodingException {
+        List<Modification> changes = new ArrayList<Modification>();
+        PostResponse response = new AbstractPostResponse() {
+            @Override
+            protected void doSend(HttpServletResponse response) throws IOException {
+
+            }
+
+            @Override
+            public void onChange(String type, String... arguments) {
+
+            }
+
+            @Override
+            public String getPath() {
+                return "/test/upload/location";
+            }
+        };
+
+        List<Part> partsList = new ArrayList<Part>();
+        partsList.add(new MockPart("test1.txt@Length", null, null, 0, new ByteArrayInputStream("8".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        partsList.add(new MockPart("test1.txt@Offset", null, null, 0, new ByteArrayInputStream("0".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        partsList.add(new MockPart(
+                "test1.txt",
+                "text/plain",
+                "test1bad.txt",
+                4,
+                new ByteArrayInputStream("test".getBytes("UTF-8")),
+                mapOf("Content-Length", "4")));
+        partsList.add(new MockPart("test1.txt@Offset", null, null, 0, new ByteArrayInputStream("4".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        partsList.add(new MockPart(
+                "test1.txt",
+                "text/plain",
+                "test1bad.txt",
+                4,
+                new ByteArrayInputStream("part".getBytes("UTF-8")),
+                mapOf("Content-Length", "4")));
+        partsList.add(new MockPart("*", "text/plain2", "test2.txt", 8, new ByteArrayInputStream("test1234".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        partsList.add(new MockPart("badformfield2", null, null, 0, new ByteArrayInputStream("testbadformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        final Iterator<Part> partsIterator = partsList.iterator();
+        final Map<String, Resource> repository = new HashMap<String, Resource>();
+        final ResourceResolver resourceResolver = new MockResourceResolver() {
+            @Override
+            public Resource getResource(String path) {
+
+                Resource resource = repository.get(path);
+
+                if ( resource == null ) {
+                    if ( "/test/upload/location".equals(path)) {
+                        resource =  new MockRealResource(this, path, "sling:Folder");
+                        repository.put(path,resource);
+                        LOG.debug("Created {} ", path);
+
+                    }
+                }
+                LOG.debug("Resource {} is {} {}", path, resource, ResourceUtil.isSyntheticResource(resource));
+                return resource;
+            }
+
+
+
+
+            @Override
+            public Iterable<Resource> getChildren(Resource resource) {
+
+                List<Resource> children = new ArrayList<Resource>();
+                for(Map.Entry<String, Resource> e : repository.entrySet()) {
+                    if (isChild(resource.getPath(), e.getKey())) {
+                        children.add(e.getValue());
+                    }
+                }
+                return children;
+            }
+
+            private boolean isChild(String path, String key) {
+                if ( key.length() > path.length() && key.startsWith(path)) {
+                    return !key.substring(path.length()+1).contains("/");
+                }
+                return false;
+            }
+
+            @Override
+            public Iterator<Resource> listChildren(Resource parent) {
+                return getChildren(parent).iterator();
+            }
+
+            @Override
+            public void delete(Resource resource) throws PersistenceException {
+
+            }
+
+            @Override
+            public Resource create(Resource resource, String s, Map<String, Object> map) throws PersistenceException {
+                Resource childResource = resource.getChild(s);
+                if ( childResource != null) {
+                    throw new IllegalArgumentException("Child "+s+" already exists ");
+                }
+                String resourceType = (String)map.get("sling:resourceType");
+                if ( resourceType == null) {
+                    resourceType = (String)map.get("jcr:primaryType");
+                }
+                if ( resourceType == null) {
+                    LOG.warn("Resource type null for {} {} ", resource,  resource.getPath()+"/"+s);
+                }
+                Resource newResource = new MockRealResource(this, resource.getPath()+"/"+s, resourceType, map);
+                repository.put(newResource.getPath(), newResource);
+                LOG.debug("Created Resource {} ", newResource.getPath());
+                return newResource;
+            }
+
+            @Override
+            public void revert() {
+
+            }
+
+            @Override
+            public void commit() throws PersistenceException {
+                LOG.debug("Committing");
+                for(Map.Entry<String, Resource> e : repository.entrySet()) {
+                    LOG.debug("Committing {} ", e.getKey());
+                    Resource r = e.getValue();
+                    ModifiableValueMap vm = r.adaptTo(ModifiableValueMap.class);
+                    for (Map.Entry<String, Object> me : vm.entrySet()) {
+                        if (me.getValue() instanceof InputStream) {
+                            try {
+                                String value = IOUtils.toString((InputStream) me.getValue());
+                                LOG.debug("Converted {} {}  ", me.getKey(), value);
+                                vm.put(me.getKey(), value);
+
+                            } catch (IOException e1) {
+                                throw new PersistenceException("Failed to commit input stream", e1);
+                            }
+                        }
+                    }
+                    LOG.debug("Converted {} ", vm);
+                }
+                LOG.debug("Comittted {} ", repository);
+
+
+            }
+
+            @Override
+            public boolean hasChanges() {
+                return false;
+            }
+        };
+
+        SlingHttpServletRequest request = new MockSlingHttpServlet3Request(null, null, null, null, null) {
+            @Override
+            public Object getAttribute(String name) {
+                if ( "request-parts-iterator".equals(name)) {
+                    return partsIterator;
+                }
+                return super.getAttribute(name);
+            }
+
+            @Override
+            public ResourceResolver getResourceResolver() {
+                return resourceResolver;
+            }
+        };
+        streamedUplodOperation.doRun(request, response, changes);
+
+
+        {
+            Resource r = repository.get("/test/upload/location/test1.txt");
+            Assert.assertNotNull(r);
+            ValueMap m = r.adaptTo(ValueMap.class);
+            Assert.assertNotNull(m);
+
+
+            Assert.assertEquals("nt:file", m.get("jcr:primaryType"));
+
+        }
+        {
+            Resource r = repository.get("/test/upload/location/test1.txt/jcr:content");
+            Assert.assertNotNull(r);
+            ValueMap m = r.adaptTo(ValueMap.class);
+            Assert.assertNotNull(m);
+
+            Assert.assertEquals("nt:resource", m.get("jcr:primaryType"));
+            Assert.assertTrue(m.get("jcr:lastModified") instanceof Calendar);
+            Assert.assertEquals("text/plain", m.get("jcr:mimeType"));
+            Assert.assertEquals("testpart", m.get("jcr:data"));
+
+        }
+        {
+            Resource r = repository.get("/test/upload/location/test2.txt");
+            Assert.assertNotNull(r);
+            ValueMap m = r.adaptTo(ValueMap.class);
+            Assert.assertNotNull(m);
+
+
+            Assert.assertEquals("nt:file", m.get("jcr:primaryType"));
+
+        }
+        {
+            Resource r = repository.get("/test/upload/location/test2.txt/jcr:content");
+            Assert.assertNotNull(r);
+            ValueMap m = r.adaptTo(ValueMap.class);
+            Assert.assertNotNull(m);
+
+
+            Assert.assertEquals("nt:resource", m.get("jcr:primaryType"));
+            Assert.assertTrue(m.get("jcr:lastModified") instanceof Calendar);
+            Assert.assertEquals("text/plain2", m.get("jcr:mimeType"));
+            Assert.assertEquals("test1234", m.get("jcr:data"));
+        }
+
+
+    }
+
+    @Test
+    public void testPartsContentRange() throws RepositoryException, UnsupportedEncodingException {
+        List<Modification> changes = new ArrayList<Modification>();
+        PostResponse response = new AbstractPostResponse() {
+            @Override
+            protected void doSend(HttpServletResponse response) throws IOException {
+
+            }
+
+            @Override
+            public void onChange(String type, String... arguments) {
+
+            }
+
+            @Override
+            public String getPath() {
+                return "/test/upload/location";
+            }
+        };
+
+        List<Part> partsList = new ArrayList<Part>();
+        partsList.add(new MockPart("formfield1", null, null, 0, new ByteArrayInputStream("testformfield1".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        partsList.add(new MockPart("formfield2", null, null, 0, new ByteArrayInputStream("testformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        partsList.add(new MockPart(
+                "test1.txt",
+                "text/plain",
+                "test1bad.txt",
+                4,
+                new ByteArrayInputStream("test".getBytes("UTF-8")),
+                mapOf("Content-Range","bytes 0-3/8", "Content-Length", "4")));
+        partsList.add(new MockPart(
+                "test1.txt",
+                "text/plain",
+                "test1bad.txt",
+                4,
+                new ByteArrayInputStream("part".getBytes("UTF-8")),
+                mapOf("Content-Range","bytes 4-7/8", "Content-Length", "4")));
+        partsList.add(new MockPart("*", "text/plain2", "test2.txt", 8, new ByteArrayInputStream("test1234".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        partsList.add(new MockPart("badformfield2", null, null, 0, new ByteArrayInputStream("testbadformfield2".getBytes("UTF-8")), Collections.EMPTY_MAP));
+        final Iterator<Part> partsIterator = partsList.iterator();
+        final Map<String, Resource> repository = new HashMap<String, Resource>();
+        final ResourceResolver resourceResolver = new MockResourceResolver() {
+            @Override
+            public Resource getResource(String path) {
+
+                Resource resource = repository.get(path);
+
+                if ( resource == null ) {
+                    if ( "/test/upload/location".equals(path)) {
+                        resource =  new MockRealResource(this, path, "sling:Folder");
+                        repository.put(path,resource);
+                        LOG.debug("Created {} ", path);
+
+                    }
+                }
+                LOG.debug("Resource {} is {} {}", path, resource, ResourceUtil.isSyntheticResource(resource));
+                return resource;
+            }
+
+
+
+
+            @Override
+            public Iterable<Resource> getChildren(Resource resource) {
+
+                List<Resource> children = new ArrayList<Resource>();
+                for(Map.Entry<String, Resource> e : repository.entrySet()) {
+                    if (isChild(resource.getPath(), e.getKey())) {
+                        children.add(e.getValue());
+                    }
+                }
+                return children;
+            }
+
+            private boolean isChild(String path, String key) {
+                if ( key.length() > path.length() && key.startsWith(path)) {
+                    return !key.substring(path.length()+1).contains("/");
+                }
+                return false;
+            }
+
+            @Override
+            public Iterator<Resource> listChildren(Resource parent) {
+                return getChildren(parent).iterator();
+            }
+
+            @Override
+            public void delete(Resource resource) throws PersistenceException {
+
+            }
+
+            @Override
+            public Resource create(Resource resource, String s, Map<String, Object> map) throws PersistenceException {
+                Resource childResource = resource.getChild(s);
+                if ( childResource != null) {
+                    throw new IllegalArgumentException("Child "+s+" already exists ");
+                }
+                String resourceType = (String)map.get("sling:resourceType");
+                if ( resourceType == null) {
+                    resourceType = (String)map.get("jcr:primaryType");
+                }
+                if ( resourceType == null) {
+                    LOG.warn("Resource type null for {} {} ", resource,  resource.getPath()+"/"+s);
+                }
+                Resource newResource = new MockRealResource(this, resource.getPath()+"/"+s, resourceType, map);
+                repository.put(newResource.getPath(), newResource);
+                LOG.debug("Created Resource {} ", newResource.getPath());
+                return newResource;
+            }
+
+            @Override
+            public void revert() {
+
+            }
+
+            @Override
+            public void commit() throws PersistenceException {
+                LOG.debug("Committing");
+                for(Map.Entry<String, Resource> e : repository.entrySet()) {
+                    LOG.debug("Committing {} ", e.getKey());
+                    Resource r = e.getValue();
+                    ModifiableValueMap vm = r.adaptTo(ModifiableValueMap.class);
+                    for (Map.Entry<String, Object> me : vm.entrySet()) {
+                        if (me.getValue() instanceof InputStream) {
+                            try {
+                                String value = IOUtils.toString((InputStream) me.getValue());
+                                LOG.debug("Converted {} {}  ", me.getKey(), value);
+                                vm.put(me.getKey(), value);
+
+                            } catch (IOException e1) {
+                                throw new PersistenceException("Failed to commit input stream", e1);
+                            }
+                        }
+                    }
+                    LOG.debug("Converted {} ", vm);
+                }
+                LOG.debug("Comittted {} ", repository);
+
+
+            }
+
+            @Override
+            public boolean hasChanges() {
+                return false;
+            }
+        };
+
+        SlingHttpServletRequest request = new MockSlingHttpServlet3Request(null, null, null, null, null) {
+            @Override
+            public Object getAttribute(String name) {
+                if ( "request-parts-iterator".equals(name)) {
+                    return partsIterator;
+                }
+                return super.getAttribute(name);
+            }
+
+            @Override
+            public ResourceResolver getResourceResolver() {
+                return resourceResolver;
+            }
+        };
+        streamedUplodOperation.doRun(request, response, changes);
+
+
+        {
+            Resource r = repository.get("/test/upload/location/test1.txt");
+            Assert.assertNotNull(r);
+            ValueMap m = r.adaptTo(ValueMap.class);
+            Assert.assertNotNull(m);
+
+
+            Assert.assertEquals("nt:file", m.get("jcr:primaryType"));
+
+        }
+        {
+            Resource r = repository.get("/test/upload/location/test1.txt/jcr:content");
+            Assert.assertNotNull(r);
+            ValueMap m = r.adaptTo(ValueMap.class);
+            Assert.assertNotNull(m);
+
+            Assert.assertEquals("nt:resource", m.get("jcr:primaryType"));
+            Assert.assertTrue(m.get("jcr:lastModified") instanceof Calendar);
+            Assert.assertEquals("text/plain", m.get("jcr:mimeType"));
+            Assert.assertEquals("testpart", m.get("jcr:data"));
+
+        }
+        {
+            Resource r = repository.get("/test/upload/location/test2.txt");
+            Assert.assertNotNull(r);
+            ValueMap m = r.adaptTo(ValueMap.class);
+            Assert.assertNotNull(m);
+
+
+            Assert.assertEquals("nt:file", m.get("jcr:primaryType"));
+
+        }
+        {
+            Resource r = repository.get("/test/upload/location/test2.txt/jcr:content");
+            Assert.assertNotNull(r);
+            ValueMap m = r.adaptTo(ValueMap.class);
+            Assert.assertNotNull(m);
+
+
+            Assert.assertEquals("nt:resource", m.get("jcr:primaryType"));
+            Assert.assertTrue(m.get("jcr:lastModified") instanceof Calendar);
+            Assert.assertEquals("text/plain2", m.get("jcr:mimeType"));
+            Assert.assertEquals("test1234", m.get("jcr:data"));
+        }
+
+
+    }
+
+
+
+    private Map<String,Object> mapOf(String ... s) {
+        Map<String, Object> m = new HashMap<String, Object>();
+        for (int i = 0; i < s.length; i+=2) {
+            m.put(s[i],s[i+1]);
+        }
+        return m;
+    }
 }
