docs: function(config){
      if (this instanceof EntityTypeWrapper)
      {
        var result;
  
        if (config.singleton)
          result = function(data){
            var entity = entityType.get();
  
            if (entity)
            {
              if (data)
                entity.update(data);
  
              /** @cut */ entity = basisData.devWrap(entity);
            }
            else
              entity = new EntityClass(data || {});
  
            return entity;
          };
        else
          result = function(data, entity){
            // newData - data for target EntityType instance
            // entity - current instance of target EntityType
  
            if (data != null)
            {
              // make sure second argument is correct entityType instance or ignore it
              if (!entity || entity.entityType !== entityType)
                entity = null;
  
              // if newData instance of target EntityType return newData
              if (data === entity || data.entityType === entityType)
                return data;
  
              var idValue;
              var idField = entityType.idField;
  
              if (isKeyType[typeof data])
              {
                if (!idField)
                {
                  /** @cut */ if (entityType.compositeKey)
                  /** @cut */   basis.dev.warn('basis.entity: Entity type `' + entityType.name + '` wrapper was invoked with ' + typeof(data) + ' value as index, but entity type index is composite and consists of [' + keys(entityType.idFields).join(', ') + '] fields');
                  /** @cut */ else
                  /** @cut */   basis.dev.warn('basis.entity: Entity type `' + entityType.name + '` wrapper was invoked with ' + typeof(data) + ' value as index, but entity type has no index');
  
                  return;
                }
  
                if (entity = entityType.index.get(data, entityType))
                  return entity;
  
                idValue = data;
                data = {};
                data[idField] = idValue;
              }
              else
              {
                if (entityType.compositeKey)
                  idValue = entityType.compositeKey(data, data);
  
                if (idValue != null)
                  entity = entityType.index.get(idValue, entityType);
              }
  
              if (entity && entity.entityType === entityType)
              {
                entity.update(data);
                /** @cut */ entity = basisData.devWrap(entity);
              }
              else
                entity = new EntityClass(data);
  
              return entity;
            }
          };
  
        var entityType = new EntityTypeConstructor(config || {}, result);
        var EntityClass = entityType.entityClass;
        var name = entityType.name;
  
        // resolve type by name
        defineType(name, result);
  
        // extend result with additional properties
        extend(result, {
          all: entityType.all,
  
          type: entityType,
          typeName: name,
  
          toString: function(){
            return name + '()';
          },
  
          get: function(data){
            return entityType.get(data);
          },
          getSlot: function(id, defaults){
            return entityType.getSlot(id, defaults);
          },
  
          reader: function(data){
            return entityType.reader(data);
          },
          readList: function(value, map){
            if (!value)
              return [];
  
            if (!Array.isArray(value))
              value = [value];
  
            if (typeof map != 'function')
              map = $self;
  
            for (var i = 0; i < value.length; i++)
              value[i] = result(result.reader(map(value[i], i)));
  
            return value;
          },
  
          extendClass: function(source){
            EntityClass.extend.call(EntityClass, source);
            return result;
          },
          extendReader: function(extReader){
            var reader = result.reader;
  
            result.reader = function(data){
              if (data && typeof data == 'object')
                extReader(data);
              return reader(data);
            };
  
            return result;
          },
  
          // deprecated in 1.3.0
          entityType: entityType,
          extend: function(){
            /** @cut */ basis.dev.warn('basis.entity: EntityType.extend() is deprecated, use EntityType.extendClass() instead.');
            return EntityClass.extend.apply(EntityClass, arguments);
          }
        });
  
        // deprecated in 1.3.0
        /** @cut */ basis.dev.warnPropertyAccess(result, 'entityType', entityType,
        /** @cut */   'basis.entity: EntityType.entityType is deprecated, use EntityType.type instead.'
        /** @cut */ );
  
        return result;
      }
      //else
      //  return namedEntityTypes.get(config);
    }