docs: function protectProperty(name, meta, instance) {
          if (meta.isPrivate) {
              if (!meta.isImmutable) {
                  instance[cacheKeyword].properties[name] = deepClone(meta.value);
                  instance[redefinedCacheKeyword].properties[name] = true; // This is just for the inspect
              } else {
                  instance[cacheKeyword].properties[name] = meta.value;
              }
  
              Object.defineProperty(instance, name, {
                  get: function get() {
                      var currCaller = process._dejavu.caller;
  
                      if (instance.$initializing || (currCaller && (currCaller.method[$name] || currCaller.method[$anonymous]) && meta.allowed === currCaller.constructorId)) {
                          return instance[cacheKeyword].properties[name];
                      }
  
                      throw new Error('Cannot access private property "' + name + '" of class "' + instance.$name + '".');
                  },
                  set: function set(newVal) {
                      var currCaller = process._dejavu.caller;
  
                      if (instance.$initializing || (currCaller && (currCaller.method[$name] || currCaller.method[$anonymous]) && meta.allowed === currCaller.constructorId)) {
                          instance[cacheKeyword].properties[name] = newVal;
                          instance[redefinedCacheKeyword].properties[name] = true;
                      } else {
                          throw new Error('Cannot set private property "' + name + '" of class "' + instance.$name + '".');
                      }
                  },
                  configurable: false,
                  enumerable: true
              });
          } else if (meta.isProtected) {
              if (!meta.isImmutable) {
                  instance[cacheKeyword].properties[name] = deepClone(meta.value);
                  instance[redefinedCacheKeyword].properties[name] = true; // This is just for the inspect
              } else {
                  instance[cacheKeyword].properties[name] = meta.value;
              }
  
              Object.defineProperty(instance, name, {
                  get: function get() {
                      var currCaller = process._dejavu.caller;
  
                      if (instance.$initializing || (currCaller && (currCaller.method[$name] || currCaller.method[$anonymous]) && (contains(meta.allowed, currCaller.constructorId) || instance instanceof currCaller.constructor))) {
                          return instance[cacheKeyword].properties[name];
                      }
  
                      throw new Error('Cannot access protected property "' + name + '" of class "' + instance.$name + '".');
                  },
                  set: function set(newVal) {
                      var currCaller = process._dejavu.caller;
  
                      if (instance.$initializing || (currCaller && (currCaller.method[$name] || currCaller.method[$anonymous]) && (contains(meta.allowed, currCaller.constructorId) || instance instanceof currCaller.constructor))) {
                          instance[cacheKeyword].properties[name] = newVal;
                          instance[redefinedCacheKeyword].properties[name] = true;
                      } else {
                          throw new Error('Cannot set protected property "' + name + '" of class "' + instance.$name + '".');
                      }
                  },
                  configurable: false,
                  enumerable: true
              });
          } else if (!meta.isImmutable) {
              instance[name] = deepClone(instance[name]);
              instance[redefinedCacheKeyword].properties[name] = true; // This is just for the inspect
          } else {
              instance[name] = meta.value;
          }
      }