                         failure("\(error)")
                     }
                 }
-
-
-
-                /*
-
-
-
-                 FileManager.default.createFile(atPath: folderPath, contents: nil, attributes: nil)
-                 // Assemble
-                 if let writeFileHande=FileHandle(forWritingAtPath:folderPath ){
-                 offset=0
-                 position=0
-                 for i in 0 ... nb{
-                 autoreleasepool(invoking: { () -> Void in
-                 do {
-                 let source=folderPath+"/\(i).data"
-                 let url=URL(fileURLWithPath: source)
-                 let encrypted = try Data(contentsOf:url)
-                 //let sha1=encrypted.sha1
-                 let decrypted = try Bartleby.cryptoDelegate.decryptData(encrypted)
-                 if let decompressed = try decrypted.decompress(algorithm: .lz4){
-                 writeFileHande.write(decompressed)
-                 }
-                 }catch{
-                 print(error)
-                 }
-                 })
-                 }
-                 }
-                 */
-                
-
-        }
-
-        }
-
-    }
-
-
-
-
-    //MARK: - Triggered Block Level Action
-
-    /// Downloads a Block.
-    /// This occurs before triggered_create on each successfull upload.
-    ///
-    /// - Parameters:
-    ///   - node: the node
-    internal func triggered_download(block:Block){
-        if block.authorized.contains(self._document.currentUser.UID) ||
-            block.authorized.contains("*"){
-            // We can download
-            // @TODO
-
-            // On each completion :
-            // Call self._tryToAssembleNodesInProgress()
-
-        }
-    }
-
-    // MARK: - Internal Mechanisms
-
-    public func _tryToAssembleNodesInProgress(){
-        for node in self._document.metadata.nodesInProgress {
-            // Check if we have all the blocks
-            if (self._allBlocksAreAvailableFor(node: node)){
-                self._assemble(node: node, handler: VoidCompletionHandler)
+            }else{
+                Async.main{
+                    failure("Unable to create file Handle at: \(path)")
+                }
             }
-        }
-    }
+
+        }
+
+    }
+
+
+    /// Joins the chunks to form a file
+    /// - The hard stuff is done Asynchronously on a the Utility queue
+    /// - we use an Autorelease pool to lower the memory foot print
+    ///
+    /// - Parameters:
+    ///   - paths: the chunks absolute paths
+    ///   - destinationFilePath: the joined file destination
+    ///   - decompress: should we decompress using LZ4
+    ///   - decrypt: should we decrypt usign AES256
+    ///   - success: the success closure
+    ///   - failure: the failure closure
+    public func joinChunks (   from paths:[String],
+                              to destinationFilePath:String,
+                              decompress:Bool,
+                              decrypt:Bool,
+                              success:@escaping ()->(),
+                              failure:@escaping (String)->()){
+
+        // Don't block the main thread with those intensive IO  processing
+        Async.utility {
+
+            do{
+
+                let folderPath=(destinationFilePath as NSString).deletingLastPathComponent
+                try FileManager.default.createDirectory(atPath: folderPath, withIntermediateDirectories: true, attributes: nil)
+                FileManager.default.createFile(atPath: destinationFilePath, contents: nil, attributes: nil)
+
+                // Assemble
+                if let writeFileHande = FileHandle(forWritingAtPath:destinationFilePath ){
+                    writeFileHande.seek(toFileOffset: 0)
+
+                    for source in paths{
+                        try autoreleasepool(invoking: { () -> Void in
+                            let url=URL(fileURLWithPath: source)
+                            var data = try Data(contentsOf:url)
+                            if decrypt{
+                                data = try Bartleby.cryptoDelegate.decryptData(data)
+                            }
+                            if decompress{
+                                data = try data.decompress(algorithm: .lz4)
+                            }
+                            writeFileHande.write(data)
+                        })
+                    }
+                    Async.main{
+                        success()
+                    }
+                    
+                }else{
+                    Async.main{
+                        failure("Unable to create file Handle at: \(destinationFilePath)")
+                    }
+                }
+            }catch{
+                Async.main{
+                    failure("\(error)")
+                }
+            }
+        }
+    }
+
     
-    public func _allBlocksAreAvailableFor(node:Node)->Bool{
-        // @TODO
-        return true
-    }
-
 }

    ///   - relativePath: the relative Path of the Node
    ///   - authorized: the User UIDS or "*" if public
    ///   - deleteOriginal: should we delete the original?
    ///   - zipped: should we zip the node
    ///   - crypted: should we encrypt the node
    ///   - priority: synchronization priority (higher == will be synchronized before the other nodes)
    /// - Returns: the node
    public func add(original absolutePath:String, relativePath:String,authorized:[String],deleteOriginal:Bool=false,zipped:Bool=false,crypted:Bool=true,priority:Int=0)throws->Node{
        return Node()
    }


                    let _ = try FileManager.default.createDirectory(atPath: bFolderPath, withIntermediateDirectories: true, attributes: nil)
                    let destination=bFolderPath+"/\(sha1)"
                    let chunkRelativePath=relativeFolderPath+"\(sha1)"
                    let chunk=Chunk(baseDirectory:folderPath, relativePath: chunkRelativePath,sha1: sha1,originalSize:Int(offset))
                    chunks.append(chunk)
                    let url=URL(fileURLWithPath: destination)
                    let _ = try data.write(to:url )
