docs: function parseClass(params, constructor) {
          var opts = {},
              key,
              value,
              saved = {},
              unallowed,
              ambiguous;
  
          // Check and save constants to parse later
          if (hasOwn(params, '$constants')) {
              // Check argument
              if (!isObject(params.$constants)) {
                  throw new Error('$constants of class "' + constructor.prototype.$name + '" must be an object.');
              }
  
              // Check reserved keywords
              checkKeywords(params.$constants, 'statics');
  
              // Check unallowed keywords
              unallowed = testKeywords(params.$constants);
              if (unallowed) {
                  throw new Error('$constants of class "' + constructor.prototype.$name + '" contains an unallowed keyword: "' + unallowed + '".');
              }
  
              // Check ambiguity
              if (isObject(params.$statics)) {
                  ambiguous = intersection(keys(params.$constants), keys(params.$statics));
                  if (ambiguous.length) {
                      throw new Error('There are members defined in class "' + constructor.prototype.$name + '" with the same name but with different modifiers: "' + ambiguous.join('", ') + '".');
                  }
              }
  
              saved.$constants = params.$constants;
              delete params.$constants;
          }
  
          // Check and save finals to parse later
          if (hasOwn(params, '$finals')) {
              // Check argument
              if (!isObject(params.$finals)) {
                  throw new Error('$finals of class "' + constructor.prototype.$name + '" must be an object.');
              }
  
              // Check reserved keywords
              checkKeywords(params.$finals);
  
              // Check unallowed keywords
              unallowed = testKeywords(params.$finals, ['$statics']);
              if (unallowed) {
                  throw new Error('$finals of class "' + constructor.prototype.$name + '" contains an unallowed keyword: "' + unallowed + '".');
              }
  
              // Check ambiguity
              if (isObject(params.$finals.$statics)) {
                  if (isObject(params.$statics)) {
                      ambiguous = intersection(keys(params.$finals.$statics), keys(params.$statics));
                      if (ambiguous.length) {
                          throw new Error('There are members defined in class "' + constructor.prototype.$name + '" with the same name but with different modifiers: "' + ambiguous.join('", ') + '".');
                      }
                  }
                  if (saved.$constants) {
                      ambiguous = intersection(keys(params.$finals.$statics), keys(saved.$constants));
                      if (ambiguous.length) {
                          throw new Error('There are members defined in class "' + constructor.prototype.$name + '" with the same name but with different modifiers: "' + ambiguous.join('", ') + '".');
                      }
                  }
              }
              ambiguous = intersection(keys(params), keys(params.$finals));
              if (ambiguous.length) {
                  remove(ambiguous, '$statics');
                  if (ambiguous.length) {
                      throw new Error('There are members defined in class "' + constructor.prototype.$name + '" with the same name but with different modifiers: "' + ambiguous.join('", ') + '".');
                  }
              }
  
              saved.$finals = params.$finals;
              delete params.$finals;
          }
  
          // Check and save locked to parse later
          if (hasOwn(params, '$locked')) {
              if (!isBoolean(params.$locked)) {
                  throw new Error('$locked of class "' + constructor.prototype.name + '" must be a boolean.');
              }
  
              saved.$locked = params.$locked;
              delete params.$locked;
          }
  
          // Parse members
          parseMembers(params, constructor);
  
          // Parse constants
          if (saved.$constants) {
              opts.isConst = true;
  
              for (key in saved.$constants) {
                  value = saved.$constants[key];
  
                  addProperty(key, value, constructor, opts);
              }
  
              delete opts.isConst;
          }
  
          // Parse finals
          if (saved.$finals) {
              parseMembers(saved.$finals, constructor, true);
          }
  
          // Parse locked
          if (hasOwn(saved, '$locked')) {
              if (constructor[$class].forceUnlocked && saved.$locked) {
                  throw new Error('Class "' + constructor.prototype.$name + '" cannot be locked because it borrows or extends from a vanilla class.');
              }
              if (constructor[$class].locked === false && saved.$locked) {
                  throw new Error('Class "' + constructor.prototype.$name + '" inherits from an unlocked class, therefore its subclasses cannot be locked.');
              }
              constructor[$class].locked = !!saved.$locked;
              delete constructor.prototype.$locked;
          } else if (!hasOwn(constructor[$class], 'locked')) {
              constructor[$class].locked = !!options.locked;
          }
      }