var newReplicateStorage = function ( spec, my ) {
    var that = Jio.storage( spec, my, 'handler' ), priv = {};

    priv.return_value_array = [];
    priv.storagelist = spec.storagelist || [];
    priv.nb_storage = priv.storagelist.length;

    var super_serialized = that.serialized;
    that.serialized = function () {
        var o = super_serialized();
        o.storagelist = priv.storagelist;
        return o;
    };

    that.validateState = function () {
        if (priv.storagelist.length === 0) {
            return 'Need at least one parameter: "storagelist" '+
                'containing at least one storage.';
        }
        return '';
    };

    priv.isTheLast = function (error_array) {
        return (error_array.length === priv.nb_storage);
    };

    priv.doJob = function (command,errormessage,nodocid) {
        var done = false, error_array = [], i,
        error = function (err) {
            if (!done) {
                error_array.push(err);
                if (priv.isTheLast(error_array)) {
                    that.error ({
                        status:207,
                        statusText:'Multi-Status',
                        error:'multi_status',
                        message:'All '+errormessage+
                            (!nodocid?' "'+command.getDocId()+'"':' ') +
                            ' requests have failed.',
                        reason:'requests fail',
                        array:error_array
                    });
                }
            }
        },
        success = function (val) {
            if (!done) {
                done = true;
                that.success (val);
            }
        };
        for (i = 0; i < priv.nb_storage; i+= 1) {
            var cloned_option = command.cloneOption();
            that.addJob (command.getLabel(),priv.storagelist[i],
                         command.cloneDoc(),cloned_option,success,error);
        }
    };

    that.post = function (command) {
        priv.doJob (command,'post');
        that.end();
    };

    /**
     * Save a document in several storages.
     * @method put
     */
    that.put = function (command) {
        priv.doJob (command,'put');
        that.end();
    };

    /**
     * Load a document from several storages, and send the first retreived
     * document.
     * @method get
     */
    that.get = function (command) {
        priv.doJob (command,'get');
        that.end();
    };

    /**
     * Get a document list from several storages, and returns the first
     * retreived document list.
     * @method allDocs
     */
    that.allDocs = function (command) {
        priv.doJob (command,'allDocs',true);
        that.end();
    };

    /**
     * Remove a document from several storages.
     * @method remove
     */
    that.remove = function (command) {
        priv.doJob (command,'remove');
        that.end();
    };

    return that;
};
Jio.addStorageType('replicate', newReplicateStorage);
