diff --git a/test/jio.storage/replicatestorage.tests.js b/test/jio.storage/replicatestorage.tests.js
index bdae9e08208fcd9226f475e2cc9e3ca04d129745..cf57cd5be7a6e916ea74601cb86c39f7f056de44 100644
--- a/test/jio.storage/replicatestorage.tests.js
+++ b/test/jio.storage/replicatestorage.tests.js
@@ -1,6 +1,6 @@
 /*jslint nomen: true*/
-/*global Blob, console, RSVP*/
-(function (jIO, QUnit, Blob, RSVP) {
+/*global Blob*/
+(function (jIO, QUnit, Blob) {
   "use strict";
   var test = QUnit.test,
     stop = QUnit.stop,
@@ -36,39 +36,6 @@
   }
   jIO.addStorage('signaturestorage2713', Storage2713);
 
-  function StorageEmptyAllAttachments(spec) {
-    this._sub_storage = jIO.createJIO(spec.sub_storage);
-    return this;
-  }
-  jIO.addStorage('signaturestorageallattachments', StorageEmptyAllAttachments);
-  StorageEmptyAllAttachments.prototype.allAttachments = function () {
-    return this._sub_storage.allAttachments.apply(this._sub_storage,
-                                                  arguments);
-  };
-  StorageEmptyAllAttachments.prototype.getAttachment = function () {
-    return this._sub_storage.getAttachment.apply(this._sub_storage,
-                                                 arguments);
-  };
-  StorageEmptyAllAttachments.prototype.putAttachment = function () {
-    return this._sub_storage.putAttachment.apply(this._sub_storage,
-                                                 arguments);
-  };
-  StorageEmptyAllAttachments.prototype.buildQuery = function () {
-    return this._sub_storage.buildQuery.apply(this._sub_storage,
-                                              arguments);
-  };
-  StorageEmptyAllAttachments.prototype.put = function () {
-    return this._sub_storage.put.apply(this._sub_storage,
-                                       arguments);
-  };
-  StorageEmptyAllAttachments.prototype.get = function () {
-    return this._sub_storage.get.apply(this._sub_storage,
-                                       arguments);
-  };
-  StorageEmptyAllAttachments.prototype.hasCapacity = function (name) {
-    return (name !== 'bulk_get');
-  };
-
   /////////////////////////////////////////////////////////////////
   // replicateStorage.constructor
   /////////////////////////////////////////////////////////////////
@@ -734,7254 +701,4 @@
       });
   });
 
-  /////////////////////////////////////////////////////////////////
-  // replicateStorage.repair use cases
-  /////////////////////////////////////////////////////////////////
-  module("replicateStorage.repair.document", {
-    setup: function () {
-      // Uses memory substorage, so that it is flushed after each run
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        }
-      });
-
-    }
-  });
-
-  /////////////////////////////////////////////////////////////////
-  // document replication
-  /////////////////////////////////////////////////////////////////
-
-  test("local document creation", function () {
-    stop();
-    expect(2);
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local document creation not checked", function () {
-    stop();
-    expect(6);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_local_creation: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local document creation and use remote post", function () {
-    stop();
-    expect(13);
-
-    var id,
-      post_id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      use_remote_post: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, 'foo', blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      // Document 'id' has been deleted in both storages
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._local_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function () {
-        ok(false, "Signature should have been deleted");
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-      })
-
-      // But another document should have been created
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.allDocs();
-      })
-      .then(function (result) {
-        equal(result.data.total_rows, 1);
-        post_id = result.data.rows[0].id;
-        return context.jio.__storage._remote_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._local_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-        // Attachment should be kept
-        return context.jio.__storage._local_sub_storage
-                      .getAttachment(post_id, 'foo', {format: 'text'});
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._signature_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local document creation, remote post and delayed allDocs", function () {
-    stop();
-    expect(11);
-
-    var id,
-      post_id = "_foobar",
-      context = this;
-
-    function Storage200DelayedAllDocs(spec) {
-      this._sub_storage = jIO.createJIO(spec.sub_storage);
-    }
-    Storage200DelayedAllDocs.prototype.get = function () {
-      return this._sub_storage.get.apply(this._sub_storage, arguments);
-    };
-    Storage200DelayedAllDocs.prototype.post = function (param) {
-      return this.put(post_id, param);
-    };
-    Storage200DelayedAllDocs.prototype.put = function () {
-      return this._sub_storage.put.apply(this._sub_storage, arguments);
-    };
-    Storage200DelayedAllDocs.prototype.hasCapacity = function () {
-      return true;
-    };
-    Storage200DelayedAllDocs.prototype.buildQuery = function () {
-      return [];
-    };
-    jIO.addStorage(
-      'replicatestorage200delayedalldocs',
-      Storage200DelayedAllDocs
-    );
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      use_remote_post: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "replicatestorage200delayedalldocs",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      // Document 'id' has been deleted in both storages
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._local_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-      })
-
-      // But another document should have been created
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._local_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote document creation", function () {
-    stop();
-    expect(2);
-
-    var id,
-      context = this;
-
-    context.jio.__storage._remote_sub_storage.post({"title": "bar"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "bar"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "6799f3ea80e325b89f19589282a343c376c1f1af"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote document creation not checked", function () {
-    stop();
-    expect(6);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_remote_creation: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.__storage._remote_sub_storage.post({"title": "bar"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "bar"
-        });
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote document creations", function () {
-    stop();
-    expect(5);
-
-    var context = this;
-
-    RSVP.all([
-      context.jio.put("conflict", {"title": "foo"}),
-      context.jio.__storage._remote_sub_storage.put("conflict",
-                                                    {"title": "bar"})
-    ])
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        ok(false);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Conflict on 'conflict': " +
-                             "{\"title\":\"foo\"} !== {\"title\":\"bar\"}");
-        equal(error.status_code, 409);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get("conflict");
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-//        equal(error.message, "Cannot find document: conflict");
-        equal(error.status_code, 404);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote document creations: keep local", function () {
-    stop();
-    expect(3);
-
-    var context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      conflict_handling: 1
-    });
-
-    RSVP.all([
-      context.jio.put("conflict", {"title": "foo"}),
-      context.jio.__storage._remote_sub_storage.put("conflict",
-                                                    {"title": "bar"})
-    ])
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get("conflict");
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .then(function () {
-        return context.jio.get("conflict");
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get("conflict");
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote document creations: keep local, remote post",
-    function () {
-      stop();
-      expect(3);
-
-      var context = this;
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        use_remote_post: 1,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        conflict_handling: 1
-      });
-
-      RSVP.all([
-        context.jio.put("conflict", {"title": "foo"}),
-        context.jio.__storage._remote_sub_storage.put("conflict",
-                                                      {"title": "bar"})
-      ])
-        .then(function () {
-          return context.jio.repair();
-        })
-        .then(function () {
-          return context.jio.__storage._signature_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-          });
-        })
-        .then(function () {
-          return context.jio.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "foo"
-          });
-        })
-        .then(function () {
-          return context.jio.__storage._remote_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "foo"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local and remote document creations: keep local, " +
-       "local not matching query", function () {
-      stop();
-      expect(3);
-
-      var context = this;
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        local_sub_storage: {
-          type: "query",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "query",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        query: {query: 'type: "foobar"'},
-        conflict_handling: 1
-      });
-
-      RSVP.all([
-        context.jio.put("conflict", {"title": "foo"}),
-        context.jio.__storage._remote_sub_storage.put("conflict",
-                                                      {"title": "bar",
-                                                       "type": "foobar"})
-      ])
-        .then(function () {
-          return context.jio.repair();
-        })
-        .then(function () {
-          return context.jio.__storage._signature_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-          });
-        })
-        .then(function () {
-          return context.jio.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "foo"
-          });
-        })
-        .then(function () {
-          return context.jio.__storage._remote_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "foo"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local and remote document creations: keep local, " +
-       "remote not matching query", function () {
-      stop();
-      expect(3);
-
-      var context = this;
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        local_sub_storage: {
-          type: "query",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "query",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        query: {query: 'type: "foobar"'},
-        conflict_handling: 1
-      });
-
-      RSVP.all([
-        context.jio.put("conflict", {"title": "foo", "type": "foobar"}),
-        context.jio.__storage._remote_sub_storage.put("conflict",
-                                                      {"title": "bar"})
-      ])
-        .then(function () {
-          return context.jio.repair();
-        })
-        .then(function () {
-          return context.jio.__storage._signature_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            hash: "a0a1b37cee3709101b752c56e59b9d66cce09961"
-          });
-        })
-        .then(function () {
-          return context.jio.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "foo",
-            type: "foobar"
-          });
-        })
-        .then(function () {
-          return context.jio.__storage._remote_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "foo",
-            type: "foobar"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local and remote document creations: keep remote", function () {
-    stop();
-    expect(3);
-
-    var context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      conflict_handling: 2
-    });
-
-    RSVP.all([
-      context.jio.put("conflict", {"title": "foo"}),
-      context.jio.__storage._remote_sub_storage.put("conflict",
-                                                    {"title": "bar"})
-    ])
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get("conflict");
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "6799f3ea80e325b89f19589282a343c376c1f1af"
-        });
-      })
-      .then(function () {
-        return context.jio.get("conflict");
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "bar"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get("conflict");
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "bar"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote document creations: keep remote, remote post",
-    function () {
-      stop();
-      expect(3);
-
-      var context = this;
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        use_remote_post: 1,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        conflict_handling: 2
-      });
-
-      RSVP.all([
-        context.jio.put("conflict", {"title": "foo"}),
-        context.jio.__storage._remote_sub_storage.put("conflict",
-                                                      {"title": "bar"})
-      ])
-        .then(function () {
-          return context.jio.repair();
-        })
-        .then(function () {
-          return context.jio.__storage._signature_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            hash: "6799f3ea80e325b89f19589282a343c376c1f1af"
-          });
-        })
-        .then(function () {
-          return context.jio.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "bar"
-          });
-        })
-        .then(function () {
-          return context.jio.__storage._remote_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "bar"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local and remote document creations: keep remote, " +
-       "local not matching query", function () {
-      stop();
-      expect(3);
-
-      var context = this;
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        local_sub_storage: {
-          type: "query",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "query",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        query: {query: 'type: "foobar"'},
-        conflict_handling: 2
-      });
-
-      RSVP.all([
-        context.jio.put("conflict", {"title": "foo"}),
-        context.jio.__storage._remote_sub_storage.put("conflict",
-                                                      {"title": "bar",
-                                                       "type": "foobar"})
-      ])
-        .then(function () {
-          return context.jio.repair();
-        })
-        .then(function () {
-          return context.jio.__storage._signature_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            hash: "45efa2292d54cc4ce1f726ea197bc0b9721fc1dc"
-          });
-        })
-        .then(function () {
-          return context.jio.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "bar",
-            type: "foobar"
-          });
-        })
-        .then(function () {
-          return context.jio.__storage._remote_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "bar",
-            type: "foobar"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local and remote document creations: keep remote, " +
-       "remote not matching query", function () {
-      stop();
-      expect(3);
-
-      var context = this;
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        local_sub_storage: {
-          type: "query",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "query",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        query: {query: 'type: "foobar"'},
-        conflict_handling: 2
-      });
-
-      RSVP.all([
-        context.jio.put("conflict", {"title": "foo", "type": "foobar"}),
-        context.jio.__storage._remote_sub_storage.put("conflict",
-                                                      {"title": "bar"})
-      ])
-        .then(function () {
-          return context.jio.repair();
-        })
-        .then(function () {
-          return context.jio.__storage._signature_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            hash: "6799f3ea80e325b89f19589282a343c376c1f1af"
-          });
-        })
-        .then(function () {
-          return context.jio.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "bar"
-          });
-        })
-        .then(function () {
-          return context.jio.__storage._remote_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "bar"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local and remote document creations: continue", function () {
-    stop();
-    expect(4);
-
-    var context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      conflict_handling: 3
-    });
-
-    RSVP.all([
-      context.jio.put("conflict", {"title": "foo"}),
-      context.jio.__storage._remote_sub_storage.put("conflict",
-                                                    {"title": "bar"})
-    ])
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get("conflict");
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-//        equal(error.message, "Cannot find document: conflict");
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.get("conflict");
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get("conflict");
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "bar"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote document creations: continue, remote post",
-    function () {
-      stop();
-      expect(4);
-
-      var context = this;
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        use_remote_post: 1,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        conflict_handling: 3
-      });
-
-      RSVP.all([
-        context.jio.put("conflict", {"title": "foo"}),
-        context.jio.__storage._remote_sub_storage.put("conflict",
-                                                      {"title": "bar"})
-      ])
-        .then(function () {
-          return context.jio.repair();
-        })
-        .then(function () {
-          return context.jio.__storage._signature_sub_storage.get("conflict");
-        })
-        .fail(function (error) {
-          ok(error instanceof jIO.util.jIOError);
-          //        equal(error.message, "Cannot find document: conflict");
-          equal(error.status_code, 404);
-        })
-        .then(function () {
-          return context.jio.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "foo"
-          });
-        })
-        .then(function () {
-          return context.jio.__storage._remote_sub_storage.get("conflict");
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            title: "bar"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local and remote same document creations", function () {
-    stop();
-    expect(1);
-
-    var context = this;
-
-    RSVP.all([
-      context.jio.put("conflict", {"title": "foo"}),
-      context.jio.__storage._remote_sub_storage.put("conflict",
-                                                    {"title": "foo"})
-    ])
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get("conflict");
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("no modification", function () {
-    stop();
-    expect(2);
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local document modification", function () {
-    stop();
-    expect(2);
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.put(id, {"title": "foo2"});
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo2"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "9819187e39531fdc9bcfd40dbc6a7d3c78fe8dab"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-
-  test("local document modification: use remote post", function () {
-    stop();
-    expect(2);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      use_remote_post: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.__storage._remote_sub_storage.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.put(id, {"title": "foo2"});
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo2"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "9819187e39531fdc9bcfd40dbc6a7d3c78fe8dab"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local document modification not checked", function () {
-    stop();
-    expect(3);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_local_modification: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.put(id, {"title": "foo2"});
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo2"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote document modification", function () {
-    stop();
-    expect(2);
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.put(
-          id,
-          {"title": "foo3"}
-        );
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo3"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "4b1dde0f80ac38514771a9d25b5278e38f560e0f"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote document modification not checked", function () {
-    stop();
-    expect(3);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_remote_modification: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.put(
-          id,
-          {"title": "foo3"}
-        );
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo3"
-        });
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote document modifications", function () {
-    stop();
-    expect(4);
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo4"}),
-          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo5"})
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        ok(false);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Conflict on '" + id + "': " +
-                             "{\"title\":\"foo4\"} !== {\"title\":\"foo5\"}");
-        equal(error.status_code, 409);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote document modifications: keep local", function () {
-    stop();
-    expect(3);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      conflict_handling: 1
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo4"}),
-          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo5"})
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "6f700e813022233a785692585484c21cb5a412fd"
-        });
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo4"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote document modifications: keep remote", function () {
-    stop();
-    expect(3);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      conflict_handling: 2
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo4"}),
-          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo5"})
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "7bea6f87fd1dda14e340e5b14836cc8578fd615f"
-        });
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo5"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo5"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote document modifications: continue", function () {
-    stop();
-    expect(3);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      conflict_handling: 3
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo4"}),
-          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo5"})
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo4"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo5"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote document same modifications", function () {
-    stop();
-    expect(1);
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo99"}),
-          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo99"})
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local document deletion", function () {
-    stop();
-    expect(6);
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.remove(id);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        ok(true, "Removal correctly synced");
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id)
-          .then(function () {
-            ok(false, "Signature should be deleted");
-          })
-          .fail(function (error) {
-            ok(error instanceof jIO.util.jIOError);
-//            equal(error.message, "Cannot find document: " + id);
-            equal(error.status_code, 404);
-          });
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local document deletion not checked", function () {
-    stop();
-    expect(6);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_local_deletion: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.remove(id);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        ok(true, "Removal correctly synced");
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local document deletion with attachment", function () {
-    stop();
-    expect(7);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.remove(id);
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage
-                      .putAttachment(id, 'foo', blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        ok(true, "Removal correctly synced");
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage
-                      .getAttachment(id, 'foo', {format: 'text'});
-      })
-      .then(function (result) {
-        equal(result, big_string);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote document deletion", function () {
-    stop();
-    expect(6);
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.remove(id);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        ok(true, "Removal correctly synced");
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id)
-          .then(function () {
-            ok(false, "Signature should be deleted");
-          })
-          .fail(function (error) {
-            ok(error instanceof jIO.util.jIOError);
-//            equal(error.message, "Cannot find document: " + id);
-            equal(error.status_code, 404);
-          });
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote document deletion not checked", function () {
-    stop();
-    expect(6);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_remote_deletion: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.remove(id);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        ok(true, "Removal correctly synced");
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote document deletion with attachment", function () {
-    stop();
-    expect(7);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.remove(id);
-      })
-      .then(function () {
-        return context.jio.putAttachment(id, 'foo', blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        ok(true, "Removal correctly synced");
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo"
-        });
-      })
-      .then(function () {
-        return context.jio.getAttachment(id, 'foo', {format: 'text'});
-      })
-      .then(function (result) {
-        equal(result, big_string);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote document deletions", function () {
-    stop();
-    expect(8);
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.remove(id),
-          context.jio.__storage._remote_sub_storage.remove(id)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.get(id)
-          .then(function () {
-            ok(false, "Document should be locally deleted");
-          })
-          .fail(function (error) {
-            ok(error instanceof jIO.util.jIOError);
-            equal(error.message, "Cannot find document: " + id);
-            equal(error.status_code, 404);
-          });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id)
-          .then(function () {
-            ok(false, "Document should be remotely deleted");
-          })
-          .fail(function (error) {
-            ok(error instanceof jIO.util.jIOError);
-            equal(error.message, "Cannot find document: " + id);
-            equal(error.status_code, 404);
-          });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id)
-          .then(function () {
-            ok(false, "Signature should be deleted");
-          })
-          .fail(function (error) {
-            ok(error instanceof jIO.util.jIOError);
-//            equal(error.message, "Cannot find document: " + id);
-            equal(error.status_code, 404);
-          });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local deletion and remote modifications", function () {
-    stop();
-    expect(2);
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.remove(id),
-          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo99"})
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local deletion and remote modifications: keep local", function () {
-    stop();
-    expect(9);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 1,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.remove(id),
-          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo99"})
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(
-          error.message.indexOf(
-            "Cannot find attachment: " +
-              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-              "jio_document/"
-          ),
-          0
-        );
-        equal(error.status_code, 404);
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local deletion and remote modifications: keep remote", function () {
-    stop();
-    expect(3);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 2,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.remove(id),
-          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo99"})
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local deletion and remote modifications: ignore", function () {
-    stop();
-    expect(5);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 3,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.remove(id),
-          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo99"})
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modifications and remote deletion", function () {
-    stop();
-    expect(2);
-
-    var id,
-      context = this;
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo99"}),
-          context.jio.__storage._remote_sub_storage.remove(id)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          title: "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modifications and remote deletion: use remote post", function () {
-    stop();
-    expect(13);
-
-    var id,
-      context = this,
-      post_id;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      use_remote_post: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.__storage._remote_sub_storage.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo99"}),
-          context.jio.__storage._remote_sub_storage.remove(id)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      // Old id deleted
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(
-          error.message.indexOf(
-            "Cannot find attachment: " +
-              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-              "jio_document/"
-          ),
-          0
-        );
-        equal(error.status_code, 404);
-      })
-      // Check new id
-      .then(function () {
-        return context.jio.allDocs({include_docs: true});
-      })
-      .then(function (result) {
-        equal(result.data.total_rows, 1);
-        post_id = result.data.rows[0].id;
-        return context.jio.__storage._remote_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          "title": "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._local_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          "title": "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-
-  test("local modif, remote del: remote post, no check loc mod", function () {
-    stop();
-    expect(13);
-
-    var id,
-      context = this,
-      post_id;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      use_remote_post: true,
-      check_local_modification: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.__storage._remote_sub_storage.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo99"}),
-          context.jio.__storage._remote_sub_storage.remove(id)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      // Old id deleted
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(
-          error.message.indexOf(
-            "Cannot find attachment: " +
-              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-              "jio_document/"
-          ),
-          0
-        );
-        equal(error.status_code, 404);
-      })
-      // Check new id
-      .then(function () {
-        return context.jio.allDocs({include_docs: true});
-      })
-      .then(function (result) {
-        equal(result.data.total_rows, 1);
-        post_id = result.data.rows[0].id;
-        return context.jio.__storage._remote_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          "title": "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._local_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          "title": "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modifications and remote deletion: keep local", function () {
-    stop();
-    expect(3);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 1,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo99"}),
-          context.jio.__storage._remote_sub_storage.remove(id)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      // Old id deleted
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          "title": "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          "title": "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modif and remote del: keep local, use remote post", function () {
-    stop();
-    expect(13);
-
-    var id,
-      context = this,
-      post_id;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 1,
-      use_remote_post: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.__storage._remote_sub_storage.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo99"}),
-          context.jio.__storage._remote_sub_storage.remove(id)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      // Old id deleted
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(
-          error.message.indexOf(
-            "Cannot find attachment: " +
-              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-              "jio_document/"
-          ),
-          0
-        );
-        equal(error.status_code, 404);
-      })
-      // Check new id
-      .then(function () {
-        return context.jio.allDocs({include_docs: true});
-      })
-      .then(function (result) {
-        equal(result.data.total_rows, 1);
-        post_id = result.data.rows[0].id;
-        return context.jio.__storage._remote_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          "title": "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._local_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          "title": "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(post_id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modifications and remote deletion: keep remote", function () {
-    stop();
-    expect(9);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 2,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo99"}),
-          context.jio.__storage._remote_sub_storage.remove(id)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      // id deleted
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(
-          error.message.indexOf(
-            "Cannot find attachment: " +
-              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-              "jio_document/"
-          ),
-          0
-        );
-        equal(error.status_code, 404);
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modif and remote del: keep remote, not check modif", function () {
-    stop();
-    expect(9);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 2,
-      check_local_modification: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo99"}),
-          context.jio.__storage._remote_sub_storage.remove(id)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      // id deleted
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(
-          error.message.indexOf(
-            "Cannot find attachment: " +
-              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-              "jio_document/"
-          ),
-          0
-        );
-        equal(error.status_code, 404);
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modifications and remote deletion: ignore", function () {
-    stop();
-    expect(5);
-
-    var id,
-      context = this;
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 3,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.put(id, {"title": "foo99"}),
-          context.jio.__storage._remote_sub_storage.remove(id)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      // id deleted
-      .then(function () {
-        return context.jio.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          "title": "foo99"
-        });
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " + id);
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("signature document is not synced", function () {
-    stop();
-    expect(6);
-
-    var context = this;
-
-    // Uses sessionstorage substorage, so that signature are stored
-    // in the same local sub storage
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "document",
-          document_id: "/",
-          sub_storage: {
-            type: "local",
-            sessiononly: true
-          }
-        }
-      },
-      remote_sub_storage: {
-        type: "memory"
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(
-          context.jio.__storage._signature_hash
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " +
-                "_replicate_8662994dcefb3a2ceec61e86953efda8ec6520d6");
-        equal(error.status_code, 404);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.get(
-          context.jio.__storage._signature_hash
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Cannot find document: " +
-                "_replicate_8662994dcefb3a2ceec61e86953efda8ec6520d6");
-        equal(error.status_code, 404);
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("substorages are repaired too", function () {
-    stop();
-    expect(8);
-
-    var context = this,
-      first_call = true,
-      options = {foo: "bar"};
-
-    function Storage200CheckRepair() {
-      return this;
-    }
-    Storage200CheckRepair.prototype.get = function () {
-      ok(true, "get 200 check repair called");
-      return {};
-    };
-    Storage200CheckRepair.prototype.hasCapacity = function () {
-      return true;
-    };
-    Storage200CheckRepair.prototype.buildQuery = function () {
-      ok(true, "buildQuery 200 check repair called");
-      return [];
-    };
-    Storage200CheckRepair.prototype.allAttachments = function () {
-      ok(true, "allAttachments 200 check repair called");
-      return {};
-    };
-    Storage200CheckRepair.prototype.repair = function (kw) {
-      if (first_call) {
-        deepEqual(
-          this,
-          context.jio.__storage._local_sub_storage.__storage,
-          "local substorage repair"
-        );
-        first_call = false;
-      } else {
-        deepEqual(
-          this,
-          context.jio.__storage._remote_sub_storage.__storage,
-          "remote substorage repair"
-        );
-      }
-      deepEqual(kw, options, "substorage repair parameters provided");
-    };
-
-    jIO.addStorage(
-      'replicatestorage200chechrepair',
-      Storage200CheckRepair
-    );
-
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      local_sub_storage: {
-        type: "replicatestorage200chechrepair"
-      },
-      remote_sub_storage: {
-        type: "replicatestorage200chechrepair"
-      }
-    });
-
-    context.jio.repair(options)
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("sync all documents by default", function () {
-    stop();
-    expect(4);
-
-    var context = this;
-
-    function Storage200DefaultQuery() {
-      return this;
-    }
-    Storage200DefaultQuery.prototype.get = function () {
-      ok(true, "get 200 check repair called");
-      return {};
-    };
-    Storage200DefaultQuery.prototype.hasCapacity = function () {
-      return true;
-    };
-    Storage200DefaultQuery.prototype.buildQuery = function (query) {
-      deepEqual(query, {});
-      return [];
-    };
-    Storage200DefaultQuery.prototype.allAttachments = function () {
-      ok(true, "allAttachments 200 check repair called");
-      return {};
-    };
-    jIO.addStorage(
-      'replicatestorage200defaultquery',
-      Storage200DefaultQuery
-    );
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      local_sub_storage: {
-        type: "replicatestorage200defaultquery"
-      },
-      remote_sub_storage: {
-        type: "replicatestorage200defaultquery"
-      }
-    });
-
-    return context.jio.repair()
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("sync can be restricted to some documents", function () {
-    stop();
-    expect(4);
-
-    var context = this,
-      query = {query: 'portal_type: "Foo"', limit: [0, 1234567890]};
-
-    function Storage200CustomQuery() {
-      return this;
-    }
-    Storage200CustomQuery.prototype.get = function () {
-      ok(true, "get 200 check repair called");
-      return {};
-    };
-    Storage200CustomQuery.prototype.hasCapacity = function () {
-      return true;
-    };
-    Storage200CustomQuery.prototype.buildQuery = function (options) {
-      deepEqual(options, query);
-      return [];
-    };
-    Storage200CustomQuery.prototype.allAttachments = function () {
-      ok(true, "allAttachments 200 check repair called");
-      return {};
-    };
-    jIO.addStorage(
-      'replicatestorage200customquery',
-      Storage200CustomQuery
-    );
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      local_sub_storage: {
-        type: "replicatestorage200customquery"
-      },
-      remote_sub_storage: {
-        type: "replicatestorage200customquery"
-      },
-      query: {query: 'portal_type: "Foo"', limit: [0, 1234567890]}
-    });
-
-    return context.jio.repair()
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("use 1 parallel operation", function () {
-    stop();
-    expect(16);
-
-    var context = this,
-      order_number = 0,
-      expected_order_list = [
-        'start get 0',
-        'stop get 0',
-        'start put 0',
-        'stop put 0',
-        'start get 1',
-        'stop get 1',
-        'start put 1',
-        'stop put 1',
-        'start get 2',
-        'stop get 2',
-        'start put 2',
-        'stop put 2',
-        'start get 3',
-        'stop get 3',
-        'start put 3',
-        'stop put 3'
-      ];
-
-    function assertExecutionOrder(text) {
-      equal(text, expected_order_list[order_number],
-            expected_order_list[order_number]);
-      order_number += 1;
-    }
-
-    function StorageOneParallelOperation() {
-      this._sub_storage = jIO.createJIO({type: "memory"});
-      return this;
-    }
-
-    StorageOneParallelOperation.prototype.put = function (id, doc) {
-      assertExecutionOrder('start put ' + id);
-      var storage = this;
-      return storage._sub_storage.put(id, doc)
-        .push(function (result) {
-          assertExecutionOrder('stop put ' + id);
-          return result;
-        });
-    };
-
-    StorageOneParallelOperation.prototype.get = function (id) {
-      assertExecutionOrder('start get ' + id);
-      var storage = this;
-      return storage._sub_storage.get(id)
-        .push(undefined, function (error) {
-          assertExecutionOrder('stop get ' + id);
-          throw error;
-        });
-    };
-    StorageOneParallelOperation.prototype.buildQuery = function () {
-      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
-    };
-
-    StorageOneParallelOperation.prototype.hasCapacity = function () {
-      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
-    };
-
-    jIO.addStorage(
-      'one_parallel',
-      StorageOneParallelOperation
-    );
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      local_sub_storage: {
-        type: "memory"
-      },
-      remote_sub_storage: {
-        type: "one_parallel"
-      }
-    });
-
-    return RSVP.all([
-      context.jio.put("0", {"title": "foo"}),
-      context.jio.put("1", {"title": "foo1"}),
-      context.jio.put("2", {"title": "foo2"}),
-      context.jio.put("3", {"title": "foo3"})
-    ])
-      .then(function () {
-        return context.jio.repair();
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("use 2 parallel operations", function () {
-    stop();
-    expect(16);
-
-    var context = this,
-      order_number = 0,
-      expected_order_list = [
-        'start get 0',
-
-        'start get 1',
-        'stop get 1',
-        'start put 1',
-        'stop put 1',
-        'start get 2',
-        'stop get 2',
-        'start put 2',
-
-        'stop get 0',
-        'start put 0',
-        'stop put 0',
-        'start get 3',
-        'stop get 3',
-        'start put 3',
-        'stop put 3',
-
-        'stop put 2'
-      ],
-      defer0,
-      defer2;
-
-    function assertExecutionOrder(text) {
-      equal(text, expected_order_list[order_number],
-            expected_order_list[order_number]);
-      order_number += 1;
-    }
-
-    function StorageTwoParallelOperation() {
-      this._sub_storage = jIO.createJIO({type: "memory"});
-      return this;
-    }
-
-    StorageTwoParallelOperation.prototype.put = function (id, doc) {
-      var storage = this;
-      assertExecutionOrder('start put ' + id);
-      return new RSVP.Queue()
-        .push(function () {
-          if (id === "2") {
-            defer0.resolve();
-            defer2 = RSVP.defer();
-            return defer2.promise;
-          }
-        })
-        .push(function () {
-          return storage._sub_storage.put(id, doc);
-        })
-        .push(function (result) {
-          if (id === "3") {
-            defer2.resolve();
-          }
-          assertExecutionOrder('stop put ' + id);
-          return result;
-        });
-    };
-
-    StorageTwoParallelOperation.prototype.get = function (id) {
-      var storage = this;
-      assertExecutionOrder('start get ' + id);
-      return new RSVP.Queue()
-        .push(function () {
-          if (id === "0") {
-            defer0 = RSVP.defer();
-            return defer0.promise;
-          }
-        })
-        .push(function () {
-          return storage._sub_storage.get(id);
-        })
-        .push(undefined, function (error) {
-          assertExecutionOrder('stop get ' + id);
-          throw error;
-        });
-    };
-    StorageTwoParallelOperation.prototype.buildQuery = function () {
-      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
-    };
-
-    StorageTwoParallelOperation.prototype.hasCapacity = function () {
-      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
-    };
-
-    jIO.addStorage(
-      'two_parallel',
-      StorageTwoParallelOperation
-    );
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      parallel_operation_amount: 2,
-      local_sub_storage: {
-        type: "memory"
-      },
-      remote_sub_storage: {
-        type: "two_parallel"
-      }
-    });
-
-    return RSVP.all([
-      context.jio.put("0", {"title": "foo"}),
-      context.jio.put("1", {"title": "foo1"}),
-      context.jio.put("2", {"title": "foo2"}),
-      context.jio.put("3", {"title": "foo3"})
-    ])
-      .then(function () {
-        return context.jio.repair();
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-
-  test("use 4 parallel operations", function () {
-    stop();
-    expect(16);
-
-    var context = this,
-      order_number = 0,
-      expected_order_list = [
-        'start get 0',
-        'start get 1',
-        'start get 2',
-        'start get 3',
-        'stop get 0',
-        'stop get 1',
-        'stop get 2',
-        'stop get 3',
-        'start put 0',
-        'start put 1',
-        'start put 2',
-        'start put 3',
-        'stop put 0',
-        'stop put 1',
-        'stop put 2',
-        'stop put 3'
-      ];
-
-    function assertExecutionOrder(text) {
-      equal(text, expected_order_list[order_number],
-            expected_order_list[order_number]);
-      order_number += 1;
-    }
-
-    function StorageFourParallelOperation() {
-      this._sub_storage = jIO.createJIO({type: "memory"});
-      return this;
-    }
-
-    StorageFourParallelOperation.prototype.put = function (id, doc) {
-      assertExecutionOrder('start put ' + id);
-      var storage = this;
-      return storage._sub_storage.put(id, doc)
-        .push(function (result) {
-          assertExecutionOrder('stop put ' + id);
-          return result;
-        });
-    };
-
-    StorageFourParallelOperation.prototype.get = function (id) {
-      assertExecutionOrder('start get ' + id);
-      var storage = this;
-      return storage._sub_storage.get(id)
-        .push(undefined, function (error) {
-          assertExecutionOrder('stop get ' + id);
-          throw error;
-        });
-    };
-    StorageFourParallelOperation.prototype.buildQuery = function () {
-      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
-    };
-
-    StorageFourParallelOperation.prototype.hasCapacity = function () {
-      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
-    };
-
-    jIO.addStorage(
-      'four_parallel',
-      StorageFourParallelOperation
-    );
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      parallel_operation_amount: 4,
-      local_sub_storage: {
-        type: "memory"
-      },
-      remote_sub_storage: {
-        type: "four_parallel"
-      }
-    });
-
-    return RSVP.all([
-      context.jio.put("0", {"title": "foo"}),
-      context.jio.put("1", {"title": "foo1"}),
-      context.jio.put("2", {"title": "foo2"}),
-      context.jio.put("3", {"title": "foo3"})
-    ])
-      .then(function () {
-        return context.jio.repair();
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  /////////////////////////////////////////////////////////////////
-  // attachment replication
-  /////////////////////////////////////////////////////////////////
-  module("replicateStorage.repair.attachment", {
-    setup: function () {
-      // Uses memory substorage, so that it is flushed after each run
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        check_local_attachment_creation: true,
-        check_local_attachment_modification: true,
-        check_local_attachment_deletion: true,
-        check_remote_attachment_creation: true,
-        check_remote_attachment_modification: true,
-        check_remote_attachment_deletion: true,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        }
-      });
-
-    }
-  });
-
-  test("local attachment creation", function () {
-    stop();
-    expect(2);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local attachment creation, local document creation not checked",
-       function () {
-      stop();
-      expect(6);
-
-      var id,
-        context = this,
-        blob = new Blob([big_string]);
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        check_local_creation: false,
-        check_local_attachment_creation: true,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        }
-      });
-
-      context.jio.post({"title": "foo"})
-        .then(function (result) {
-          id = result;
-          return context.jio.putAttachment(id, "foo", blob);
-        })
-        .then(function () {
-          return context.jio.repair();
-        })
-        .then(function () {
-          return context.jio.__storage._remote_sub_storage.getAttachment(
-            id,
-            "foo",
-            {format: "text"}
-          );
-        })
-        .fail(function (error) {
-          ok(error instanceof jIO.util.jIOError);
-          equal(error.status_code, 404);
-          equal(error.message, "Cannot find attachment: " + id + " , foo");
-          return context.jio.__storage._signature_sub_storage
-                        .getAttachment(id, "foo", {format: "json"});
-        })
-        .fail(function (error) {
-          ok(error instanceof jIO.util.jIOError);
-          equal(error.status_code, 404);
-          var error_message = "Cannot find attachment: " +
-            "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-            "jio_attachment/";
-          equal(
-            error.message.substring(0, error_message.length),
-            error_message
-          );
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local attachment creation not checked", function () {
-    stop();
-    expect(6);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_local_attachment_creation: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        var error_message = "Cannot find attachment: " +
-          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-          "jio_attachment/";
-        equal(
-          error.message.substring(0, error_message.length),
-          error_message
-        );
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local attachment creation, local document creation and use remote post",
-       function () {
-      stop();
-      expect(4);
-
-      var id,
-        context = this,
-        post_id,
-        blob = new Blob([big_string]);
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        use_remote_post: true,
-        check_local_attachment_creation: true,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        }
-      });
-
-      context.jio.post({"title": "foo"})
-        .then(function (result) {
-          id = result;
-          return context.jio.putAttachment(id, "foo", blob);
-        })
-        .then(function () {
-          return context.jio.repair();
-        })
-        // Another document should have been created
-        .then(function () {
-          return context.jio.__storage._remote_sub_storage.allDocs();
-        })
-        .then(function (result) {
-          equal(result.data.total_rows, 1);
-          post_id = result.data.rows[0].id;
-          return context.jio.getAttachment(
-            post_id,
-            "foo",
-            {format: "text"}
-          );
-        })
-        .then(function (result) {
-          equal(result, big_string);
-          return context.jio.__storage._remote_sub_storage.getAttachment(
-            post_id,
-            "foo",
-            {format: "text"}
-          );
-        })
-        .then(function (result) {
-          equal(result, big_string);
-          return context.jio.__storage._signature_sub_storage
-                        .getAttachment(post_id, "foo", {format: "json"});
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("remote attachment creation", function () {
-    stop();
-    expect(2);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    context.jio.__storage._remote_sub_storage.post({"title": "bar"})
-      .then(function (result) {
-        id = result;
-        return context.jio.__storage._remote_sub_storage
-                      .putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote attachment creation, remote document creation not checked",
-       function () {
-      stop();
-      expect(6);
-
-      var id,
-        context = this,
-        blob = new Blob([big_string]);
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        check_remote_creation: false,
-        check_local_attachment_creation: true,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        }
-      });
-
-      context.jio.__storage._remote_sub_storage.post({"title": "foo"})
-        .then(function (result) {
-          id = result;
-          return context.jio.__storage._remote_sub_storage
-                        .putAttachment(id, "foo", blob);
-        })
-        .then(function () {
-          return context.jio.repair();
-        })
-        .then(function () {
-          return context.jio.getAttachment(
-            id,
-            "foo",
-            {format: "text"}
-          );
-        })
-        .fail(function (error) {
-          ok(error instanceof jIO.util.jIOError);
-          equal(error.status_code, 404);
-          equal(error.message, "Cannot find attachment: " + id + " , foo");
-          return context.jio.__storage._signature_sub_storage
-                        .getAttachment(id, "foo", {format: "json"});
-        })
-        .fail(function (error) {
-          ok(error instanceof jIO.util.jIOError);
-          equal(error.status_code, 404);
-          var error_message = "Cannot find attachment: " +
-            "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-            "jio_attachment/";
-          equal(
-            error.message.substring(0, error_message.length),
-            error_message
-          );
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-
-  test("remote attachment creation not checked", function () {
-    stop();
-    expect(6);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_remote_attachment_creation: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.__storage._remote_sub_storage.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.__storage._remote_sub_storage
-                      .putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        var error_message = "Cannot find attachment: " +
-          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-          "jio_attachment/";
-        equal(
-          error.message.substring(0, error_message.length),
-          error_message
-        );
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote attachment creations", function () {
-    stop();
-    expect(5);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]);
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "conflict", blob),
-          context.jio.__storage._remote_sub_storage.putAttachment(id,
-                                                                  "conflict",
-                                                                  blob2)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        ok(false);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Conflict on 'foobar' with attachment 'conflict'");
-        equal(error.status_code, 409);
-      })
-      .then(function () {
-        return context.jio.__storage._signature_sub_storage.getAttachment(
-          id,
-          "conflict"
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-//        equal(error.message, "Cannot find document: conflict");
-        equal(error.status_code, 404);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote attachment creations: keep local", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 1,
-      check_local_attachment_creation: true,
-      check_remote_attachment_creation: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "conflict", blob),
-          context.jio.__storage._remote_sub_storage.putAttachment(id,
-                                                                  "conflict",
-                                                                  blob2)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote attachment creations: keep local, " +
-       "local not matching allAttachments", function () {
-      stop();
-      expect(3);
-
-      var context = this,
-        id = 'foobar',
-        blob = new Blob([big_string]),
-        blob2 = new Blob([big_string + "a"]);
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        conflict_handling: 1,
-        check_local_attachment_creation: true,
-        check_remote_attachment_creation: true,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "signaturestorageallattachments",
-            sub_storage: {
-              type: "memory"
-            }
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        }
-      });
-
-      context.jio.put(id, {"title": "foo"})
-        .push(function () {
-          return context.jio.repair();
-        })
-        .push(function () {
-          return RSVP.all([
-            context.jio.putAttachment(id, "conflict", blob),
-            context.jio.__storage._remote_sub_storage.putAttachment(id,
-                                                                    "conflict",
-                                                                    blob2)
-          ]);
-        })
-        .then(function () {
-          return context.jio.repair();
-        })
-         .then(function () {
-          return context.jio.getAttachment(
-            id,
-            "conflict",
-            {format: "text"}
-          );
-        })
-        .then(function (result) {
-          equal(result, big_string);
-          return context.jio.__storage._remote_sub_storage.getAttachment(
-            id,
-            "conflict",
-            {format: "text"}
-          );
-        })
-        .then(function (result) {
-          equal(result, big_string);
-          return context.jio.__storage._signature_sub_storage
-                        .getAttachment(id, "conflict", {format: "json"});
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local and remote attachment creations: keep local, " +
-       "remote not matching allAttachments", function () {
-      stop();
-      expect(3);
-
-      var context = this,
-        id = 'foobar',
-        blob = new Blob([big_string]),
-        blob2 = new Blob([big_string + "a"]);
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        conflict_handling: 1,
-        check_local_attachment_creation: true,
-        check_remote_attachment_creation: true,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "signaturestorageallattachments",
-            sub_storage: {
-              type: "memory"
-            }
-          }
-        }
-      });
-
-      context.jio.put(id, {"title": "foo"})
-        .push(function () {
-          return context.jio.repair();
-        })
-        .push(function () {
-          return RSVP.all([
-            context.jio.putAttachment(id, "conflict", blob),
-            context.jio.__storage._remote_sub_storage.putAttachment(id,
-                                                                    "conflict",
-                                                                    blob2)
-          ]);
-        })
-        .then(function () {
-          return context.jio.repair();
-        })
-         .then(function () {
-          return context.jio.getAttachment(
-            id,
-            "conflict",
-            {format: "text"}
-          );
-        })
-        .then(function (result) {
-          equal(result, big_string);
-          return context.jio.__storage._remote_sub_storage.getAttachment(
-            id,
-            "conflict",
-            {format: "text"}
-          );
-        })
-        .then(function (result) {
-          equal(result, big_string);
-          return context.jio.__storage._signature_sub_storage
-                        .getAttachment(id, "conflict", {format: "json"});
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local and remote attachment creations: keep remote", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 2,
-      check_local_attachment_creation: true,
-      check_remote_attachment_creation: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "conflict", blob),
-          context.jio.__storage._remote_sub_storage.putAttachment(id,
-                                                                  "conflict",
-                                                                  blob2)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote attachment creations: keep remote, " +
-       "local not matching allAttachments", function () {
-      stop();
-      expect(3);
-
-      var context = this,
-        id = 'foobar',
-        blob = new Blob([big_string]),
-        blob2 = new Blob([big_string + "a"]);
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        conflict_handling: 2,
-        check_local_attachment_creation: true,
-        check_remote_attachment_creation: true,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "signaturestorageallattachments",
-            sub_storage: {
-              type: "memory"
-            }
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        }
-      });
-
-      context.jio.put(id, {"title": "foo"})
-        .push(function () {
-          return context.jio.repair();
-        })
-        .push(function () {
-          return RSVP.all([
-            context.jio.putAttachment(id, "conflict", blob),
-            context.jio.__storage._remote_sub_storage.putAttachment(id,
-                                                                    "conflict",
-                                                                    blob2)
-          ]);
-        })
-        .then(function () {
-          return context.jio.repair();
-        })
-         .then(function () {
-          return context.jio.getAttachment(
-            id,
-            "conflict",
-            {format: "text"}
-          );
-        })
-        .then(function (result) {
-          equal(result, big_string + "a");
-          return context.jio.__storage._remote_sub_storage.getAttachment(
-            id,
-            "conflict",
-            {format: "text"}
-          );
-        })
-        .then(function (result) {
-          equal(result, big_string + "a");
-          return context.jio.__storage._signature_sub_storage
-                        .getAttachment(id, "conflict", {format: "json"});
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local and remote attachment creations: keep remote, " +
-       "remote not matching allAttachments", function () {
-      stop();
-      expect(3);
-
-      var context = this,
-        id = 'foobar',
-        blob = new Blob([big_string]),
-        blob2 = new Blob([big_string + "a"]);
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        conflict_handling: 2,
-        check_local_attachment_creation: true,
-        check_remote_attachment_creation: true,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "signaturestorageallattachments",
-            sub_storage: {
-              type: "memory"
-            }
-          }
-        }
-      });
-
-      context.jio.put(id, {"title": "foo"})
-        .push(function () {
-          return context.jio.repair();
-        })
-        .push(function () {
-          return RSVP.all([
-            context.jio.putAttachment(id, "conflict", blob),
-            context.jio.__storage._remote_sub_storage.putAttachment(id,
-                                                                    "conflict",
-                                                                    blob2)
-          ]);
-        })
-        .then(function () {
-          return context.jio.repair();
-        })
-         .then(function () {
-          return context.jio.getAttachment(
-            id,
-            "conflict",
-            {format: "text"}
-          );
-        })
-        .then(function (result) {
-          equal(result, big_string + "a");
-          return context.jio.__storage._remote_sub_storage.getAttachment(
-            id,
-            "conflict",
-            {format: "text"}
-          );
-        })
-        .then(function (result) {
-          equal(result, big_string + "a");
-          return context.jio.__storage._signature_sub_storage
-                        .getAttachment(id, "conflict", {format: "json"});
-        })
-        .then(function (result) {
-          deepEqual(result, {
-            hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
-          });
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local and remote attachment creations: continue", function () {
-    stop();
-    expect(4);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 3,
-      check_local_attachment_creation: true,
-      check_remote_attachment_creation: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "conflict", blob),
-          context.jio.__storage._remote_sub_storage.putAttachment(id,
-                                                                  "conflict",
-                                                                  blob2)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-//        equal(error.message, "Cannot find document: conflict");
-        equal(error.status_code, 404);
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote same attachment creations", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string]);
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "conflict", blob),
-          context.jio.__storage._remote_sub_storage.putAttachment(id,
-                                                                  "conflict",
-                                                                  blob2)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("no attachment modification", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]);
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local attachment modification", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]);
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob);
-      })
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob2);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local attachment modification not checked", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_local_attachment_creation: true,
-      check_local_attachment_modification: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob);
-      })
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob2);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote attachment modification", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]);
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob);
-      })
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.__storage._remote_sub_storage
-                          .putAttachment(id, "conflict", blob2);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote attachment modification not checked", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_local_attachment_creation: true,
-      check_remote_attachment_modification: false,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob);
-      })
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.__storage._remote_sub_storage
-                      .putAttachment(id, "conflict", blob2);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote attachment modifications", function () {
-    stop();
-    expect(6);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]),
-      blob3 = new Blob([big_string + "b"]);
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob);
-      })
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "conflict", blob2),
-          context.jio.__storage._remote_sub_storage
-                     .putAttachment(id, "conflict", blob3)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        ok(false);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.message, "Conflict on 'foobar' " +
-                             "with attachment 'conflict'");
-        equal(error.status_code, 409);
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "b");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote attachment modifications: keep local", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]),
-      blob3 = new Blob([big_string + "b"]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 1,
-      check_local_attachment_creation: true,
-      check_remote_attachment_creation: true,
-      check_local_attachment_modification: true,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob);
-      })
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "conflict", blob2),
-          context.jio.__storage._remote_sub_storage
-                     .putAttachment(id, "conflict", blob3)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote attachment modifications: keep remote", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]),
-      blob3 = new Blob([big_string + "b"]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 2,
-      check_local_attachment_creation: true,
-      check_remote_attachment_creation: true,
-      check_local_attachment_modification: true,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob);
-      })
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "conflict", blob2),
-          context.jio.__storage._remote_sub_storage
-                     .putAttachment(id, "conflict", blob3)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "b");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "b");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "9a73ce4f16b7fa5d2b4d8f723a754fef048fb9f8"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote attachment modifications: continue", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]),
-      blob3 = new Blob([big_string + "b"]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 3,
-      check_local_attachment_creation: true,
-      check_remote_attachment_creation: true,
-      check_local_attachment_modification: true,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob);
-      })
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "conflict", blob2),
-          context.jio.__storage._remote_sub_storage
-                     .putAttachment(id, "conflict", blob3)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "b");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote attachment same modifications", function () {
-    stop();
-    expect(3);
-
-    var context = this,
-      id = 'foobar',
-      blob = new Blob([big_string]),
-      blob2 = new Blob([big_string + "a"]);
-
-    context.jio.put(id, {"title": "foo"})
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return context.jio.putAttachment(id, "conflict", blob);
-      })
-      .push(function () {
-        return context.jio.repair();
-      })
-      .push(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "conflict", blob2),
-          context.jio.__storage._remote_sub_storage
-                     .putAttachment(id, "conflict", blob2)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "conflict",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string + "a");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "conflict", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local attachment deletion", function () {
-    stop();
-    expect(9);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.removeAttachment(id, "foo");
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        var error_message = "Cannot find attachment: " +
-          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-          "jio_attachment/";
-        equal(
-          error.message.substring(0, error_message.length),
-          error_message
-        );
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local attachment deletion not checked", function () {
-
-    stop();
-    expect(5);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_local_attachment_creation: true,
-      check_local_attachment_deletion: false,
-      check_local_attachment_modification: true,
-      check_remote_attachment_creation: true,
-      check_remote_attachment_deletion: true,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.removeAttachment(id, "foo");
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote attachment deletion", function () {
-    stop();
-    expect(9);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage
-                      .removeAttachment(id, "foo");
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        var error_message = "Cannot find attachment: " +
-          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-          "jio_attachment/";
-        equal(
-          error.message.substring(0, error_message.length),
-          error_message
-        );
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("remote attachment deletion not checked", function () {
-
-    stop();
-    expect(5);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_local_attachment_creation: true,
-      check_local_attachment_deletion: true,
-      check_local_attachment_modification: true,
-      check_remote_attachment_creation: true,
-      check_remote_attachment_deletion: false,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage
-                      .removeAttachment(id, "foo");
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(result, big_string);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local and remote attachment deletions", function () {
-    stop();
-    expect(9);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.removeAttachment(id, "foo"),
-          context.jio.__storage._remote_sub_storage
-                     .removeAttachment(id, "foo")
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        var error_message = "Cannot find attachment: " +
-          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-          "jio_attachment/";
-        equal(
-          error.message.substring(0, error_message.length),
-          error_message
-        );
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local deletion and remote modifications", function () {
-    stop();
-    expect(3);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string + "a"]),
-      blob2 = new Blob([big_string]);
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.removeAttachment(id, "foo"),
-          context.jio.__storage._remote_sub_storage
-                     .putAttachment(id, "foo", blob2)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(true, big_string === result);
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(true, big_string === result);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local deletion and remote modifications: keep local", function () {
-    stop();
-    expect(9);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string + "a"]),
-      blob2 = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 1,
-      check_local_attachment_creation: true,
-      check_local_attachment_deletion: true,
-      check_local_attachment_modification: true,
-      check_remote_attachment_creation: true,
-      check_remote_attachment_deletion: true,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.removeAttachment(id, "foo"),
-          context.jio.__storage._remote_sub_storage
-                     .putAttachment(id, "foo", blob2)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        var error_message = "Cannot find attachment: " +
-          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-          "jio_attachment/";
-        equal(
-          error.message.substring(0, error_message.length),
-          error_message
-        );
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local deletion and remote modifications: keep local, dont check local",
-       function () {
-      stop();
-      expect(9);
-
-      var id,
-        context = this,
-        blob = new Blob([big_string + "a"]),
-        blob2 = new Blob([big_string]);
-
-      this.jio = jIO.createJIO({
-        type: "replicate",
-        conflict_handling: 1,
-        check_local_attachment_creation: true,
-        check_local_attachment_deletion: false,
-        check_local_attachment_modification: true,
-        check_remote_attachment_creation: true,
-        check_remote_attachment_deletion: true,
-        check_remote_attachment_modification: true,
-        local_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        },
-        remote_sub_storage: {
-          type: "uuid",
-          sub_storage: {
-            type: "memory"
-          }
-        }
-      });
-
-      context.jio.post({"title": "foo"})
-        .then(function (result) {
-          id = result;
-          return context.jio.putAttachment(id, "foo", blob);
-        })
-        .then(function () {
-          return context.jio.repair();
-        })
-        .then(function () {
-          return RSVP.all([
-            context.jio.removeAttachment(id, "foo"),
-            context.jio.__storage._remote_sub_storage
-                       .putAttachment(id, "foo", blob2)
-          ]);
-        })
-        .then(function () {
-          return context.jio.repair();
-        })
-        .then(function () {
-          return context.jio.getAttachment(
-            id,
-            "foo",
-            {format: "text"}
-          );
-        })
-        .fail(function (error) {
-          ok(error instanceof jIO.util.jIOError);
-          equal(error.status_code, 404);
-          equal(error.message, "Cannot find attachment: " + id + " , foo");
-          return context.jio.__storage._remote_sub_storage.getAttachment(
-            id,
-            "foo",
-            {format: "text"}
-          );
-        })
-        .fail(function (error) {
-          ok(error instanceof jIO.util.jIOError);
-          equal(error.status_code, 404);
-          equal(error.message, "Cannot find attachment: " + id + " , foo");
-          return context.jio.__storage._signature_sub_storage
-                        .getAttachment(id, "foo", {format: "json"});
-        })
-        .fail(function (error) {
-          ok(error instanceof jIO.util.jIOError);
-          equal(error.status_code, 404);
-          var error_message = "Cannot find attachment: " +
-            "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-            "jio_attachment/";
-          equal(
-            error.message.substring(0, error_message.length),
-            error_message
-          );
-        })
-        .fail(function (error) {
-          ok(false, error);
-        })
-        .always(function () {
-          start();
-        });
-    });
-
-  test("local deletion and remote modifications: keep remote", function () {
-    stop();
-    expect(3);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string + "a"]),
-      blob2 = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 2,
-      check_local_attachment_creation: true,
-      check_local_attachment_deletion: true,
-      check_local_attachment_modification: true,
-      check_remote_attachment_creation: true,
-      check_remote_attachment_deletion: true,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.removeAttachment(id, "foo"),
-          context.jio.__storage._remote_sub_storage
-                     .putAttachment(id, "foo", blob2)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(true, big_string === result);
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(true, big_string === result);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local deletion and remote modifications: ignore", function () {
-    stop();
-    expect(5);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string + "a"]),
-      blob2 = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 3,
-      check_local_attachment_creation: true,
-      check_local_attachment_deletion: true,
-      check_local_attachment_modification: true,
-      check_remote_attachment_creation: true,
-      check_remote_attachment_deletion: true,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.removeAttachment(id, "foo"),
-          context.jio.__storage._remote_sub_storage
-                     .putAttachment(id, "foo", blob2)
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(true, big_string === result);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modifications and remote deletion", function () {
-    stop();
-    expect(3);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string + "a"]),
-      blob2 = new Blob([big_string]);
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "foo", blob2),
-          context.jio.__storage._remote_sub_storage
-                      .removeAttachment(id, "foo")
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(true, big_string === result);
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(true, big_string === result);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modifications and remote deletion: keep remote", function () {
-    stop();
-    expect(9);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string + "a"]),
-      blob2 = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 2,
-      check_local_attachment_creation: true,
-      check_local_attachment_deletion: true,
-      check_local_attachment_modification: true,
-      check_remote_attachment_creation: true,
-      check_remote_attachment_deletion: true,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "foo", blob2),
-          context.jio.__storage._remote_sub_storage.removeAttachment(id, "foo")
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        var error_message = "Cannot find attachment: " +
-          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-          "jio_attachment/";
-        equal(
-          error.message.substring(0, error_message.length),
-          error_message
-        );
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modifications and remote deletion: keep local", function () {
-    stop();
-    expect(3);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string + "a"]),
-      blob2 = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 1,
-      check_local_attachment_creation: true,
-      check_local_attachment_deletion: true,
-      check_local_attachment_modification: true,
-      check_remote_attachment_creation: true,
-      check_remote_attachment_deletion: true,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "foo", blob2),
-          context.jio.__storage._remote_sub_storage.removeAttachment(id, "foo")
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(true, big_string === result);
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(true, big_string === result);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modif and remote del: keep remote, not check modif", function () {
-    stop();
-    expect(9);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string + "a"]),
-      blob2 = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 2,
-      check_local_attachment_creation: true,
-      check_local_attachment_deletion: true,
-      check_local_attachment_modification: false,
-      check_remote_attachment_creation: true,
-      check_remote_attachment_deletion: true,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "foo", blob2),
-          context.jio.__storage._remote_sub_storage.removeAttachment(id, "foo")
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        var error_message = "Cannot find attachment: " +
-          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-          "jio_attachment/";
-        equal(
-          error.message.substring(0, error_message.length),
-          error_message
-        );
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("local modifications and remote deletion: ignore", function () {
-    stop();
-    expect(5);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string + "a"]),
-      blob2 = new Blob([big_string]);
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      conflict_handling: 3,
-      check_local_attachment_creation: true,
-      check_local_attachment_deletion: true,
-      check_local_attachment_modification: true,
-      check_remote_attachment_creation: true,
-      check_remote_attachment_deletion: true,
-      check_remote_attachment_modification: true,
-      local_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      },
-      remote_sub_storage: {
-        type: "uuid",
-        sub_storage: {
-          type: "memory"
-        }
-      }
-    });
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return RSVP.all([
-          context.jio.putAttachment(id, "foo", blob2),
-          context.jio.__storage._remote_sub_storage.removeAttachment(id, "foo")
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .then(function (result) {
-        equal(true, big_string === result);
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .then(function (result) {
-        deepEqual(result, {
-          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
-        });
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  /////////////////////////////////////////////////////////////////
-  // attachment replication performance
-  /////////////////////////////////////////////////////////////////
-  test("document and attachment deletion performance", function () {
-    stop();
-    expect(12);
-
-    var id,
-      context = this,
-      blob = new Blob([big_string]);
-
-    context.jio.post({"title": "foo"})
-      .then(function (result) {
-        id = result;
-        return context.jio.putAttachment(id, "foo", blob);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.remove(id);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .then(function () {
-        return context.jio.__storage._remote_sub_storage.getAttachment(
-          id,
-          "foo",
-          {format: "text"}
-        );
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find attachment: " + id + " , foo");
-        return context.jio.__storage._remote_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        equal(error.message, "Cannot find document: " + id);
-        return context.jio.__storage._signature_sub_storage
-                      .getAttachment(id, "foo", {format: "json"});
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        var error_message = "Cannot find attachment: " +
-          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-          "jio_attachment/";
-        equal(
-          error.message.substring(0, error_message.length),
-          error_message
-        );
-        return context.jio.__storage._signature_sub_storage.get(id);
-      })
-      .fail(function (error) {
-        ok(error instanceof jIO.util.jIOError);
-        equal(error.status_code, 404);
-        var error_message = "Cannot find attachment: " +
-          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
-          "jio_document/";
-        equal(
-          error.message.substring(0, error_message.length),
-          error_message
-        );
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("use 1 parallel operation", function () {
-    stop();
-    expect(40);
-
-    var context = this,
-      order_number = 0,
-      expected_order_list = [
-        'start get 0',
-        'stop get 0',
-        'start put 0',
-        'stop put 0',
-        'start get 1',
-        'stop get 1',
-        'start put 1',
-        'stop put 1',
-        'start getAttachment 00',
-        'stop getAttachment 00',
-        'start putAttachment 00',
-        'stop putAttachment 00',
-        'start getAttachment 01',
-        'stop getAttachment 01',
-        'start putAttachment 01',
-        'stop putAttachment 01',
-        'start getAttachment 02',
-        'stop getAttachment 02',
-        'start putAttachment 02',
-        'stop putAttachment 02',
-        'start getAttachment 03',
-        'stop getAttachment 03',
-        'start putAttachment 03',
-        'stop putAttachment 03',
-        'start getAttachment 10',
-        'stop getAttachment 10',
-        'start putAttachment 10',
-        'stop putAttachment 10',
-        'start getAttachment 11',
-        'stop getAttachment 11',
-        'start putAttachment 11',
-        'stop putAttachment 11',
-        'start getAttachment 12',
-        'stop getAttachment 12',
-        'start putAttachment 12',
-        'stop putAttachment 12',
-        'start getAttachment 13',
-        'stop getAttachment 13',
-        'start putAttachment 13',
-        'stop putAttachment 13'
-      ];
-
-    function assertExecutionOrder(text) {
-      equal(text, expected_order_list[order_number],
-            expected_order_list[order_number]);
-      order_number += 1;
-    }
-
-    function StorageOneParallelOperation() {
-      this._sub_storage = jIO.createJIO({type: "memory"});
-      return this;
-    }
-
-    StorageOneParallelOperation.prototype.put = function (id, doc) {
-      assertExecutionOrder('start put ' + id);
-      var storage = this;
-      return storage._sub_storage.put(id, doc)
-        .push(function (result) {
-          assertExecutionOrder('stop put ' + id);
-          return result;
-        });
-    };
-
-    StorageOneParallelOperation.prototype.get = function (id) {
-      assertExecutionOrder('start get ' + id);
-      var storage = this;
-      return storage._sub_storage.get(id)
-        .push(undefined, function (error) {
-          assertExecutionOrder('stop get ' + id);
-          throw error;
-        });
-    };
-
-    StorageOneParallelOperation.prototype.getAttachment = function (id, name) {
-      assertExecutionOrder('start getAttachment ' + name);
-      var storage = this;
-      return storage._sub_storage.getAttachment(id, name)
-        .push(undefined, function (error) {
-          assertExecutionOrder('stop getAttachment ' + name);
-          throw error;
-        });
-    };
-
-    StorageOneParallelOperation.prototype.putAttachment = function (id, name,
-                                                                    blob) {
-      assertExecutionOrder('start putAttachment ' + name);
-      var storage = this;
-      return storage._sub_storage.putAttachment(id, name, blob)
-        .push(function (result) {
-          assertExecutionOrder('stop putAttachment ' + name);
-          return result;
-        });
-    };
-
-    StorageOneParallelOperation.prototype.buildQuery = function () {
-      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
-    };
-    StorageOneParallelOperation.prototype.allAttachments = function () {
-      return this._sub_storage.allAttachments.apply(this._sub_storage,
-        arguments);
-    };
-
-    StorageOneParallelOperation.prototype.hasCapacity = function () {
-      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
-    };
-
-    jIO.addStorage(
-      'one_parallel_attachment',
-      StorageOneParallelOperation
-    );
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_local_attachment_creation: true,
-      local_sub_storage: {
-        type: "memory"
-      },
-      remote_sub_storage: {
-        type: "one_parallel_attachment"
-      }
-    });
-
-    return RSVP.all([
-      context.jio.put("0", {}),
-      context.jio.put("1", {})
-    ])
-      .then(function () {
-        return RSVP.all([
-          context.jio.putAttachment("0", "00", new Blob(["0"])),
-          context.jio.putAttachment("0", "01", new Blob(["1"])),
-          context.jio.putAttachment("0", "02", new Blob(["2"])),
-          context.jio.putAttachment("0", "03", new Blob(["3"])),
-          context.jio.putAttachment("1", "10", new Blob(["0"])),
-          context.jio.putAttachment("1", "11", new Blob(["1"])),
-          context.jio.putAttachment("1", "12", new Blob(["2"])),
-          context.jio.putAttachment("1", "13", new Blob(["3"]))
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("use 2 parallel operation", function () {
-    stop();
-    expect(40);
-
-    var context = this,
-      order_number = 0,
-      expected_order_list = [
-        'start get 0',
-        'stop get 0',
-        'start put 0',
-        'stop put 0',
-        'start get 1',
-        'stop get 1',
-        'start put 1',
-        'stop put 1',
-
-        'start getAttachment 00',
-
-        'start getAttachment 01',
-        'stop getAttachment 01',
-        'start putAttachment 01',
-        'stop putAttachment 01',
-        'start getAttachment 02',
-        'stop getAttachment 02',
-        'start putAttachment 02',
-
-        'stop getAttachment 00',
-        'start putAttachment 00',
-        'stop putAttachment 00',
-        'start getAttachment 03',
-        'stop getAttachment 03',
-        'start putAttachment 03',
-        'stop putAttachment 03',
-
-        'stop putAttachment 02',
-
-        'start getAttachment 10',
-
-        'start getAttachment 11',
-        'stop getAttachment 11',
-        'start putAttachment 11',
-        'stop putAttachment 11',
-        'start getAttachment 12',
-        'stop getAttachment 12',
-        'start putAttachment 12',
-
-        'stop getAttachment 10',
-        'start putAttachment 10',
-        'stop putAttachment 10',
-        'start getAttachment 13',
-        'stop getAttachment 13',
-        'start putAttachment 13',
-        'stop putAttachment 13',
-
-        'stop putAttachment 12'
-      ],
-      defer0,
-      defer2;
-
-    function assertExecutionOrder(text) {
-      equal(text, expected_order_list[order_number],
-            expected_order_list[order_number]);
-      order_number += 1;
-    }
-
-    function StorageTwoParallelOperation() {
-      this._sub_storage = jIO.createJIO({type: "memory"});
-      return this;
-    }
-
-    StorageTwoParallelOperation.prototype.put = function (id, doc) {
-      assertExecutionOrder('start put ' + id);
-      var storage = this;
-      return storage._sub_storage.put(id, doc)
-        .push(function (result) {
-          assertExecutionOrder('stop put ' + id);
-          return result;
-        });
-    };
-
-    StorageTwoParallelOperation.prototype.get = function (id) {
-      assertExecutionOrder('start get ' + id);
-      var storage = this;
-      return storage._sub_storage.get(id)
-        .push(undefined, function (error) {
-          assertExecutionOrder('stop get ' + id);
-          throw error;
-        });
-    };
-
-
-    StorageTwoParallelOperation.prototype.getAttachment = function (id,
-                                                                     name) {
-      assertExecutionOrder('start getAttachment ' + name);
-      var storage = this;
-      return new RSVP.Queue()
-        .push(function () {
-          if (name[1] === "0") {
-            defer0 = RSVP.defer();
-            return defer0.promise;
-          }
-        })
-        .push(function () {
-          return storage._sub_storage.getAttachment(id, name);
-        })
-        .push(undefined, function (error) {
-          assertExecutionOrder('stop getAttachment ' + name);
-          throw error;
-        });
-    };
-
-    StorageTwoParallelOperation.prototype.putAttachment = function (id, name,
-                                                                     blob) {
-      assertExecutionOrder('start putAttachment ' + name);
-      var storage = this;
-      return new RSVP.Queue()
-        .push(function () {
-          if (name[1] === "2") {
-            defer0.resolve();
-            defer2 = RSVP.defer();
-            return defer2.promise;
-          }
-        })
-        .push(function () {
-          return storage._sub_storage.putAttachment(id, name, blob);
-        })
-        .push(function (result) {
-          if (name[1] === "3") {
-            defer2.resolve();
-          }
-          assertExecutionOrder('stop putAttachment ' + name);
-          return result;
-        });
-    };
-
-
-    StorageTwoParallelOperation.prototype.buildQuery = function () {
-      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
-    };
-    StorageTwoParallelOperation.prototype.allAttachments = function () {
-      return this._sub_storage.allAttachments.apply(this._sub_storage,
-        arguments);
-    };
-
-    StorageTwoParallelOperation.prototype.hasCapacity = function () {
-      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
-    };
-
-    jIO.addStorage(
-      'two_parallel_attachment',
-      StorageTwoParallelOperation
-    );
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_local_attachment_creation: true,
-      parallel_operation_attachment_amount: 2,
-      local_sub_storage: {
-        type: "memory"
-      },
-      remote_sub_storage: {
-        type: "two_parallel_attachment"
-      }
-    });
-
-    return RSVP.all([
-      context.jio.put("0", {}),
-      context.jio.put("1", {})
-    ])
-      .then(function () {
-        return RSVP.all([
-          context.jio.putAttachment("0", "00", new Blob(["0"])),
-          context.jio.putAttachment("0", "01", new Blob(["1"])),
-          context.jio.putAttachment("0", "02", new Blob(["2"])),
-          context.jio.putAttachment("0", "03", new Blob(["3"])),
-          context.jio.putAttachment("1", "10", new Blob(["0"])),
-          context.jio.putAttachment("1", "11", new Blob(["1"])),
-          context.jio.putAttachment("1", "12", new Blob(["2"])),
-          context.jio.putAttachment("1", "13", new Blob(["3"]))
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-  test("use 4 parallel operation", function () {
-    stop();
-    expect(40);
-
-    var context = this,
-      order_number = 0,
-      expected_order_list = [
-        'start get 0',
-        'stop get 0',
-        'start put 0',
-        'stop put 0',
-        'start get 1',
-        'stop get 1',
-        'start put 1',
-        'stop put 1',
-
-        'start getAttachment 00',
-        'stop getAttachment 00',
-        'start putAttachment 00',
-
-        'start getAttachment 01',
-        'stop getAttachment 01',
-        'start putAttachment 01',
-
-        'start getAttachment 02',
-        'stop getAttachment 02',
-        'start putAttachment 02',
-
-        'start getAttachment 03',
-        'stop getAttachment 03',
-        'start putAttachment 03',
-
-        'stop putAttachment 00',
-        'stop putAttachment 01',
-        'stop putAttachment 02',
-        'stop putAttachment 03',
-
-        'start getAttachment 10',
-        'stop getAttachment 10',
-        'start putAttachment 10',
-
-        'start getAttachment 11',
-        'stop getAttachment 11',
-        'start putAttachment 11',
-
-        'start getAttachment 12',
-        'stop getAttachment 12',
-        'start putAttachment 12',
-
-        'start getAttachment 13',
-        'stop getAttachment 13',
-        'start putAttachment 13',
-
-        'stop putAttachment 10',
-        'stop putAttachment 11',
-        'stop putAttachment 12',
-        'stop putAttachment 13'
-
-      ];
-
-    function assertExecutionOrder(text) {
-      equal(text, expected_order_list[order_number],
-            expected_order_list[order_number]);
-      order_number += 1;
-    }
-
-    function StorageFourParallelOperation() {
-      this._sub_storage = jIO.createJIO({type: "memory"});
-      return this;
-    }
-
-    StorageFourParallelOperation.prototype.put = function (id, doc) {
-      assertExecutionOrder('start put ' + id);
-      var storage = this;
-      return storage._sub_storage.put(id, doc)
-        .push(function (result) {
-          assertExecutionOrder('stop put ' + id);
-          return result;
-        });
-    };
-
-    StorageFourParallelOperation.prototype.get = function (id) {
-      assertExecutionOrder('start get ' + id);
-      var storage = this;
-      return storage._sub_storage.get(id)
-        .push(undefined, function (error) {
-          assertExecutionOrder('stop get ' + id);
-          throw error;
-        });
-    };
-
-    StorageFourParallelOperation.prototype.getAttachment = function (id,
-                                                                     name) {
-      assertExecutionOrder('start getAttachment ' + name);
-      var storage = this;
-      return storage._sub_storage.getAttachment(id, name)
-        .push(undefined, function (error) {
-          assertExecutionOrder('stop getAttachment ' + name);
-          throw error;
-        });
-    };
-
-    StorageFourParallelOperation.prototype.putAttachment = function (id, name,
-                                                                     blob) {
-      assertExecutionOrder('start putAttachment ' + name);
-      var storage = this;
-      return storage._sub_storage.putAttachment(id, name, blob)
-        .push(function (result) {
-          assertExecutionOrder('stop putAttachment ' + name);
-          return result;
-        });
-    };
-
-    StorageFourParallelOperation.prototype.buildQuery = function () {
-      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
-    };
-    StorageFourParallelOperation.prototype.allAttachments = function () {
-      return this._sub_storage.allAttachments.apply(this._sub_storage,
-        arguments);
-    };
-
-    StorageFourParallelOperation.prototype.hasCapacity = function () {
-      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
-    };
-
-    jIO.addStorage(
-      'four_parallel_attachment',
-      StorageFourParallelOperation
-    );
-
-    this.jio = jIO.createJIO({
-      type: "replicate",
-      check_local_attachment_creation: true,
-      parallel_operation_attachment_amount: 4,
-      local_sub_storage: {
-        type: "memory"
-      },
-      remote_sub_storage: {
-        type: "four_parallel_attachment"
-      }
-    });
-
-    return RSVP.all([
-      context.jio.put("0", {}),
-      context.jio.put("1", {})
-    ])
-      .then(function () {
-        return RSVP.all([
-          context.jio.putAttachment("0", "00", new Blob(["0"])),
-          context.jio.putAttachment("0", "01", new Blob(["1"])),
-          context.jio.putAttachment("0", "02", new Blob(["2"])),
-          context.jio.putAttachment("0", "03", new Blob(["3"])),
-          context.jio.putAttachment("1", "10", new Blob(["0"])),
-          context.jio.putAttachment("1", "11", new Blob(["1"])),
-          context.jio.putAttachment("1", "12", new Blob(["2"])),
-          context.jio.putAttachment("1", "13", new Blob(["3"]))
-        ]);
-      })
-      .then(function () {
-        return context.jio.repair();
-      })
-      .fail(function (error) {
-        ok(false, error);
-      })
-      .always(function () {
-        start();
-      });
-  });
-
-}(jIO, QUnit, Blob, RSVP));
\ No newline at end of file
+}(jIO, QUnit, Blob));
\ No newline at end of file
diff --git a/test/jio.storage/replicatestorage_repair.tests.js b/test/jio.storage/replicatestorage_repair.tests.js
new file mode 100644
index 0000000000000000000000000000000000000000..45afa3a9ec3393f25925d627445298e1511349f4
--- /dev/null
+++ b/test/jio.storage/replicatestorage_repair.tests.js
@@ -0,0 +1,3672 @@
+/*jslint nomen: true*/
+/*global Blob, RSVP*/
+(function (jIO, QUnit, Blob, RSVP) {
+  "use strict";
+  var test = QUnit.test,
+    stop = QUnit.stop,
+    start = QUnit.start,
+    ok = QUnit.ok,
+    expect = QUnit.expect,
+    deepEqual = QUnit.deepEqual,
+    equal = QUnit.equal,
+    module = QUnit.module,
+    big_string = "",
+    j;
+
+  for (j = 0; j < 30; j += 1) {
+    big_string += "a";
+  }
+
+  /////////////////////////////////////////////////////////////////
+  // replicateStorage.repair use cases
+  /////////////////////////////////////////////////////////////////
+  module("replicateStorage.repair.document", {
+    setup: function () {
+      // Uses memory substorage, so that it is flushed after each run
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        }
+      });
+
+    }
+  });
+
+  /////////////////////////////////////////////////////////////////
+  // document replication
+  /////////////////////////////////////////////////////////////////
+
+  test("local document creation", function () {
+    stop();
+    expect(2);
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local document creation not checked", function () {
+    stop();
+    expect(6);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_local_creation: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local document creation and use remote post", function () {
+    stop();
+    expect(13);
+
+    var id,
+      post_id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      use_remote_post: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, 'foo', blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      // Document 'id' has been deleted in both storages
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._local_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function () {
+        ok(false, "Signature should have been deleted");
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+      })
+
+      // But another document should have been created
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.allDocs();
+      })
+      .then(function (result) {
+        equal(result.data.total_rows, 1);
+        post_id = result.data.rows[0].id;
+        return context.jio.__storage._remote_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._local_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+        // Attachment should be kept
+        return context.jio.__storage._local_sub_storage
+                      .getAttachment(post_id, 'foo', {format: 'text'});
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._signature_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local document creation, remote post and delayed allDocs", function () {
+    stop();
+    expect(11);
+
+    var id,
+      post_id = "_foobar",
+      context = this;
+
+    function Storage200DelayedAllDocs(spec) {
+      this._sub_storage = jIO.createJIO(spec.sub_storage);
+    }
+    Storage200DelayedAllDocs.prototype.get = function () {
+      return this._sub_storage.get.apply(this._sub_storage, arguments);
+    };
+    Storage200DelayedAllDocs.prototype.post = function (param) {
+      return this.put(post_id, param);
+    };
+    Storage200DelayedAllDocs.prototype.put = function () {
+      return this._sub_storage.put.apply(this._sub_storage, arguments);
+    };
+    Storage200DelayedAllDocs.prototype.hasCapacity = function () {
+      return true;
+    };
+    Storage200DelayedAllDocs.prototype.buildQuery = function () {
+      return [];
+    };
+    jIO.addStorage(
+      'replicatestorage200delayedalldocs',
+      Storage200DelayedAllDocs
+    );
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      use_remote_post: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "replicatestorage200delayedalldocs",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      // Document 'id' has been deleted in both storages
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._local_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+      })
+
+      // But another document should have been created
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._local_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote document creation", function () {
+    stop();
+    expect(2);
+
+    var id,
+      context = this;
+
+    context.jio.__storage._remote_sub_storage.post({"title": "bar"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "bar"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "6799f3ea80e325b89f19589282a343c376c1f1af"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote document creation not checked", function () {
+    stop();
+    expect(6);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_remote_creation: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.__storage._remote_sub_storage.post({"title": "bar"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "bar"
+        });
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote document creations", function () {
+    stop();
+    expect(5);
+
+    var context = this;
+
+    RSVP.all([
+      context.jio.put("conflict", {"title": "foo"}),
+      context.jio.__storage._remote_sub_storage.put("conflict",
+                                                    {"title": "bar"})
+    ])
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        ok(false);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Conflict on 'conflict': " +
+                             "{\"title\":\"foo\"} !== {\"title\":\"bar\"}");
+        equal(error.status_code, 409);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get("conflict");
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+//        equal(error.message, "Cannot find document: conflict");
+        equal(error.status_code, 404);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote document creations: keep local", function () {
+    stop();
+    expect(3);
+
+    var context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      conflict_handling: 1
+    });
+
+    RSVP.all([
+      context.jio.put("conflict", {"title": "foo"}),
+      context.jio.__storage._remote_sub_storage.put("conflict",
+                                                    {"title": "bar"})
+    ])
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get("conflict");
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .then(function () {
+        return context.jio.get("conflict");
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get("conflict");
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote document creations: keep local, remote post",
+    function () {
+      stop();
+      expect(3);
+
+      var context = this;
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        use_remote_post: 1,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        conflict_handling: 1
+      });
+
+      RSVP.all([
+        context.jio.put("conflict", {"title": "foo"}),
+        context.jio.__storage._remote_sub_storage.put("conflict",
+                                                      {"title": "bar"})
+      ])
+        .then(function () {
+          return context.jio.repair();
+        })
+        .then(function () {
+          return context.jio.__storage._signature_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+          });
+        })
+        .then(function () {
+          return context.jio.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "foo"
+          });
+        })
+        .then(function () {
+          return context.jio.__storage._remote_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "foo"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local and remote document creations: keep local, " +
+       "local not matching query", function () {
+      stop();
+      expect(3);
+
+      var context = this;
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        local_sub_storage: {
+          type: "query",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "query",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        query: {query: 'type: "foobar"'},
+        conflict_handling: 1
+      });
+
+      RSVP.all([
+        context.jio.put("conflict", {"title": "foo"}),
+        context.jio.__storage._remote_sub_storage.put("conflict",
+                                                      {"title": "bar",
+                                                       "type": "foobar"})
+      ])
+        .then(function () {
+          return context.jio.repair();
+        })
+        .then(function () {
+          return context.jio.__storage._signature_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+          });
+        })
+        .then(function () {
+          return context.jio.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "foo"
+          });
+        })
+        .then(function () {
+          return context.jio.__storage._remote_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "foo"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local and remote document creations: keep local, " +
+       "remote not matching query", function () {
+      stop();
+      expect(3);
+
+      var context = this;
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        local_sub_storage: {
+          type: "query",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "query",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        query: {query: 'type: "foobar"'},
+        conflict_handling: 1
+      });
+
+      RSVP.all([
+        context.jio.put("conflict", {"title": "foo", "type": "foobar"}),
+        context.jio.__storage._remote_sub_storage.put("conflict",
+                                                      {"title": "bar"})
+      ])
+        .then(function () {
+          return context.jio.repair();
+        })
+        .then(function () {
+          return context.jio.__storage._signature_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            hash: "a0a1b37cee3709101b752c56e59b9d66cce09961"
+          });
+        })
+        .then(function () {
+          return context.jio.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "foo",
+            type: "foobar"
+          });
+        })
+        .then(function () {
+          return context.jio.__storage._remote_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "foo",
+            type: "foobar"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local and remote document creations: keep remote", function () {
+    stop();
+    expect(3);
+
+    var context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      conflict_handling: 2
+    });
+
+    RSVP.all([
+      context.jio.put("conflict", {"title": "foo"}),
+      context.jio.__storage._remote_sub_storage.put("conflict",
+                                                    {"title": "bar"})
+    ])
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get("conflict");
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "6799f3ea80e325b89f19589282a343c376c1f1af"
+        });
+      })
+      .then(function () {
+        return context.jio.get("conflict");
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "bar"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get("conflict");
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "bar"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote document creations: keep remote, remote post",
+    function () {
+      stop();
+      expect(3);
+
+      var context = this;
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        use_remote_post: 1,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        conflict_handling: 2
+      });
+
+      RSVP.all([
+        context.jio.put("conflict", {"title": "foo"}),
+        context.jio.__storage._remote_sub_storage.put("conflict",
+                                                      {"title": "bar"})
+      ])
+        .then(function () {
+          return context.jio.repair();
+        })
+        .then(function () {
+          return context.jio.__storage._signature_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            hash: "6799f3ea80e325b89f19589282a343c376c1f1af"
+          });
+        })
+        .then(function () {
+          return context.jio.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "bar"
+          });
+        })
+        .then(function () {
+          return context.jio.__storage._remote_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "bar"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local and remote document creations: keep remote, " +
+       "local not matching query", function () {
+      stop();
+      expect(3);
+
+      var context = this;
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        local_sub_storage: {
+          type: "query",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "query",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        query: {query: 'type: "foobar"'},
+        conflict_handling: 2
+      });
+
+      RSVP.all([
+        context.jio.put("conflict", {"title": "foo"}),
+        context.jio.__storage._remote_sub_storage.put("conflict",
+                                                      {"title": "bar",
+                                                       "type": "foobar"})
+      ])
+        .then(function () {
+          return context.jio.repair();
+        })
+        .then(function () {
+          return context.jio.__storage._signature_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            hash: "45efa2292d54cc4ce1f726ea197bc0b9721fc1dc"
+          });
+        })
+        .then(function () {
+          return context.jio.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "bar",
+            type: "foobar"
+          });
+        })
+        .then(function () {
+          return context.jio.__storage._remote_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "bar",
+            type: "foobar"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local and remote document creations: keep remote, " +
+       "remote not matching query", function () {
+      stop();
+      expect(3);
+
+      var context = this;
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        local_sub_storage: {
+          type: "query",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "query",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        query: {query: 'type: "foobar"'},
+        conflict_handling: 2
+      });
+
+      RSVP.all([
+        context.jio.put("conflict", {"title": "foo", "type": "foobar"}),
+        context.jio.__storage._remote_sub_storage.put("conflict",
+                                                      {"title": "bar"})
+      ])
+        .then(function () {
+          return context.jio.repair();
+        })
+        .then(function () {
+          return context.jio.__storage._signature_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            hash: "6799f3ea80e325b89f19589282a343c376c1f1af"
+          });
+        })
+        .then(function () {
+          return context.jio.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "bar"
+          });
+        })
+        .then(function () {
+          return context.jio.__storage._remote_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "bar"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local and remote document creations: continue", function () {
+    stop();
+    expect(4);
+
+    var context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      conflict_handling: 3
+    });
+
+    RSVP.all([
+      context.jio.put("conflict", {"title": "foo"}),
+      context.jio.__storage._remote_sub_storage.put("conflict",
+                                                    {"title": "bar"})
+    ])
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get("conflict");
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+//        equal(error.message, "Cannot find document: conflict");
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.get("conflict");
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get("conflict");
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "bar"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote document creations: continue, remote post",
+    function () {
+      stop();
+      expect(4);
+
+      var context = this;
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        use_remote_post: 1,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        conflict_handling: 3
+      });
+
+      RSVP.all([
+        context.jio.put("conflict", {"title": "foo"}),
+        context.jio.__storage._remote_sub_storage.put("conflict",
+                                                      {"title": "bar"})
+      ])
+        .then(function () {
+          return context.jio.repair();
+        })
+        .then(function () {
+          return context.jio.__storage._signature_sub_storage.get("conflict");
+        })
+        .fail(function (error) {
+          ok(error instanceof jIO.util.jIOError);
+          //        equal(error.message, "Cannot find document: conflict");
+          equal(error.status_code, 404);
+        })
+        .then(function () {
+          return context.jio.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "foo"
+          });
+        })
+        .then(function () {
+          return context.jio.__storage._remote_sub_storage.get("conflict");
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            title: "bar"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local and remote same document creations", function () {
+    stop();
+    expect(1);
+
+    var context = this;
+
+    RSVP.all([
+      context.jio.put("conflict", {"title": "foo"}),
+      context.jio.__storage._remote_sub_storage.put("conflict",
+                                                    {"title": "foo"})
+    ])
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get("conflict");
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("no modification", function () {
+    stop();
+    expect(2);
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local document modification", function () {
+    stop();
+    expect(2);
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.put(id, {"title": "foo2"});
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo2"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "9819187e39531fdc9bcfd40dbc6a7d3c78fe8dab"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+
+  test("local document modification: use remote post", function () {
+    stop();
+    expect(2);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      use_remote_post: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.__storage._remote_sub_storage.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.put(id, {"title": "foo2"});
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo2"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "9819187e39531fdc9bcfd40dbc6a7d3c78fe8dab"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local document modification not checked", function () {
+    stop();
+    expect(3);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_local_modification: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.put(id, {"title": "foo2"});
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo2"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote document modification", function () {
+    stop();
+    expect(2);
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.put(
+          id,
+          {"title": "foo3"}
+        );
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo3"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "4b1dde0f80ac38514771a9d25b5278e38f560e0f"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote document modification not checked", function () {
+    stop();
+    expect(3);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_remote_modification: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.put(
+          id,
+          {"title": "foo3"}
+        );
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo3"
+        });
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote document modifications", function () {
+    stop();
+    expect(4);
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo4"}),
+          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo5"})
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        ok(false);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Conflict on '" + id + "': " +
+                             "{\"title\":\"foo4\"} !== {\"title\":\"foo5\"}");
+        equal(error.status_code, 409);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote document modifications: keep local", function () {
+    stop();
+    expect(3);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      conflict_handling: 1
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo4"}),
+          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo5"})
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "6f700e813022233a785692585484c21cb5a412fd"
+        });
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo4"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote document modifications: keep remote", function () {
+    stop();
+    expect(3);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      conflict_handling: 2
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo4"}),
+          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo5"})
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "7bea6f87fd1dda14e340e5b14836cc8578fd615f"
+        });
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo5"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo5"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote document modifications: continue", function () {
+    stop();
+    expect(3);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      conflict_handling: 3
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo4"}),
+          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo5"})
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo4"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo5"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote document same modifications", function () {
+    stop();
+    expect(1);
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo99"}),
+          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo99"})
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local document deletion", function () {
+    stop();
+    expect(6);
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.remove(id);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        ok(true, "Removal correctly synced");
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id)
+          .then(function () {
+            ok(false, "Signature should be deleted");
+          })
+          .fail(function (error) {
+            ok(error instanceof jIO.util.jIOError);
+//            equal(error.message, "Cannot find document: " + id);
+            equal(error.status_code, 404);
+          });
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local document deletion not checked", function () {
+    stop();
+    expect(6);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_local_deletion: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.remove(id);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        ok(true, "Removal correctly synced");
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local document deletion with attachment", function () {
+    stop();
+    expect(7);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.remove(id);
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage
+                      .putAttachment(id, 'foo', blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        ok(true, "Removal correctly synced");
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage
+                      .getAttachment(id, 'foo', {format: 'text'});
+      })
+      .then(function (result) {
+        equal(result, big_string);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote document deletion", function () {
+    stop();
+    expect(6);
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.remove(id);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        ok(true, "Removal correctly synced");
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id)
+          .then(function () {
+            ok(false, "Signature should be deleted");
+          })
+          .fail(function (error) {
+            ok(error instanceof jIO.util.jIOError);
+//            equal(error.message, "Cannot find document: " + id);
+            equal(error.status_code, 404);
+          });
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote document deletion not checked", function () {
+    stop();
+    expect(6);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_remote_deletion: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.remove(id);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        ok(true, "Removal correctly synced");
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote document deletion with attachment", function () {
+    stop();
+    expect(7);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.remove(id);
+      })
+      .then(function () {
+        return context.jio.putAttachment(id, 'foo', blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        ok(true, "Removal correctly synced");
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo"
+        });
+      })
+      .then(function () {
+        return context.jio.getAttachment(id, 'foo', {format: 'text'});
+      })
+      .then(function (result) {
+        equal(result, big_string);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote document deletions", function () {
+    stop();
+    expect(8);
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.remove(id),
+          context.jio.__storage._remote_sub_storage.remove(id)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.get(id)
+          .then(function () {
+            ok(false, "Document should be locally deleted");
+          })
+          .fail(function (error) {
+            ok(error instanceof jIO.util.jIOError);
+            equal(error.message, "Cannot find document: " + id);
+            equal(error.status_code, 404);
+          });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id)
+          .then(function () {
+            ok(false, "Document should be remotely deleted");
+          })
+          .fail(function (error) {
+            ok(error instanceof jIO.util.jIOError);
+            equal(error.message, "Cannot find document: " + id);
+            equal(error.status_code, 404);
+          });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id)
+          .then(function () {
+            ok(false, "Signature should be deleted");
+          })
+          .fail(function (error) {
+            ok(error instanceof jIO.util.jIOError);
+//            equal(error.message, "Cannot find document: " + id);
+            equal(error.status_code, 404);
+          });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local deletion and remote modifications", function () {
+    stop();
+    expect(2);
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.remove(id),
+          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo99"})
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local deletion and remote modifications: keep local", function () {
+    stop();
+    expect(9);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 1,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.remove(id),
+          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo99"})
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(
+          error.message.indexOf(
+            "Cannot find attachment: " +
+              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+              "jio_document/"
+          ),
+          0
+        );
+        equal(error.status_code, 404);
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local deletion and remote modifications: keep remote", function () {
+    stop();
+    expect(3);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 2,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.remove(id),
+          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo99"})
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local deletion and remote modifications: ignore", function () {
+    stop();
+    expect(5);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 3,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.remove(id),
+          context.jio.__storage._remote_sub_storage.put(id, {"title": "foo99"})
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modifications and remote deletion", function () {
+    stop();
+    expect(2);
+
+    var id,
+      context = this;
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo99"}),
+          context.jio.__storage._remote_sub_storage.remove(id)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          title: "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modifications and remote deletion: use remote post", function () {
+    stop();
+    expect(13);
+
+    var id,
+      context = this,
+      post_id;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      use_remote_post: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.__storage._remote_sub_storage.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo99"}),
+          context.jio.__storage._remote_sub_storage.remove(id)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      // Old id deleted
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(
+          error.message.indexOf(
+            "Cannot find attachment: " +
+              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+              "jio_document/"
+          ),
+          0
+        );
+        equal(error.status_code, 404);
+      })
+      // Check new id
+      .then(function () {
+        return context.jio.allDocs({include_docs: true});
+      })
+      .then(function (result) {
+        equal(result.data.total_rows, 1);
+        post_id = result.data.rows[0].id;
+        return context.jio.__storage._remote_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          "title": "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._local_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          "title": "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+
+  test("local modif, remote del: remote post, no check loc mod", function () {
+    stop();
+    expect(13);
+
+    var id,
+      context = this,
+      post_id;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      use_remote_post: true,
+      check_local_modification: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.__storage._remote_sub_storage.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo99"}),
+          context.jio.__storage._remote_sub_storage.remove(id)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      // Old id deleted
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(
+          error.message.indexOf(
+            "Cannot find attachment: " +
+              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+              "jio_document/"
+          ),
+          0
+        );
+        equal(error.status_code, 404);
+      })
+      // Check new id
+      .then(function () {
+        return context.jio.allDocs({include_docs: true});
+      })
+      .then(function (result) {
+        equal(result.data.total_rows, 1);
+        post_id = result.data.rows[0].id;
+        return context.jio.__storage._remote_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          "title": "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._local_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          "title": "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modifications and remote deletion: keep local", function () {
+    stop();
+    expect(3);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 1,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo99"}),
+          context.jio.__storage._remote_sub_storage.remove(id)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      // Old id deleted
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          "title": "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          "title": "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modif and remote del: keep local, use remote post", function () {
+    stop();
+    expect(13);
+
+    var id,
+      context = this,
+      post_id;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 1,
+      use_remote_post: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.__storage._remote_sub_storage.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo99"}),
+          context.jio.__storage._remote_sub_storage.remove(id)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      // Old id deleted
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(
+          error.message.indexOf(
+            "Cannot find attachment: " +
+              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+              "jio_document/"
+          ),
+          0
+        );
+        equal(error.status_code, 404);
+      })
+      // Check new id
+      .then(function () {
+        return context.jio.allDocs({include_docs: true});
+      })
+      .then(function (result) {
+        equal(result.data.total_rows, 1);
+        post_id = result.data.rows[0].id;
+        return context.jio.__storage._remote_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          "title": "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._local_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          "title": "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(post_id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "8ed3a474128b6e0c0c7d3dd51b1a06ebfbf6722f"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modifications and remote deletion: keep remote", function () {
+    stop();
+    expect(9);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 2,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo99"}),
+          context.jio.__storage._remote_sub_storage.remove(id)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      // id deleted
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(
+          error.message.indexOf(
+            "Cannot find attachment: " +
+              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+              "jio_document/"
+          ),
+          0
+        );
+        equal(error.status_code, 404);
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modif and remote del: keep remote, not check modif", function () {
+    stop();
+    expect(9);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 2,
+      check_local_modification: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo99"}),
+          context.jio.__storage._remote_sub_storage.remove(id)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      // id deleted
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(
+          error.message.indexOf(
+            "Cannot find attachment: " +
+              "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+              "jio_document/"
+          ),
+          0
+        );
+        equal(error.status_code, 404);
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modifications and remote deletion: ignore", function () {
+    stop();
+    expect(5);
+
+    var id,
+      context = this;
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 3,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.put(id, {"title": "foo99"}),
+          context.jio.__storage._remote_sub_storage.remove(id)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      // id deleted
+      .then(function () {
+        return context.jio.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          "title": "foo99"
+        });
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " + id);
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "5ea9013447539ad65de308cbd75b5826a2ae30e5"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("signature document is not synced", function () {
+    stop();
+    expect(6);
+
+    var context = this;
+
+    // Uses sessionstorage substorage, so that signature are stored
+    // in the same local sub storage
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "document",
+          document_id: "/",
+          sub_storage: {
+            type: "local",
+            sessiononly: true
+          }
+        }
+      },
+      remote_sub_storage: {
+        type: "memory"
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(
+          context.jio.__storage._signature_hash
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " +
+                "_replicate_8662994dcefb3a2ceec61e86953efda8ec6520d6");
+        equal(error.status_code, 404);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.get(
+          context.jio.__storage._signature_hash
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Cannot find document: " +
+                "_replicate_8662994dcefb3a2ceec61e86953efda8ec6520d6");
+        equal(error.status_code, 404);
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("substorages are repaired too", function () {
+    stop();
+    expect(8);
+
+    var context = this,
+      first_call = true,
+      options = {foo: "bar"};
+
+    function Storage200CheckRepair() {
+      return this;
+    }
+    Storage200CheckRepair.prototype.get = function () {
+      ok(true, "get 200 check repair called");
+      return {};
+    };
+    Storage200CheckRepair.prototype.hasCapacity = function () {
+      return true;
+    };
+    Storage200CheckRepair.prototype.buildQuery = function () {
+      ok(true, "buildQuery 200 check repair called");
+      return [];
+    };
+    Storage200CheckRepair.prototype.allAttachments = function () {
+      ok(true, "allAttachments 200 check repair called");
+      return {};
+    };
+    Storage200CheckRepair.prototype.repair = function (kw) {
+      if (first_call) {
+        deepEqual(
+          this,
+          context.jio.__storage._local_sub_storage.__storage,
+          "local substorage repair"
+        );
+        first_call = false;
+      } else {
+        deepEqual(
+          this,
+          context.jio.__storage._remote_sub_storage.__storage,
+          "remote substorage repair"
+        );
+      }
+      deepEqual(kw, options, "substorage repair parameters provided");
+    };
+
+    jIO.addStorage(
+      'replicatestorage200chechrepair',
+      Storage200CheckRepair
+    );
+
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      local_sub_storage: {
+        type: "replicatestorage200chechrepair"
+      },
+      remote_sub_storage: {
+        type: "replicatestorage200chechrepair"
+      }
+    });
+
+    context.jio.repair(options)
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("sync all documents by default", function () {
+    stop();
+    expect(4);
+
+    var context = this;
+
+    function Storage200DefaultQuery() {
+      return this;
+    }
+    Storage200DefaultQuery.prototype.get = function () {
+      ok(true, "get 200 check repair called");
+      return {};
+    };
+    Storage200DefaultQuery.prototype.hasCapacity = function () {
+      return true;
+    };
+    Storage200DefaultQuery.prototype.buildQuery = function (query) {
+      deepEqual(query, {});
+      return [];
+    };
+    Storage200DefaultQuery.prototype.allAttachments = function () {
+      ok(true, "allAttachments 200 check repair called");
+      return {};
+    };
+    jIO.addStorage(
+      'replicatestorage200defaultquery',
+      Storage200DefaultQuery
+    );
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      local_sub_storage: {
+        type: "replicatestorage200defaultquery"
+      },
+      remote_sub_storage: {
+        type: "replicatestorage200defaultquery"
+      }
+    });
+
+    return context.jio.repair()
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("sync can be restricted to some documents", function () {
+    stop();
+    expect(4);
+
+    var context = this,
+      query = {query: 'portal_type: "Foo"', limit: [0, 1234567890]};
+
+    function Storage200CustomQuery() {
+      return this;
+    }
+    Storage200CustomQuery.prototype.get = function () {
+      ok(true, "get 200 check repair called");
+      return {};
+    };
+    Storage200CustomQuery.prototype.hasCapacity = function () {
+      return true;
+    };
+    Storage200CustomQuery.prototype.buildQuery = function (options) {
+      deepEqual(options, query);
+      return [];
+    };
+    Storage200CustomQuery.prototype.allAttachments = function () {
+      ok(true, "allAttachments 200 check repair called");
+      return {};
+    };
+    jIO.addStorage(
+      'replicatestorage200customquery',
+      Storage200CustomQuery
+    );
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      local_sub_storage: {
+        type: "replicatestorage200customquery"
+      },
+      remote_sub_storage: {
+        type: "replicatestorage200customquery"
+      },
+      query: {query: 'portal_type: "Foo"', limit: [0, 1234567890]}
+    });
+
+    return context.jio.repair()
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("use 1 parallel operation", function () {
+    stop();
+    expect(16);
+
+    var context = this,
+      order_number = 0,
+      expected_order_list = [
+        'start get 0',
+        'stop get 0',
+        'start put 0',
+        'stop put 0',
+        'start get 1',
+        'stop get 1',
+        'start put 1',
+        'stop put 1',
+        'start get 2',
+        'stop get 2',
+        'start put 2',
+        'stop put 2',
+        'start get 3',
+        'stop get 3',
+        'start put 3',
+        'stop put 3'
+      ];
+
+    function assertExecutionOrder(text) {
+      equal(text, expected_order_list[order_number],
+            expected_order_list[order_number]);
+      order_number += 1;
+    }
+
+    function StorageOneParallelOperation() {
+      this._sub_storage = jIO.createJIO({type: "memory"});
+      return this;
+    }
+
+    StorageOneParallelOperation.prototype.put = function (id, doc) {
+      assertExecutionOrder('start put ' + id);
+      var storage = this;
+      return storage._sub_storage.put(id, doc)
+        .push(function (result) {
+          assertExecutionOrder('stop put ' + id);
+          return result;
+        });
+    };
+
+    StorageOneParallelOperation.prototype.get = function (id) {
+      assertExecutionOrder('start get ' + id);
+      var storage = this;
+      return storage._sub_storage.get(id)
+        .push(undefined, function (error) {
+          assertExecutionOrder('stop get ' + id);
+          throw error;
+        });
+    };
+    StorageOneParallelOperation.prototype.buildQuery = function () {
+      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
+    };
+
+    StorageOneParallelOperation.prototype.hasCapacity = function () {
+      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
+    };
+
+    jIO.addStorage(
+      'one_parallel',
+      StorageOneParallelOperation
+    );
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      local_sub_storage: {
+        type: "memory"
+      },
+      remote_sub_storage: {
+        type: "one_parallel"
+      }
+    });
+
+    return RSVP.all([
+      context.jio.put("0", {"title": "foo"}),
+      context.jio.put("1", {"title": "foo1"}),
+      context.jio.put("2", {"title": "foo2"}),
+      context.jio.put("3", {"title": "foo3"})
+    ])
+      .then(function () {
+        return context.jio.repair();
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("use 2 parallel operations", function () {
+    stop();
+    expect(16);
+
+    var context = this,
+      order_number = 0,
+      expected_order_list = [
+        'start get 0',
+
+        'start get 1',
+        'stop get 1',
+        'start put 1',
+        'stop put 1',
+        'start get 2',
+        'stop get 2',
+        'start put 2',
+
+        'stop get 0',
+        'start put 0',
+        'stop put 0',
+        'start get 3',
+        'stop get 3',
+        'start put 3',
+        'stop put 3',
+
+        'stop put 2'
+      ],
+      defer0,
+      defer2;
+
+    function assertExecutionOrder(text) {
+      equal(text, expected_order_list[order_number],
+            expected_order_list[order_number]);
+      order_number += 1;
+    }
+
+    function StorageTwoParallelOperation() {
+      this._sub_storage = jIO.createJIO({type: "memory"});
+      return this;
+    }
+
+    StorageTwoParallelOperation.prototype.put = function (id, doc) {
+      var storage = this;
+      assertExecutionOrder('start put ' + id);
+      return new RSVP.Queue()
+        .push(function () {
+          if (id === "2") {
+            defer0.resolve();
+            defer2 = RSVP.defer();
+            return defer2.promise;
+          }
+        })
+        .push(function () {
+          return storage._sub_storage.put(id, doc);
+        })
+        .push(function (result) {
+          if (id === "3") {
+            defer2.resolve();
+          }
+          assertExecutionOrder('stop put ' + id);
+          return result;
+        });
+    };
+
+    StorageTwoParallelOperation.prototype.get = function (id) {
+      var storage = this;
+      assertExecutionOrder('start get ' + id);
+      return new RSVP.Queue()
+        .push(function () {
+          if (id === "0") {
+            defer0 = RSVP.defer();
+            return defer0.promise;
+          }
+        })
+        .push(function () {
+          return storage._sub_storage.get(id);
+        })
+        .push(undefined, function (error) {
+          assertExecutionOrder('stop get ' + id);
+          throw error;
+        });
+    };
+    StorageTwoParallelOperation.prototype.buildQuery = function () {
+      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
+    };
+
+    StorageTwoParallelOperation.prototype.hasCapacity = function () {
+      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
+    };
+
+    jIO.addStorage(
+      'two_parallel',
+      StorageTwoParallelOperation
+    );
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      parallel_operation_amount: 2,
+      local_sub_storage: {
+        type: "memory"
+      },
+      remote_sub_storage: {
+        type: "two_parallel"
+      }
+    });
+
+    return RSVP.all([
+      context.jio.put("0", {"title": "foo"}),
+      context.jio.put("1", {"title": "foo1"}),
+      context.jio.put("2", {"title": "foo2"}),
+      context.jio.put("3", {"title": "foo3"})
+    ])
+      .then(function () {
+        return context.jio.repair();
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+
+  test("use 4 parallel operations", function () {
+    stop();
+    expect(16);
+
+    var context = this,
+      order_number = 0,
+      expected_order_list = [
+        'start get 0',
+        'start get 1',
+        'start get 2',
+        'start get 3',
+        'stop get 0',
+        'stop get 1',
+        'stop get 2',
+        'stop get 3',
+        'start put 0',
+        'start put 1',
+        'start put 2',
+        'start put 3',
+        'stop put 0',
+        'stop put 1',
+        'stop put 2',
+        'stop put 3'
+      ];
+
+    function assertExecutionOrder(text) {
+      equal(text, expected_order_list[order_number],
+            expected_order_list[order_number]);
+      order_number += 1;
+    }
+
+    function StorageFourParallelOperation() {
+      this._sub_storage = jIO.createJIO({type: "memory"});
+      return this;
+    }
+
+    StorageFourParallelOperation.prototype.put = function (id, doc) {
+      assertExecutionOrder('start put ' + id);
+      var storage = this;
+      return storage._sub_storage.put(id, doc)
+        .push(function (result) {
+          assertExecutionOrder('stop put ' + id);
+          return result;
+        });
+    };
+
+    StorageFourParallelOperation.prototype.get = function (id) {
+      assertExecutionOrder('start get ' + id);
+      var storage = this;
+      return storage._sub_storage.get(id)
+        .push(undefined, function (error) {
+          assertExecutionOrder('stop get ' + id);
+          throw error;
+        });
+    };
+    StorageFourParallelOperation.prototype.buildQuery = function () {
+      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
+    };
+
+    StorageFourParallelOperation.prototype.hasCapacity = function () {
+      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
+    };
+
+    jIO.addStorage(
+      'four_parallel',
+      StorageFourParallelOperation
+    );
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      parallel_operation_amount: 4,
+      local_sub_storage: {
+        type: "memory"
+      },
+      remote_sub_storage: {
+        type: "four_parallel"
+      }
+    });
+
+    return RSVP.all([
+      context.jio.put("0", {"title": "foo"}),
+      context.jio.put("1", {"title": "foo1"}),
+      context.jio.put("2", {"title": "foo2"}),
+      context.jio.put("3", {"title": "foo3"})
+    ])
+      .then(function () {
+        return context.jio.repair();
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+
+}(jIO, QUnit, Blob, RSVP));
\ No newline at end of file
diff --git a/test/jio.storage/replicatestorage_repairattachment.tests.js b/test/jio.storage/replicatestorage_repairattachment.tests.js
new file mode 100644
index 0000000000000000000000000000000000000000..589618b390121340ecd0ec4f72bf06c9d195f325
--- /dev/null
+++ b/test/jio.storage/replicatestorage_repairattachment.tests.js
@@ -0,0 +1,3653 @@
+/*jslint nomen: true*/
+/*global Blob, RSVP*/
+(function (jIO, QUnit, Blob, RSVP) {
+  "use strict";
+  var test = QUnit.test,
+    stop = QUnit.stop,
+    start = QUnit.start,
+    ok = QUnit.ok,
+    expect = QUnit.expect,
+    deepEqual = QUnit.deepEqual,
+    equal = QUnit.equal,
+    module = QUnit.module,
+    big_string = "",
+    j;
+
+  for (j = 0; j < 30; j += 1) {
+    big_string += "a";
+  }
+
+  function StorageEmptyAllAttachments(spec) {
+    this._sub_storage = jIO.createJIO(spec.sub_storage);
+    return this;
+  }
+  jIO.addStorage('signaturestorageallattachments', StorageEmptyAllAttachments);
+  StorageEmptyAllAttachments.prototype.allAttachments = function () {
+    return this._sub_storage.allAttachments.apply(this._sub_storage,
+                                                  arguments);
+  };
+  StorageEmptyAllAttachments.prototype.getAttachment = function () {
+    return this._sub_storage.getAttachment.apply(this._sub_storage,
+                                                 arguments);
+  };
+  StorageEmptyAllAttachments.prototype.putAttachment = function () {
+    return this._sub_storage.putAttachment.apply(this._sub_storage,
+                                                 arguments);
+  };
+  StorageEmptyAllAttachments.prototype.buildQuery = function () {
+    return this._sub_storage.buildQuery.apply(this._sub_storage,
+                                              arguments);
+  };
+  StorageEmptyAllAttachments.prototype.put = function () {
+    return this._sub_storage.put.apply(this._sub_storage,
+                                       arguments);
+  };
+  StorageEmptyAllAttachments.prototype.get = function () {
+    return this._sub_storage.get.apply(this._sub_storage,
+                                       arguments);
+  };
+  StorageEmptyAllAttachments.prototype.hasCapacity = function (name) {
+    return (name !== 'bulk_get');
+  };
+
+  /////////////////////////////////////////////////////////////////
+  // attachment replication
+  /////////////////////////////////////////////////////////////////
+  module("replicateStorage.repair.attachment", {
+    setup: function () {
+      // Uses memory substorage, so that it is flushed after each run
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        check_local_attachment_creation: true,
+        check_local_attachment_modification: true,
+        check_local_attachment_deletion: true,
+        check_remote_attachment_creation: true,
+        check_remote_attachment_modification: true,
+        check_remote_attachment_deletion: true,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        }
+      });
+
+    }
+  });
+
+  test("local attachment creation", function () {
+    stop();
+    expect(2);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local attachment creation, local document creation not checked",
+       function () {
+      stop();
+      expect(6);
+
+      var id,
+        context = this,
+        blob = new Blob([big_string]);
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        check_local_creation: false,
+        check_local_attachment_creation: true,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        }
+      });
+
+      context.jio.post({"title": "foo"})
+        .then(function (result) {
+          id = result;
+          return context.jio.putAttachment(id, "foo", blob);
+        })
+        .then(function () {
+          return context.jio.repair();
+        })
+        .then(function () {
+          return context.jio.__storage._remote_sub_storage.getAttachment(
+            id,
+            "foo",
+            {format: "text"}
+          );
+        })
+        .fail(function (error) {
+          ok(error instanceof jIO.util.jIOError);
+          equal(error.status_code, 404);
+          equal(error.message, "Cannot find attachment: " + id + " , foo");
+          return context.jio.__storage._signature_sub_storage
+                        .getAttachment(id, "foo", {format: "json"});
+        })
+        .fail(function (error) {
+          ok(error instanceof jIO.util.jIOError);
+          equal(error.status_code, 404);
+          var error_message = "Cannot find attachment: " +
+            "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+            "jio_attachment/";
+          equal(
+            error.message.substring(0, error_message.length),
+            error_message
+          );
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local attachment creation not checked", function () {
+    stop();
+    expect(6);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_local_attachment_creation: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        var error_message = "Cannot find attachment: " +
+          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+          "jio_attachment/";
+        equal(
+          error.message.substring(0, error_message.length),
+          error_message
+        );
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local attachment creation, local document creation and use remote post",
+       function () {
+      stop();
+      expect(4);
+
+      var id,
+        context = this,
+        post_id,
+        blob = new Blob([big_string]);
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        use_remote_post: true,
+        check_local_attachment_creation: true,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        }
+      });
+
+      context.jio.post({"title": "foo"})
+        .then(function (result) {
+          id = result;
+          return context.jio.putAttachment(id, "foo", blob);
+        })
+        .then(function () {
+          return context.jio.repair();
+        })
+        // Another document should have been created
+        .then(function () {
+          return context.jio.__storage._remote_sub_storage.allDocs();
+        })
+        .then(function (result) {
+          equal(result.data.total_rows, 1);
+          post_id = result.data.rows[0].id;
+          return context.jio.getAttachment(
+            post_id,
+            "foo",
+            {format: "text"}
+          );
+        })
+        .then(function (result) {
+          equal(result, big_string);
+          return context.jio.__storage._remote_sub_storage.getAttachment(
+            post_id,
+            "foo",
+            {format: "text"}
+          );
+        })
+        .then(function (result) {
+          equal(result, big_string);
+          return context.jio.__storage._signature_sub_storage
+                        .getAttachment(post_id, "foo", {format: "json"});
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("remote attachment creation", function () {
+    stop();
+    expect(2);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    context.jio.__storage._remote_sub_storage.post({"title": "bar"})
+      .then(function (result) {
+        id = result;
+        return context.jio.__storage._remote_sub_storage
+                      .putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote attachment creation, remote document creation not checked",
+       function () {
+      stop();
+      expect(6);
+
+      var id,
+        context = this,
+        blob = new Blob([big_string]);
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        check_remote_creation: false,
+        check_local_attachment_creation: true,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        }
+      });
+
+      context.jio.__storage._remote_sub_storage.post({"title": "foo"})
+        .then(function (result) {
+          id = result;
+          return context.jio.__storage._remote_sub_storage
+                        .putAttachment(id, "foo", blob);
+        })
+        .then(function () {
+          return context.jio.repair();
+        })
+        .then(function () {
+          return context.jio.getAttachment(
+            id,
+            "foo",
+            {format: "text"}
+          );
+        })
+        .fail(function (error) {
+          ok(error instanceof jIO.util.jIOError);
+          equal(error.status_code, 404);
+          equal(error.message, "Cannot find attachment: " + id + " , foo");
+          return context.jio.__storage._signature_sub_storage
+                        .getAttachment(id, "foo", {format: "json"});
+        })
+        .fail(function (error) {
+          ok(error instanceof jIO.util.jIOError);
+          equal(error.status_code, 404);
+          var error_message = "Cannot find attachment: " +
+            "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+            "jio_attachment/";
+          equal(
+            error.message.substring(0, error_message.length),
+            error_message
+          );
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+
+  test("remote attachment creation not checked", function () {
+    stop();
+    expect(6);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_remote_attachment_creation: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.__storage._remote_sub_storage.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.__storage._remote_sub_storage
+                      .putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        var error_message = "Cannot find attachment: " +
+          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+          "jio_attachment/";
+        equal(
+          error.message.substring(0, error_message.length),
+          error_message
+        );
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote attachment creations", function () {
+    stop();
+    expect(5);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]);
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "conflict", blob),
+          context.jio.__storage._remote_sub_storage.putAttachment(id,
+                                                                  "conflict",
+                                                                  blob2)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        ok(false);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Conflict on 'foobar' with attachment 'conflict'");
+        equal(error.status_code, 409);
+      })
+      .then(function () {
+        return context.jio.__storage._signature_sub_storage.getAttachment(
+          id,
+          "conflict"
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+//        equal(error.message, "Cannot find document: conflict");
+        equal(error.status_code, 404);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote attachment creations: keep local", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 1,
+      check_local_attachment_creation: true,
+      check_remote_attachment_creation: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "conflict", blob),
+          context.jio.__storage._remote_sub_storage.putAttachment(id,
+                                                                  "conflict",
+                                                                  blob2)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote attachment creations: keep local, " +
+       "local not matching allAttachments", function () {
+      stop();
+      expect(3);
+
+      var context = this,
+        id = 'foobar',
+        blob = new Blob([big_string]),
+        blob2 = new Blob([big_string + "a"]);
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        conflict_handling: 1,
+        check_local_attachment_creation: true,
+        check_remote_attachment_creation: true,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "signaturestorageallattachments",
+            sub_storage: {
+              type: "memory"
+            }
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        }
+      });
+
+      context.jio.put(id, {"title": "foo"})
+        .push(function () {
+          return context.jio.repair();
+        })
+        .push(function () {
+          return RSVP.all([
+            context.jio.putAttachment(id, "conflict", blob),
+            context.jio.__storage._remote_sub_storage.putAttachment(id,
+                                                                    "conflict",
+                                                                    blob2)
+          ]);
+        })
+        .then(function () {
+          return context.jio.repair();
+        })
+         .then(function () {
+          return context.jio.getAttachment(
+            id,
+            "conflict",
+            {format: "text"}
+          );
+        })
+        .then(function (result) {
+          equal(result, big_string);
+          return context.jio.__storage._remote_sub_storage.getAttachment(
+            id,
+            "conflict",
+            {format: "text"}
+          );
+        })
+        .then(function (result) {
+          equal(result, big_string);
+          return context.jio.__storage._signature_sub_storage
+                        .getAttachment(id, "conflict", {format: "json"});
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local and remote attachment creations: keep local, " +
+       "remote not matching allAttachments", function () {
+      stop();
+      expect(3);
+
+      var context = this,
+        id = 'foobar',
+        blob = new Blob([big_string]),
+        blob2 = new Blob([big_string + "a"]);
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        conflict_handling: 1,
+        check_local_attachment_creation: true,
+        check_remote_attachment_creation: true,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "signaturestorageallattachments",
+            sub_storage: {
+              type: "memory"
+            }
+          }
+        }
+      });
+
+      context.jio.put(id, {"title": "foo"})
+        .push(function () {
+          return context.jio.repair();
+        })
+        .push(function () {
+          return RSVP.all([
+            context.jio.putAttachment(id, "conflict", blob),
+            context.jio.__storage._remote_sub_storage.putAttachment(id,
+                                                                    "conflict",
+                                                                    blob2)
+          ]);
+        })
+        .then(function () {
+          return context.jio.repair();
+        })
+         .then(function () {
+          return context.jio.getAttachment(
+            id,
+            "conflict",
+            {format: "text"}
+          );
+        })
+        .then(function (result) {
+          equal(result, big_string);
+          return context.jio.__storage._remote_sub_storage.getAttachment(
+            id,
+            "conflict",
+            {format: "text"}
+          );
+        })
+        .then(function (result) {
+          equal(result, big_string);
+          return context.jio.__storage._signature_sub_storage
+                        .getAttachment(id, "conflict", {format: "json"});
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local and remote attachment creations: keep remote", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 2,
+      check_local_attachment_creation: true,
+      check_remote_attachment_creation: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "conflict", blob),
+          context.jio.__storage._remote_sub_storage.putAttachment(id,
+                                                                  "conflict",
+                                                                  blob2)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote attachment creations: keep remote, " +
+       "local not matching allAttachments", function () {
+      stop();
+      expect(3);
+
+      var context = this,
+        id = 'foobar',
+        blob = new Blob([big_string]),
+        blob2 = new Blob([big_string + "a"]);
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        conflict_handling: 2,
+        check_local_attachment_creation: true,
+        check_remote_attachment_creation: true,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "signaturestorageallattachments",
+            sub_storage: {
+              type: "memory"
+            }
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        }
+      });
+
+      context.jio.put(id, {"title": "foo"})
+        .push(function () {
+          return context.jio.repair();
+        })
+        .push(function () {
+          return RSVP.all([
+            context.jio.putAttachment(id, "conflict", blob),
+            context.jio.__storage._remote_sub_storage.putAttachment(id,
+                                                                    "conflict",
+                                                                    blob2)
+          ]);
+        })
+        .then(function () {
+          return context.jio.repair();
+        })
+         .then(function () {
+          return context.jio.getAttachment(
+            id,
+            "conflict",
+            {format: "text"}
+          );
+        })
+        .then(function (result) {
+          equal(result, big_string + "a");
+          return context.jio.__storage._remote_sub_storage.getAttachment(
+            id,
+            "conflict",
+            {format: "text"}
+          );
+        })
+        .then(function (result) {
+          equal(result, big_string + "a");
+          return context.jio.__storage._signature_sub_storage
+                        .getAttachment(id, "conflict", {format: "json"});
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local and remote attachment creations: keep remote, " +
+       "remote not matching allAttachments", function () {
+      stop();
+      expect(3);
+
+      var context = this,
+        id = 'foobar',
+        blob = new Blob([big_string]),
+        blob2 = new Blob([big_string + "a"]);
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        conflict_handling: 2,
+        check_local_attachment_creation: true,
+        check_remote_attachment_creation: true,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "signaturestorageallattachments",
+            sub_storage: {
+              type: "memory"
+            }
+          }
+        }
+      });
+
+      context.jio.put(id, {"title": "foo"})
+        .push(function () {
+          return context.jio.repair();
+        })
+        .push(function () {
+          return RSVP.all([
+            context.jio.putAttachment(id, "conflict", blob),
+            context.jio.__storage._remote_sub_storage.putAttachment(id,
+                                                                    "conflict",
+                                                                    blob2)
+          ]);
+        })
+        .then(function () {
+          return context.jio.repair();
+        })
+         .then(function () {
+          return context.jio.getAttachment(
+            id,
+            "conflict",
+            {format: "text"}
+          );
+        })
+        .then(function (result) {
+          equal(result, big_string + "a");
+          return context.jio.__storage._remote_sub_storage.getAttachment(
+            id,
+            "conflict",
+            {format: "text"}
+          );
+        })
+        .then(function (result) {
+          equal(result, big_string + "a");
+          return context.jio.__storage._signature_sub_storage
+                        .getAttachment(id, "conflict", {format: "json"});
+        })
+        .then(function (result) {
+          deepEqual(result, {
+            hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
+          });
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local and remote attachment creations: continue", function () {
+    stop();
+    expect(4);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 3,
+      check_local_attachment_creation: true,
+      check_remote_attachment_creation: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "conflict", blob),
+          context.jio.__storage._remote_sub_storage.putAttachment(id,
+                                                                  "conflict",
+                                                                  blob2)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+//        equal(error.message, "Cannot find document: conflict");
+        equal(error.status_code, 404);
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote same attachment creations", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string]);
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "conflict", blob),
+          context.jio.__storage._remote_sub_storage.putAttachment(id,
+                                                                  "conflict",
+                                                                  blob2)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("no attachment modification", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]);
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local attachment modification", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]);
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob);
+      })
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob2);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local attachment modification not checked", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_local_attachment_creation: true,
+      check_local_attachment_modification: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob);
+      })
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob2);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote attachment modification", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]);
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob);
+      })
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.__storage._remote_sub_storage
+                          .putAttachment(id, "conflict", blob2);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote attachment modification not checked", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_local_attachment_creation: true,
+      check_remote_attachment_modification: false,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob);
+      })
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.__storage._remote_sub_storage
+                      .putAttachment(id, "conflict", blob2);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote attachment modifications", function () {
+    stop();
+    expect(6);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]),
+      blob3 = new Blob([big_string + "b"]);
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob);
+      })
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "conflict", blob2),
+          context.jio.__storage._remote_sub_storage
+                     .putAttachment(id, "conflict", blob3)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        ok(false);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.message, "Conflict on 'foobar' " +
+                             "with attachment 'conflict'");
+        equal(error.status_code, 409);
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "b");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote attachment modifications: keep local", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]),
+      blob3 = new Blob([big_string + "b"]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 1,
+      check_local_attachment_creation: true,
+      check_remote_attachment_creation: true,
+      check_local_attachment_modification: true,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob);
+      })
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "conflict", blob2),
+          context.jio.__storage._remote_sub_storage
+                     .putAttachment(id, "conflict", blob3)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote attachment modifications: keep remote", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]),
+      blob3 = new Blob([big_string + "b"]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 2,
+      check_local_attachment_creation: true,
+      check_remote_attachment_creation: true,
+      check_local_attachment_modification: true,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob);
+      })
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "conflict", blob2),
+          context.jio.__storage._remote_sub_storage
+                     .putAttachment(id, "conflict", blob3)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "b");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "b");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "9a73ce4f16b7fa5d2b4d8f723a754fef048fb9f8"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote attachment modifications: continue", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]),
+      blob3 = new Blob([big_string + "b"]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 3,
+      check_local_attachment_creation: true,
+      check_remote_attachment_creation: true,
+      check_local_attachment_modification: true,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob);
+      })
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "conflict", blob2),
+          context.jio.__storage._remote_sub_storage
+                     .putAttachment(id, "conflict", blob3)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "b");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote attachment same modifications", function () {
+    stop();
+    expect(3);
+
+    var context = this,
+      id = 'foobar',
+      blob = new Blob([big_string]),
+      blob2 = new Blob([big_string + "a"]);
+
+    context.jio.put(id, {"title": "foo"})
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return context.jio.putAttachment(id, "conflict", blob);
+      })
+      .push(function () {
+        return context.jio.repair();
+      })
+      .push(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "conflict", blob2),
+          context.jio.__storage._remote_sub_storage
+                     .putAttachment(id, "conflict", blob2)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "conflict",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string + "a");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "conflict", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local attachment deletion", function () {
+    stop();
+    expect(9);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.removeAttachment(id, "foo");
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        var error_message = "Cannot find attachment: " +
+          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+          "jio_attachment/";
+        equal(
+          error.message.substring(0, error_message.length),
+          error_message
+        );
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local attachment deletion not checked", function () {
+
+    stop();
+    expect(5);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_local_attachment_creation: true,
+      check_local_attachment_deletion: false,
+      check_local_attachment_modification: true,
+      check_remote_attachment_creation: true,
+      check_remote_attachment_deletion: true,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.removeAttachment(id, "foo");
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote attachment deletion", function () {
+    stop();
+    expect(9);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage
+                      .removeAttachment(id, "foo");
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        var error_message = "Cannot find attachment: " +
+          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+          "jio_attachment/";
+        equal(
+          error.message.substring(0, error_message.length),
+          error_message
+        );
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("remote attachment deletion not checked", function () {
+
+    stop();
+    expect(5);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_local_attachment_creation: true,
+      check_local_attachment_deletion: true,
+      check_local_attachment_modification: true,
+      check_remote_attachment_creation: true,
+      check_remote_attachment_deletion: false,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage
+                      .removeAttachment(id, "foo");
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(result, big_string);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local and remote attachment deletions", function () {
+    stop();
+    expect(9);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.removeAttachment(id, "foo"),
+          context.jio.__storage._remote_sub_storage
+                     .removeAttachment(id, "foo")
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        var error_message = "Cannot find attachment: " +
+          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+          "jio_attachment/";
+        equal(
+          error.message.substring(0, error_message.length),
+          error_message
+        );
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local deletion and remote modifications", function () {
+    stop();
+    expect(3);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string + "a"]),
+      blob2 = new Blob([big_string]);
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.removeAttachment(id, "foo"),
+          context.jio.__storage._remote_sub_storage
+                     .putAttachment(id, "foo", blob2)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(true, big_string === result);
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(true, big_string === result);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local deletion and remote modifications: keep local", function () {
+    stop();
+    expect(9);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string + "a"]),
+      blob2 = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 1,
+      check_local_attachment_creation: true,
+      check_local_attachment_deletion: true,
+      check_local_attachment_modification: true,
+      check_remote_attachment_creation: true,
+      check_remote_attachment_deletion: true,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.removeAttachment(id, "foo"),
+          context.jio.__storage._remote_sub_storage
+                     .putAttachment(id, "foo", blob2)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        var error_message = "Cannot find attachment: " +
+          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+          "jio_attachment/";
+        equal(
+          error.message.substring(0, error_message.length),
+          error_message
+        );
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local deletion and remote modifications: keep local, dont check local",
+       function () {
+      stop();
+      expect(9);
+
+      var id,
+        context = this,
+        blob = new Blob([big_string + "a"]),
+        blob2 = new Blob([big_string]);
+
+      this.jio = jIO.createJIO({
+        type: "replicate",
+        conflict_handling: 1,
+        check_local_attachment_creation: true,
+        check_local_attachment_deletion: false,
+        check_local_attachment_modification: true,
+        check_remote_attachment_creation: true,
+        check_remote_attachment_deletion: true,
+        check_remote_attachment_modification: true,
+        local_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        },
+        remote_sub_storage: {
+          type: "uuid",
+          sub_storage: {
+            type: "memory"
+          }
+        }
+      });
+
+      context.jio.post({"title": "foo"})
+        .then(function (result) {
+          id = result;
+          return context.jio.putAttachment(id, "foo", blob);
+        })
+        .then(function () {
+          return context.jio.repair();
+        })
+        .then(function () {
+          return RSVP.all([
+            context.jio.removeAttachment(id, "foo"),
+            context.jio.__storage._remote_sub_storage
+                       .putAttachment(id, "foo", blob2)
+          ]);
+        })
+        .then(function () {
+          return context.jio.repair();
+        })
+        .then(function () {
+          return context.jio.getAttachment(
+            id,
+            "foo",
+            {format: "text"}
+          );
+        })
+        .fail(function (error) {
+          ok(error instanceof jIO.util.jIOError);
+          equal(error.status_code, 404);
+          equal(error.message, "Cannot find attachment: " + id + " , foo");
+          return context.jio.__storage._remote_sub_storage.getAttachment(
+            id,
+            "foo",
+            {format: "text"}
+          );
+        })
+        .fail(function (error) {
+          ok(error instanceof jIO.util.jIOError);
+          equal(error.status_code, 404);
+          equal(error.message, "Cannot find attachment: " + id + " , foo");
+          return context.jio.__storage._signature_sub_storage
+                        .getAttachment(id, "foo", {format: "json"});
+        })
+        .fail(function (error) {
+          ok(error instanceof jIO.util.jIOError);
+          equal(error.status_code, 404);
+          var error_message = "Cannot find attachment: " +
+            "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+            "jio_attachment/";
+          equal(
+            error.message.substring(0, error_message.length),
+            error_message
+          );
+        })
+        .fail(function (error) {
+          ok(false, error);
+        })
+        .always(function () {
+          start();
+        });
+    });
+
+  test("local deletion and remote modifications: keep remote", function () {
+    stop();
+    expect(3);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string + "a"]),
+      blob2 = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 2,
+      check_local_attachment_creation: true,
+      check_local_attachment_deletion: true,
+      check_local_attachment_modification: true,
+      check_remote_attachment_creation: true,
+      check_remote_attachment_deletion: true,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.removeAttachment(id, "foo"),
+          context.jio.__storage._remote_sub_storage
+                     .putAttachment(id, "foo", blob2)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(true, big_string === result);
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(true, big_string === result);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local deletion and remote modifications: ignore", function () {
+    stop();
+    expect(5);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string + "a"]),
+      blob2 = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 3,
+      check_local_attachment_creation: true,
+      check_local_attachment_deletion: true,
+      check_local_attachment_modification: true,
+      check_remote_attachment_creation: true,
+      check_remote_attachment_deletion: true,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.removeAttachment(id, "foo"),
+          context.jio.__storage._remote_sub_storage
+                     .putAttachment(id, "foo", blob2)
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(true, big_string === result);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modifications and remote deletion", function () {
+    stop();
+    expect(3);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string + "a"]),
+      blob2 = new Blob([big_string]);
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "foo", blob2),
+          context.jio.__storage._remote_sub_storage
+                      .removeAttachment(id, "foo")
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(true, big_string === result);
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(true, big_string === result);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modifications and remote deletion: keep remote", function () {
+    stop();
+    expect(9);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string + "a"]),
+      blob2 = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 2,
+      check_local_attachment_creation: true,
+      check_local_attachment_deletion: true,
+      check_local_attachment_modification: true,
+      check_remote_attachment_creation: true,
+      check_remote_attachment_deletion: true,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "foo", blob2),
+          context.jio.__storage._remote_sub_storage.removeAttachment(id, "foo")
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        var error_message = "Cannot find attachment: " +
+          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+          "jio_attachment/";
+        equal(
+          error.message.substring(0, error_message.length),
+          error_message
+        );
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modifications and remote deletion: keep local", function () {
+    stop();
+    expect(3);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string + "a"]),
+      blob2 = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 1,
+      check_local_attachment_creation: true,
+      check_local_attachment_deletion: true,
+      check_local_attachment_modification: true,
+      check_remote_attachment_creation: true,
+      check_remote_attachment_deletion: true,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "foo", blob2),
+          context.jio.__storage._remote_sub_storage.removeAttachment(id, "foo")
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(true, big_string === result);
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(true, big_string === result);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "cd762363c1c11ecb48611583520bba111f0034d4"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modif and remote del: keep remote, not check modif", function () {
+    stop();
+    expect(9);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string + "a"]),
+      blob2 = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 2,
+      check_local_attachment_creation: true,
+      check_local_attachment_deletion: true,
+      check_local_attachment_modification: false,
+      check_remote_attachment_creation: true,
+      check_remote_attachment_deletion: true,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "foo", blob2),
+          context.jio.__storage._remote_sub_storage.removeAttachment(id, "foo")
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        var error_message = "Cannot find attachment: " +
+          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+          "jio_attachment/";
+        equal(
+          error.message.substring(0, error_message.length),
+          error_message
+        );
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("local modifications and remote deletion: ignore", function () {
+    stop();
+    expect(5);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string + "a"]),
+      blob2 = new Blob([big_string]);
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      conflict_handling: 3,
+      check_local_attachment_creation: true,
+      check_local_attachment_deletion: true,
+      check_local_attachment_modification: true,
+      check_remote_attachment_creation: true,
+      check_remote_attachment_deletion: true,
+      check_remote_attachment_modification: true,
+      local_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      },
+      remote_sub_storage: {
+        type: "uuid",
+        sub_storage: {
+          type: "memory"
+        }
+      }
+    });
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return RSVP.all([
+          context.jio.putAttachment(id, "foo", blob2),
+          context.jio.__storage._remote_sub_storage.removeAttachment(id, "foo")
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .then(function (result) {
+        equal(true, big_string === result);
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .then(function (result) {
+        deepEqual(result, {
+          hash: "65cf771ad2cc0b1e8f89361e3b7bec2365b3ad24"
+        });
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  /////////////////////////////////////////////////////////////////
+  // attachment replication performance
+  /////////////////////////////////////////////////////////////////
+  test("document and attachment deletion performance", function () {
+    stop();
+    expect(12);
+
+    var id,
+      context = this,
+      blob = new Blob([big_string]);
+
+    context.jio.post({"title": "foo"})
+      .then(function (result) {
+        id = result;
+        return context.jio.putAttachment(id, "foo", blob);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.remove(id);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .then(function () {
+        return context.jio.__storage._remote_sub_storage.getAttachment(
+          id,
+          "foo",
+          {format: "text"}
+        );
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find attachment: " + id + " , foo");
+        return context.jio.__storage._remote_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        equal(error.message, "Cannot find document: " + id);
+        return context.jio.__storage._signature_sub_storage
+                      .getAttachment(id, "foo", {format: "json"});
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        var error_message = "Cannot find attachment: " +
+          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+          "jio_attachment/";
+        equal(
+          error.message.substring(0, error_message.length),
+          error_message
+        );
+        return context.jio.__storage._signature_sub_storage.get(id);
+      })
+      .fail(function (error) {
+        ok(error instanceof jIO.util.jIOError);
+        equal(error.status_code, 404);
+        var error_message = "Cannot find attachment: " +
+          "_replicate_b9296354cdf1dbe0046de11f57a5a24f8f6a78a8 , " +
+          "jio_document/";
+        equal(
+          error.message.substring(0, error_message.length),
+          error_message
+        );
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("use 1 parallel operation", function () {
+    stop();
+    expect(40);
+
+    var context = this,
+      order_number = 0,
+      expected_order_list = [
+        'start get 0',
+        'stop get 0',
+        'start put 0',
+        'stop put 0',
+        'start get 1',
+        'stop get 1',
+        'start put 1',
+        'stop put 1',
+        'start getAttachment 00',
+        'stop getAttachment 00',
+        'start putAttachment 00',
+        'stop putAttachment 00',
+        'start getAttachment 01',
+        'stop getAttachment 01',
+        'start putAttachment 01',
+        'stop putAttachment 01',
+        'start getAttachment 02',
+        'stop getAttachment 02',
+        'start putAttachment 02',
+        'stop putAttachment 02',
+        'start getAttachment 03',
+        'stop getAttachment 03',
+        'start putAttachment 03',
+        'stop putAttachment 03',
+        'start getAttachment 10',
+        'stop getAttachment 10',
+        'start putAttachment 10',
+        'stop putAttachment 10',
+        'start getAttachment 11',
+        'stop getAttachment 11',
+        'start putAttachment 11',
+        'stop putAttachment 11',
+        'start getAttachment 12',
+        'stop getAttachment 12',
+        'start putAttachment 12',
+        'stop putAttachment 12',
+        'start getAttachment 13',
+        'stop getAttachment 13',
+        'start putAttachment 13',
+        'stop putAttachment 13'
+      ];
+
+    function assertExecutionOrder(text) {
+      equal(text, expected_order_list[order_number],
+            expected_order_list[order_number]);
+      order_number += 1;
+    }
+
+    function StorageOneParallelOperation() {
+      this._sub_storage = jIO.createJIO({type: "memory"});
+      return this;
+    }
+
+    StorageOneParallelOperation.prototype.put = function (id, doc) {
+      assertExecutionOrder('start put ' + id);
+      var storage = this;
+      return storage._sub_storage.put(id, doc)
+        .push(function (result) {
+          assertExecutionOrder('stop put ' + id);
+          return result;
+        });
+    };
+
+    StorageOneParallelOperation.prototype.get = function (id) {
+      assertExecutionOrder('start get ' + id);
+      var storage = this;
+      return storage._sub_storage.get(id)
+        .push(undefined, function (error) {
+          assertExecutionOrder('stop get ' + id);
+          throw error;
+        });
+    };
+
+    StorageOneParallelOperation.prototype.getAttachment = function (id, name) {
+      assertExecutionOrder('start getAttachment ' + name);
+      var storage = this;
+      return storage._sub_storage.getAttachment(id, name)
+        .push(undefined, function (error) {
+          assertExecutionOrder('stop getAttachment ' + name);
+          throw error;
+        });
+    };
+
+    StorageOneParallelOperation.prototype.putAttachment = function (id, name,
+                                                                    blob) {
+      assertExecutionOrder('start putAttachment ' + name);
+      var storage = this;
+      return storage._sub_storage.putAttachment(id, name, blob)
+        .push(function (result) {
+          assertExecutionOrder('stop putAttachment ' + name);
+          return result;
+        });
+    };
+
+    StorageOneParallelOperation.prototype.buildQuery = function () {
+      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
+    };
+    StorageOneParallelOperation.prototype.allAttachments = function () {
+      return this._sub_storage.allAttachments.apply(this._sub_storage,
+        arguments);
+    };
+
+    StorageOneParallelOperation.prototype.hasCapacity = function () {
+      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
+    };
+
+    jIO.addStorage(
+      'one_parallel_attachment',
+      StorageOneParallelOperation
+    );
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_local_attachment_creation: true,
+      local_sub_storage: {
+        type: "memory"
+      },
+      remote_sub_storage: {
+        type: "one_parallel_attachment"
+      }
+    });
+
+    return RSVP.all([
+      context.jio.put("0", {}),
+      context.jio.put("1", {})
+    ])
+      .then(function () {
+        return RSVP.all([
+          context.jio.putAttachment("0", "00", new Blob(["0"])),
+          context.jio.putAttachment("0", "01", new Blob(["1"])),
+          context.jio.putAttachment("0", "02", new Blob(["2"])),
+          context.jio.putAttachment("0", "03", new Blob(["3"])),
+          context.jio.putAttachment("1", "10", new Blob(["0"])),
+          context.jio.putAttachment("1", "11", new Blob(["1"])),
+          context.jio.putAttachment("1", "12", new Blob(["2"])),
+          context.jio.putAttachment("1", "13", new Blob(["3"]))
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("use 2 parallel operation", function () {
+    stop();
+    expect(40);
+
+    var context = this,
+      order_number = 0,
+      expected_order_list = [
+        'start get 0',
+        'stop get 0',
+        'start put 0',
+        'stop put 0',
+        'start get 1',
+        'stop get 1',
+        'start put 1',
+        'stop put 1',
+
+        'start getAttachment 00',
+
+        'start getAttachment 01',
+        'stop getAttachment 01',
+        'start putAttachment 01',
+        'stop putAttachment 01',
+        'start getAttachment 02',
+        'stop getAttachment 02',
+        'start putAttachment 02',
+
+        'stop getAttachment 00',
+        'start putAttachment 00',
+        'stop putAttachment 00',
+        'start getAttachment 03',
+        'stop getAttachment 03',
+        'start putAttachment 03',
+        'stop putAttachment 03',
+
+        'stop putAttachment 02',
+
+        'start getAttachment 10',
+
+        'start getAttachment 11',
+        'stop getAttachment 11',
+        'start putAttachment 11',
+        'stop putAttachment 11',
+        'start getAttachment 12',
+        'stop getAttachment 12',
+        'start putAttachment 12',
+
+        'stop getAttachment 10',
+        'start putAttachment 10',
+        'stop putAttachment 10',
+        'start getAttachment 13',
+        'stop getAttachment 13',
+        'start putAttachment 13',
+        'stop putAttachment 13',
+
+        'stop putAttachment 12'
+      ],
+      defer0,
+      defer2;
+
+    function assertExecutionOrder(text) {
+      equal(text, expected_order_list[order_number],
+            expected_order_list[order_number]);
+      order_number += 1;
+    }
+
+    function StorageTwoParallelOperation() {
+      this._sub_storage = jIO.createJIO({type: "memory"});
+      return this;
+    }
+
+    StorageTwoParallelOperation.prototype.put = function (id, doc) {
+      assertExecutionOrder('start put ' + id);
+      var storage = this;
+      return storage._sub_storage.put(id, doc)
+        .push(function (result) {
+          assertExecutionOrder('stop put ' + id);
+          return result;
+        });
+    };
+
+    StorageTwoParallelOperation.prototype.get = function (id) {
+      assertExecutionOrder('start get ' + id);
+      var storage = this;
+      return storage._sub_storage.get(id)
+        .push(undefined, function (error) {
+          assertExecutionOrder('stop get ' + id);
+          throw error;
+        });
+    };
+
+
+    StorageTwoParallelOperation.prototype.getAttachment = function (id,
+                                                                     name) {
+      assertExecutionOrder('start getAttachment ' + name);
+      var storage = this;
+      return new RSVP.Queue()
+        .push(function () {
+          if (name[1] === "0") {
+            defer0 = RSVP.defer();
+            return defer0.promise;
+          }
+        })
+        .push(function () {
+          return storage._sub_storage.getAttachment(id, name);
+        })
+        .push(undefined, function (error) {
+          assertExecutionOrder('stop getAttachment ' + name);
+          throw error;
+        });
+    };
+
+    StorageTwoParallelOperation.prototype.putAttachment = function (id, name,
+                                                                     blob) {
+      assertExecutionOrder('start putAttachment ' + name);
+      var storage = this;
+      return new RSVP.Queue()
+        .push(function () {
+          if (name[1] === "2") {
+            defer0.resolve();
+            defer2 = RSVP.defer();
+            return defer2.promise;
+          }
+        })
+        .push(function () {
+          return storage._sub_storage.putAttachment(id, name, blob);
+        })
+        .push(function (result) {
+          if (name[1] === "3") {
+            defer2.resolve();
+          }
+          assertExecutionOrder('stop putAttachment ' + name);
+          return result;
+        });
+    };
+
+
+    StorageTwoParallelOperation.prototype.buildQuery = function () {
+      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
+    };
+    StorageTwoParallelOperation.prototype.allAttachments = function () {
+      return this._sub_storage.allAttachments.apply(this._sub_storage,
+        arguments);
+    };
+
+    StorageTwoParallelOperation.prototype.hasCapacity = function () {
+      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
+    };
+
+    jIO.addStorage(
+      'two_parallel_attachment',
+      StorageTwoParallelOperation
+    );
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_local_attachment_creation: true,
+      parallel_operation_attachment_amount: 2,
+      local_sub_storage: {
+        type: "memory"
+      },
+      remote_sub_storage: {
+        type: "two_parallel_attachment"
+      }
+    });
+
+    return RSVP.all([
+      context.jio.put("0", {}),
+      context.jio.put("1", {})
+    ])
+      .then(function () {
+        return RSVP.all([
+          context.jio.putAttachment("0", "00", new Blob(["0"])),
+          context.jio.putAttachment("0", "01", new Blob(["1"])),
+          context.jio.putAttachment("0", "02", new Blob(["2"])),
+          context.jio.putAttachment("0", "03", new Blob(["3"])),
+          context.jio.putAttachment("1", "10", new Blob(["0"])),
+          context.jio.putAttachment("1", "11", new Blob(["1"])),
+          context.jio.putAttachment("1", "12", new Blob(["2"])),
+          context.jio.putAttachment("1", "13", new Blob(["3"]))
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+  test("use 4 parallel operation", function () {
+    stop();
+    expect(40);
+
+    var context = this,
+      order_number = 0,
+      expected_order_list = [
+        'start get 0',
+        'stop get 0',
+        'start put 0',
+        'stop put 0',
+        'start get 1',
+        'stop get 1',
+        'start put 1',
+        'stop put 1',
+
+        'start getAttachment 00',
+        'stop getAttachment 00',
+        'start putAttachment 00',
+
+        'start getAttachment 01',
+        'stop getAttachment 01',
+        'start putAttachment 01',
+
+        'start getAttachment 02',
+        'stop getAttachment 02',
+        'start putAttachment 02',
+
+        'start getAttachment 03',
+        'stop getAttachment 03',
+        'start putAttachment 03',
+
+        'stop putAttachment 00',
+        'stop putAttachment 01',
+        'stop putAttachment 02',
+        'stop putAttachment 03',
+
+        'start getAttachment 10',
+        'stop getAttachment 10',
+        'start putAttachment 10',
+
+        'start getAttachment 11',
+        'stop getAttachment 11',
+        'start putAttachment 11',
+
+        'start getAttachment 12',
+        'stop getAttachment 12',
+        'start putAttachment 12',
+
+        'start getAttachment 13',
+        'stop getAttachment 13',
+        'start putAttachment 13',
+
+        'stop putAttachment 10',
+        'stop putAttachment 11',
+        'stop putAttachment 12',
+        'stop putAttachment 13'
+
+      ];
+
+    function assertExecutionOrder(text) {
+      equal(text, expected_order_list[order_number],
+            expected_order_list[order_number]);
+      order_number += 1;
+    }
+
+    function StorageFourParallelOperation() {
+      this._sub_storage = jIO.createJIO({type: "memory"});
+      return this;
+    }
+
+    StorageFourParallelOperation.prototype.put = function (id, doc) {
+      assertExecutionOrder('start put ' + id);
+      var storage = this;
+      return storage._sub_storage.put(id, doc)
+        .push(function (result) {
+          assertExecutionOrder('stop put ' + id);
+          return result;
+        });
+    };
+
+    StorageFourParallelOperation.prototype.get = function (id) {
+      assertExecutionOrder('start get ' + id);
+      var storage = this;
+      return storage._sub_storage.get(id)
+        .push(undefined, function (error) {
+          assertExecutionOrder('stop get ' + id);
+          throw error;
+        });
+    };
+
+    StorageFourParallelOperation.prototype.getAttachment = function (id,
+                                                                     name) {
+      assertExecutionOrder('start getAttachment ' + name);
+      var storage = this;
+      return storage._sub_storage.getAttachment(id, name)
+        .push(undefined, function (error) {
+          assertExecutionOrder('stop getAttachment ' + name);
+          throw error;
+        });
+    };
+
+    StorageFourParallelOperation.prototype.putAttachment = function (id, name,
+                                                                     blob) {
+      assertExecutionOrder('start putAttachment ' + name);
+      var storage = this;
+      return storage._sub_storage.putAttachment(id, name, blob)
+        .push(function (result) {
+          assertExecutionOrder('stop putAttachment ' + name);
+          return result;
+        });
+    };
+
+    StorageFourParallelOperation.prototype.buildQuery = function () {
+      return this._sub_storage.buildQuery.apply(this._sub_storage, arguments);
+    };
+    StorageFourParallelOperation.prototype.allAttachments = function () {
+      return this._sub_storage.allAttachments.apply(this._sub_storage,
+        arguments);
+    };
+
+    StorageFourParallelOperation.prototype.hasCapacity = function () {
+      return this._sub_storage.hasCapacity.apply(this._sub_storage, arguments);
+    };
+
+    jIO.addStorage(
+      'four_parallel_attachment',
+      StorageFourParallelOperation
+    );
+
+    this.jio = jIO.createJIO({
+      type: "replicate",
+      check_local_attachment_creation: true,
+      parallel_operation_attachment_amount: 4,
+      local_sub_storage: {
+        type: "memory"
+      },
+      remote_sub_storage: {
+        type: "four_parallel_attachment"
+      }
+    });
+
+    return RSVP.all([
+      context.jio.put("0", {}),
+      context.jio.put("1", {})
+    ])
+      .then(function () {
+        return RSVP.all([
+          context.jio.putAttachment("0", "00", new Blob(["0"])),
+          context.jio.putAttachment("0", "01", new Blob(["1"])),
+          context.jio.putAttachment("0", "02", new Blob(["2"])),
+          context.jio.putAttachment("0", "03", new Blob(["3"])),
+          context.jio.putAttachment("1", "10", new Blob(["0"])),
+          context.jio.putAttachment("1", "11", new Blob(["1"])),
+          context.jio.putAttachment("1", "12", new Blob(["2"])),
+          context.jio.putAttachment("1", "13", new Blob(["3"]))
+        ]);
+      })
+      .then(function () {
+        return context.jio.repair();
+      })
+      .fail(function (error) {
+        ok(false, error);
+      })
+      .always(function () {
+        start();
+      });
+  });
+
+
+}(jIO, QUnit, Blob, RSVP));
\ No newline at end of file
diff --git a/test/tests.html b/test/tests.html
index a1b4b765b6a5af4f746f6274b8d36b23a40de4e7..5712c9c3e117dc50e03ddf71badb86ceb763917c 100644
--- a/test/tests.html
+++ b/test/tests.html
@@ -40,6 +40,8 @@
   <script src="jio.storage/indexeddbstorage.tests.js"></script>
   <script src="jio.storage/uuidstorage.tests.js"></script>
   <script src="jio.storage/replicatestorage.tests.js"></script>
+  <script src="jio.storage/replicatestorage_repair.tests.js"></script>
+  <script src="jio.storage/replicatestorage_repairattachment.tests.js"></script>
   <script src="jio.storage/shastorage.tests.js"></script>
 
   <!--script src="jio.storage/qiniustorage.tests.js"></script-->