docs: public void defineProperty(String propertyName, Object delegateTo,
                                 Method getter, Method setter, int attributes)
      {
          MemberBox getterBox = null;
          if (getter != null) {
              getterBox = new MemberBox(getter);
  
              boolean delegatedForm;
              if (!Modifier.isStatic(getter.getModifiers())) {
                  delegatedForm = (delegateTo != null);
                  getterBox.delegateTo = delegateTo;
              } else {
                  delegatedForm = true;
                  // Ignore delegateTo for static getter but store
                  // non-null delegateTo indicator.
                  getterBox.delegateTo = Void.TYPE;
              }
  
              String errorId = null;
              Class<?>[] parmTypes = getter.getParameterTypes();
              if (parmTypes.length == 0) {
                  if (delegatedForm) {
                      errorId = "msg.obj.getter.parms";
                  }
              } else if (parmTypes.length == 1) {
                  Object argType = parmTypes[0];
                  // Allow ScriptableObject for compatibility
                  if (!(argType == ScriptRuntime.ScriptableClass ||
                        argType == ScriptRuntime.ScriptableObjectClass))
                  {
                      errorId = "msg.bad.getter.parms";
                  } else if (!delegatedForm) {
                      errorId = "msg.bad.getter.parms";
                  }
              } else {
                  errorId = "msg.bad.getter.parms";
              }
              if (errorId != null) {
                  throw Context.reportRuntimeError1(errorId, getter.toString());
              }
          }
  
          MemberBox setterBox = null;
          if (setter != null) {
              if (setter.getReturnType() != Void.TYPE)
                  throw Context.reportRuntimeError1("msg.setter.return",
                                                    setter.toString());
  
              setterBox = new MemberBox(setter);
  
              boolean delegatedForm;
              if (!Modifier.isStatic(setter.getModifiers())) {
                  delegatedForm = (delegateTo != null);
                  setterBox.delegateTo = delegateTo;
              } else {
                  delegatedForm = true;
                  // Ignore delegateTo for static setter but store
                  // non-null delegateTo indicator.
                  setterBox.delegateTo = Void.TYPE;
              }
  
              String errorId = null;
              Class<?>[] parmTypes = setter.getParameterTypes();
              if (parmTypes.length == 1) {
                  if (delegatedForm) {
                      errorId = "msg.setter2.expected";
                  }
              } else if (parmTypes.length == 2) {
                  Object argType = parmTypes[0];
                  // Allow ScriptableObject for compatibility
                  if (!(argType == ScriptRuntime.ScriptableClass ||
                        argType == ScriptRuntime.ScriptableObjectClass))
                  {
                      errorId = "msg.setter2.parms";
                  } else if (!delegatedForm) {
                      errorId = "msg.setter1.parms";
                  }
              } else {
                  errorId = "msg.setter.parms";
              }
              if (errorId != null) {
                  throw Context.reportRuntimeError1(errorId, setter.toString());
              }
          }
  
          GetterSlot gslot = (GetterSlot)slotMap.get(propertyName, 0,
              SlotAccess.MODIFY_GETTER_SETTER);
          gslot.setAttributes(attributes);
          gslot.getter = getterBox;
          gslot.setter = setterBox;
      }