docs: function protectMethod(name, meta, instance) {
          instance[cacheKeyword].methods[name] = meta.implementation;
  
          if (meta.isPrivate) {
              Object.defineProperty(instance, name, {
                  get: function get() {
                      var method = instance[cacheKeyword].methods[name],
                          isConstructor = name === 'initialize',
                          currCaller;
  
                      currCaller = caller;
  
                      if (instance.$initializing || (currCaller && (currCaller.method[$name] || currCaller.method[$anonymous]) && meta.allowed === currCaller.constructorId)) {
                          return method;
                      }
  
                      if (!isConstructor) {
                          throw new Error('Cannot access private method "' + name + '" of class "' + instance.$name + '".');
                      } else {
                          throw new Error('Constructor of class "' + instance.$name + '" is private.');
                      }
                  },
                  set: function set(newVal) {
                      if (instance.$initializing || !instance.$static[$class].locked || instance.$static[$class].forceUnlocked) {
                          instance[cacheKeyword].methods[name] = newVal;
                          instance[redefinedCacheKeyword].methods[name] = true; // This is just for the inspect
                      } else {
                          throw new Error('Cannot set private method "' + name + '" of class "' + instance.$name + '".');
                      }
                  },
                  configurable: false,
                  enumerable: true
              });
          } else if (meta.isProtected) {
              Object.defineProperty(instance, name, {
                  get: function get() {
                      var method = instance[cacheKeyword].methods[name],
                          isConstructor = name === 'initialize',
                          currCaller;
  
                      currCaller = caller;
  
                      if (instance.$initializing || (currCaller && (currCaller.method[$name] || currCaller.method[$anonymous]) && (contains(meta.allowed, currCaller.constructorId) || instance instanceof currCaller.constructor))) {
                          return method;
                      }
  
                      if (!isConstructor) {
                          throw new Error('Cannot access protected method "' + name + '" of class "' + instance.$name + '".');
                      } else {
                          throw new Error('Constructor of class "' + instance.$name + '" is protected.');
                      }
                  },
                  set: function set(newVal) {
                      if (instance.$initializing || !instance.$static[$class].locked || instance.$static[$class].forceUnlocked) {
                          instance[cacheKeyword].methods[name] = newVal;
                          instance[redefinedCacheKeyword].methods[name] = true; // This is just for the inspect
                      } else {
                          throw new Error('Cannot set protected method "' + name + '" of class "' + instance.$name + '".');
                      }
                  },
                  configurable: false,
                  enumerable: true
              });
          } else {
              Object.defineProperty(instance, name, {
                  get: function get() {
                      return instance[cacheKeyword].methods[name];
                  },
                  set: function set(newVal) {
                      if (instance.$initializing || !instance.$static[$class].locked || instance.$static[$class].forceUnlocked) {
                          instance[cacheKeyword].methods[name] = newVal;
                          instance[redefinedCacheKeyword].methods[name] = true;
                      } else {
                          throw new Error('Cannot set public method "' + name + '" of class "' + instance.$name + '".');
                      }
                  },
                  configurable: false,
                  enumerable: true
              });
          }
      }