docs: function(wrapper, name, options){
      function createLocalId(id){
        if (typeof id == 'string')
          return function(data, item){
            return data[id] == item.data[id];
          };
  
        if (typeof id == 'function')
          return id;
      }
  
      if (this instanceof EntitySetWrapper)
      {
        if (!wrapper)
          wrapper = $self;
  
        if (!name || getTypeByNameIfDefined(name))
        {
          /** @cut */ if (getTypeByNameIfDefined(name)) basis.dev.warn(namespace + ': Duplicate entity set type name `' + this.name + '`, name ignored');
          name = getUntitledName('UntitledEntitySetType');
        }
  
        var entitySetType = new EntitySetConstructor({
          entitySetClass: {
            /** @cut */ className: namespace + '.EntitySet(' + (typeof wrapper == 'string' ? wrapper : (wrapper.type || wrapper).name || 'UnknownType') + ')',
            /** @cut */ name: 'Set of {' + (typeof wrapper == 'string' ? wrapper : (wrapper.type || wrapper).name || 'UnknownType') + '}',
            wrapper: wrapper,
            localId: createLocalId(options && options.localId)
          }
        });
  
        var EntitySetClass = entitySetType.entitySetClass;
        var result = function(data, entitySet){
          if (data != null)
          {
            if (entitySet instanceof EntitySet == false)
              entitySet = entitySetType.createEntitySet();
  
            entitySet.set(data instanceof Dataset ? data.getItems() : arrayFrom(data));
  
            return entitySet;
          }
          else
            return null;
        };
  
        // if wrapper is string resolve it by named type map
        if (typeof wrapper == 'string')
          EntitySetClass.prototype.wrapper = getTypeByName(wrapper, EntitySetClass.prototype, 'wrapper');
  
        // resolve type name
        defineType(name, result);
  
        // extend result with additional properties
        extend(result, {
          type: entitySetType,
          typeName: name,
  
          toString: function(){
            return name + '()';
          },
  
          reader: function(data){
            if (Array.isArray(data))
            {
              var wrapper = EntitySetClass.prototype.wrapper;
              return data.map(wrapper.reader || wrapper);
            }
  
            return data;
          },
  
          extendClass: function(source){
            EntitySetClass.extend.call(EntitySetClass, source);
            return result;
          },
          extendReader: function(extReader){
            var reader = result.reader;
  
            result.reader = function(data){
              if (Array.isArray(data))
                extReader(data);
              return reader(data);
            };
  
            return result;
          },
  
          // deprecated in 1.3.0
          entitySetType: entitySetType,
          extend: function(){
            /** @cut */ basis.dev.warn('basis.entity: EntitySetType.extend() is deprecated, use EntitySetType.extendClass() instead.');
            return EntitySetClass.extend.apply(EntitySetClass, arguments);
          }
        });
  
        // deprecated in 1.3.0
        /** @cut */ basis.dev.warnPropertyAccess(result, 'entitySetType', entitySetType,
        /** @cut */   'basis.entity: EntitySetType.entitySetType is deprecated, use EntitySetType.type instead.'
        /** @cut */ );
  
        return result;
      }
    }