text: 'use strict';
  
  var contains    = require('es5-ext/string/#/contains')
    , customError = require('es5-ext/error/custom')
    , forEach     = require('es5-ext/object/for-each')
    , db          = require('../../').db
  
    , isArray = Array.isArray
    , unserializeObject = db.objects.unserialize
    , isObjectType = db.isObjectType;
  
  module.exports = function (data) {
  	var proto, prefixLength, obj, Type;
  
  	// Read prototype
  	forEach(data, function (value, id) {
  		var obj = unserializeObject(id);
  		if (proto == null) {
  			proto = obj.master;
  			if ((proto == null) || (proto.constructor.prototype !== proto) ||
  					!isObjectType(proto.constructor)) {
  				throw customError(proto.__id__ + " is not valid prototype",
  					'INVALID_PROTOTYPE');
  			}
  			return;
  		}
  		if (obj.master !== proto) throw customError("Prototype mismatch", 'PROTOTYPE_MISMATCH');
  	});
  
  	if (!proto) throw customError("Minimum one field must be filled", 'EMPTY_FORM_SUBMISSION');
  	Type = proto.constructor;
  	prefixLength = proto.__id__.length;
  	db._postponed_ += 1;
  	obj = new Type();
  	forEach(data, function (value, id) {
  		var target, Type;
  		if (!contains.call(id, '/')) return;
  		if (value === undefined) return;
  		target = unserializeObject(obj.__id__ + id.slice(prefixLength));
  		if (target._kind_ !== 'descriptor') {
  			throw new TypeError("Unsupported dbjs update");
  		}
  		Type = target.type;
  		if (isObjectType(Type)) {
  			if (isArray(value)) {
  				value.forEach(function (val, index) {
  					if (db.Object.is(val)) return;
  					value[index] = new Type(val);
  				});
  			} else if (value == null) {
  				if (target.nested) return;
  			} else if (!db.Object.is(value)) {
  				if (target.nested) {
  					target.object._get_(target._sKey_)._initialize_(value);
  					return;
  				}
  				value = new Type(value);
  			}
  		}
  		target.object._set_(target._sKey_, value);
  	});
  	db._postponed_ -= 1;
  	return obj;
  };
  