docs: function Class(parent, api) {
      if ( !api) {
        parent = (api = parent, 0); // !api means there's no parent
      }
  
      // TODO remove $statics, use $static instead
      var clazz, constructor, singleton, statics, key, bindTo, len, i = 0, p,
          ignoredKeys = { constructor: 1, $singleton: 1, $static:1, $statics: 1, prototype: 1, $super: 1, $superp: 1, main: 1, toString: 0 },
          plugins     = Class.plugins,
          rootParent, parentClass, Stub, descriptor;
  
      api         = (typeof api === "function" ? api() : api) || {};             // execute api if it's a function
      constructor = api.hasOwnProperty("constructor") ? api.constructor : null;  // hasOwnProperty is a must, constructor is special
      singleton   = api.$singleton;
      statics     = api.$statics || api.$static;
  
      // add plugins' keys into ignoredKeys
      for (key in plugins) { ignoredKeys[key] = 1; }
  
      // make sure parent be always an array
      parent = !parent || parent instanceof Array ? parent : [ parent ];
      len = parent && parent.length;
      rootParent = parent[0];
  
      // construct constructor
      clazz = singleton ? function(){} : (constructor ? constructor : function(){
        if (rootParent) {
          rootParent.apply(this, arguments);
        }
      });
  
      if ( !singleton && len) {
        parentClass = rootParent.prototype && rootParent === rootParent.prototype.constructor && rootParent;
  
        if ( !parentClass) {
          clazz.prototype = rootParent;
        } else {
          // Constributed by Freddy Snijder (https://github.com/tnhu/jsface/issues/26)
          Stub = function(){};
  
          Stub.prototype                    = parentClass.prototype;
          Stub.prototype.constructor        = Stub;
          clazz.prototype                   = new Stub();
          clazz.prototype.constructor       = clazz;       // restoring proper constructor for child class
          parentClass.prototype.constructor = parentClass; // restoring proper constructor for parent class
        }
      }
  
      // determine bindTo: where api should be bound
      bindTo = singleton ? clazz : clazz.prototype;
  
      // do inherit static properties and extentions (parents other than the first one)
      while (i < len) {
        p = parent[i++];
  
        // copy static properties
        for (key in p) {
          if ( !ignoredKeys[key]) {
            clazz[key] = p[key];
          }
        }
        if ( !singleton && i !== 0) {
          for (key in p.prototype) {
            if ( !ignoredKeys[key]) {
              descriptor = Object.getOwnPropertyDescriptor(p.prototype, key);                                    // Fix #37
              bindTo[key] = (descriptor && (descriptor.get || descriptor.set)) ? descriptor : p.prototype[key]; 
            }
          }
        }
      }
  
      // copy properties from api to bindTo
      for (key in api) {
        if ( !ignoredKeys[key]) {
          var prop = api[key];
  
          if (prop && (prop.get || prop.set)) {                 // check if it is a property descriptor
            prop.enumerable = true;
            Object.defineProperty(bindTo, key, prop);
          } else {
            bindTo[key] = prop;
          }
        }
      }
  
      // copy static properties from statics to clazz
      for (key in statics) {
        clazz[key] = statics[key];
      }
  
      // add $super and $superp to refer to parent class and parent.prototype (if applied)
      p = parent && rootParent || parent;
      clazz.$super  = p;
      clazz.$superp = p && p.prototype || p;
  
      for (key in plugins) { plugins[key](clazz, parent, api); }            // pass control to plugins
      if (typeof api.main === "function") { api.main.call(clazz, clazz); }  // execute main()
  
      return clazz;
    }