docs: function createClass(SuperClass){
        var classId = classSeed++;
  
        if (typeof SuperClass != 'function')
          SuperClass = BaseClass;
  
        /** @cut */ var className = '';
  
        /** @cut */ for (var i = 1, extension; extension = arguments[i]; i++)
        /** @cut */   if (typeof extension != 'function' && extension.className)
        /** @cut */     className = extension.className;
  
        /** @cut */ if (!className)
        /** @cut */   className = SuperClass.className + '._Class' + classId;
  
        // temp class constructor with no init call
        var NewClassProto = function(){};
  
        // verbose name in dev
        /** @cut */ NewClassProto = devVerboseName(className, {}, NewClassProto);
  
        NewClassProto.prototype = SuperClass.prototype;
  
        var newProto = new NewClassProto;
        var newClassProps = {
          /** @cut */ className: className,
  
          basisClassId_: classId,
          superClass_: SuperClass,
          extendConstructor_: !!SuperClass.extendConstructor_,
  
          // class methods
          isSubclassOf: isSubclassOf,
          subclass: function(){
            return createClass.apply(null, [NewClass].concat(arrayFrom(arguments)));
          },
          extend: extendClass,
          factory: function(config){
            return factory(function(extra){
              return new NewClass(merge(config, extra));
            });
          },
  
          // auto extend creates a subclass
          __extend__: function(value){
            if (value && value !== SELF && (typeof value == 'object' || (typeof value == 'function' && !isClass(value))))
              return BaseClass.create.call(null, NewClass, value);
            else
              return value;
          },
  
          // new class prototype
          prototype: newProto
        };
  
        // extend NewClass prototype
        for (var i = 1, extension; extension = arguments[i]; i++)
          newClassProps.extend(extension);
  
        /** @cut */if (newProto.init !== BaseClass.prototype.init && !/^function[^(]*\(\)/.test(newProto.init) && newClassProps.extendConstructor_) consoleMethods.warn('probably wrong extendConstructor_ value for ' + newClassProps.className);
  
        // new class constructor
        var NewClass = newClassProps.extendConstructor_
          // constructor with instance extension
          ? function(extend){
              // mark object
              this.basisObjectId = instanceSeed.id++;
  
              // extend and override instance properties
              var prop;
              for (var key in extend)
              {
                prop = this[key];
                this[key] = prop && prop.__extend__
                  ? prop.__extend__(extend[key])
                  : extend[key];
              }
  
              // call constructor
              this.init();
  
              // post init
              this.postInit();
            }
  
          // simple constructor
          : function(){
              // mark object
              this.basisObjectId = instanceSeed.id++;
  
              // call constructor
              this.init.apply(this, arguments);
  
              // post init
              this.postInit();
            };
  
        // verbose name in dev
        // NOTE: this code makes Chrome and Firefox show class name in console
        /** @cut */ NewClass = devVerboseName(className, { instanceSeed: instanceSeed }, NewClass);
  
        // add constructor property to prototype
        newProto.constructor = NewClass;
  
        for (var key in newProto)
          if (newProto[key] === SELF)
            newProto[key] = NewClass;
          //else
          //  newProto[key] = newProto[key];
  
        // extend constructor with properties
        extend(NewClass, newClassProps);
  
        // for class introspection
        /** @cut */ classes.push(NewClass);
  
        // return new class
        return NewClass;
      }