     console.time('insert') if @debug
 
     randFileName  = @namingFunction.call null, true
-    currentChunk  = 0
-    first         = true
-    chunksQty     = if @chunkSize < file.size then Math.ceil(file.size / @chunkSize) else 1
     self          = @
+    partSize      = Math.ceil file.size / streams
+    parts         = []
+    uploaded      = 0
+    last          = false
+
+    i = 1
+    while i <= streams
+      parts.push
+        from: partSize * (i-1)
+        to:   partSize * i
+        size: partSize
+        part: i
+        chunksQty: if @chunkSize < partSize then Math.ceil(partSize / @chunkSize) else 1
+      # console.log "if #{@chunkSize} < #{partSize} then Math.ceil(partSize / @chunkSize) else 1", if @chunkSize < partSize then Math.ceil(partSize / @chunkSize) else 1
+      i++
+
+    # console.log parts
 
     end = (error, data) ->
       console.timeEnd('insert') if self.debug

          type:       fileData.type
          size:       fileData.size
          chunk:      currentChunk
          isVideo:    fileData.type.toLowerCase().indexOf("video") > -1
          isAudio:    fileData.type.toLowerCase().indexOf("audio") > -1
          isImage:    fileData.type.toLowerCase().indexOf("image") > -1

      onUploaded and onUploaded.call self, error, data

    if onBeforeUpload
      if not onBeforeUpload.call file
        end new Meteor.Error(500, "FORBIDDEN"), null
        return false

    upload = (filePart, part, chunksQtyInPart, fileReader) ->
      currentChunk = 1
      first = true
      console.time("insertPart#{part}") if @debug

      fileReader.onload = (chunk) ->
        ++totalSentChunks
        # console.log "currentChunk", currentChunk
        onProgress and onProgress((uploaded / file.size) * 100)
        # console.log "PROGRESS: ", (uploaded / file.size) * 100

        uploaded   += self.chunkSize
        binary      = chunk.srcElement or chunk.target
        arrayBuffer = new Uint8Array binary.result
        last        = (part is streams and currentChunk >= chunksQtyInPart)

        # console.log "isLastPart?", last, "#{currentChunk} >= #{chunksQtyInPart}"

        if chunksQtyInPart is 1
          Meteor.call self.methodNames.MeteorFileWrite, arrayBuffer, fileData, meta, first, chunksQtyInPart, currentChunk, totalSentChunks, randFileName, part, streams, file.size, (error, data) ->
            if data.last
              end error, data
        else
          Meteor.call self.methodNames.MeteorFileWrite, arrayBuffer, fileData, meta, first, chunksQtyInPart, currentChunk, totalSentChunks, randFileName, part, streams, file.size, (error, data)->
            # console.log "DATA.last", data.last, error, data
            if data.chunk + 1 <= chunksQtyInPart
              from         = currentChunk * self.chunkSize
              to           = from + self.chunkSize

              # console.log "Send chunk ##{currentChunk} of part ##{part} | #{from} #{to}"
              fileReader.readAsArrayBuffer filePart.slice from, to
              currentChunk = ++data.chunk
            else if data.last
              end error, data
        first = false

      # console.log "Send first chunk of part"
      fileReader.readAsArrayBuffer filePart.slice 0, self.chunkSize

    # for part, index in parts
    i = parts.length - 1
    while i >= 0
      Meteor.setTimeout ((parts, i) ->
        return () ->
          part = parts[i]
          # console.log "Upload part#", part
          fileReader = new FileReader
          # console.log "Slice file to parts: #{index}"
          upload(file.slice(part.from, part.to), i + 1, part.chunksQty, fileReader)
      )(parts, i)
      ,
        0
      --i

    return undefined

  ###
  @isomorphic
