private Object getAttribute(
      final ResourceAndRegistration reg,
      final PathAddress address,
      final ObjectName name,
      final String attribute,
      final ResourceAccessControl accessControl)
      throws ReflectionException, AttributeNotFoundException, InstanceNotFoundException {
    final ImmutableManagementResourceRegistration registration = getMBeanRegistration(address, reg);
    final DescriptionProvider provider =
        registration.getModelDescription(PathAddress.EMPTY_ADDRESS);
    if (provider == null) {
      throw MESSAGES.descriptionProviderNotFound(address);
    }
    final ModelNode description = provider.getModelDescription(null);
    final String attributeName = findAttributeName(description.get(ATTRIBUTES), attribute);

    if (!accessControl.isReadableAttribute(attributeName)) {
      throw MESSAGES.notAuthorizedToReadAttribute(attributeName);
    }

    ModelNode op = new ModelNode();
    op.get(OP).set(READ_ATTRIBUTE_OPERATION);
    op.get(OP_ADDR).set(address.toModelNode());
    op.get(NAME).set(attributeName);
    ModelNode result = execute(op);
    String error = getFailureDescription(result);
    if (error != null) {
      throw new AttributeNotFoundException(error);
    }

    return converters.fromModelNode(
        description.require(ATTRIBUTES).require(attributeName), result.get(RESULT));
  }
  private void setAttribute(
      final ResourceAndRegistration reg,
      final PathAddress address,
      final ObjectName name,
      final Attribute attribute,
      ResourceAccessControl accessControl)
      throws InvalidAttributeValueException, AttributeNotFoundException, InstanceNotFoundException {
    final ImmutableManagementResourceRegistration registration = getMBeanRegistration(address, reg);
    final DescriptionProvider provider =
        registration.getModelDescription(PathAddress.EMPTY_ADDRESS);
    if (provider == null) {
      throw MESSAGES.descriptionProviderNotFound(address);
    }
    final ModelNode description = provider.getModelDescription(null);
    final String attributeName =
        findAttributeName(description.get(ATTRIBUTES), attribute.getName());

    if (!standalone) {
      throw MESSAGES.attributeNotWritable(attribute);
    }

    if (!accessControl.isWritableAttribute(attributeName)) {
      throw MESSAGES.notAuthorizedToWriteAttribute(attributeName);
    }

    ModelNode op = new ModelNode();
    op.get(OP).set(WRITE_ATTRIBUTE_OPERATION);
    op.get(OP_ADDR).set(address.toModelNode());
    op.get(NAME).set(attributeName);
    try {
      op.get(VALUE)
          .set(
              converters.toModelNode(
                  description.require(ATTRIBUTES).require(attributeName), attribute.getValue()));
    } catch (ClassCastException e) {
      throw MESSAGES.invalidAttributeType(e, attribute.getName());
    }
    ModelNode result = execute(op);
    String error = getFailureDescription(result);
    if (error != null) {
      // Since read-resource-description does not know the parameters of the operation, i.e. if a
      // vault expression is used or not,
      // check the error code
      // TODO add a separate authorize step where we check ourselves that the operation will pass
      // authorization?
      if (isVaultExpression(attribute.getValue()) && error.contains(AUTHORIZED_ERROR)) {
        throw MESSAGES.notAuthorizedToWriteAttribute(attributeName);
      }
      throw new InvalidAttributeValueException(error);
    }
  }
  private Object invoke(
      final OperationEntry entry, final String operationName, PathAddress address, Object[] params)
      throws InstanceNotFoundException, MBeanException, ReflectionException {
    if (!standalone && !entry.getFlags().contains(OperationEntry.Flag.READ_ONLY)) {
      throw MESSAGES.noOperationCalled(operationName);
    }

    ResourceAccessControl accessControl;
    if (operationName.equals("add")) {
      accessControl = accessControlUtil.getResourceAccess(address, true);
    } else {
      ObjectName objectName = ObjectNameAddressUtil.createObjectName(operationName, address);
      accessControl =
          accessControlUtil.getResourceAccessWithInstanceNotFoundExceptionIfNotAccessible(
              objectName, address, true);
    }

    if (!accessControl.isExecutableOperation(operationName)) {
      throw MESSAGES.notAuthorizedToExecuteOperation(operationName);
    }

    final ModelNode description = entry.getDescriptionProvider().getModelDescription(null);
    ModelNode op = new ModelNode();
    op.get(OP).set(operationName);
    op.get(OP_ADDR).set(address.toModelNode());
    if (params.length > 0) {
      ModelNode requestProperties = description.require(REQUEST_PROPERTIES);
      Set<String> keys = requestProperties.keys();
      if (keys.size() != params.length) {
        throw MESSAGES.differentLengths("params", "description");
      }
      Iterator<String> it = requestProperties.keys().iterator();
      for (int i = 0; i < params.length; i++) {
        String attributeName = it.next();
        ModelNode paramDescription = requestProperties.get(attributeName);
        op.get(attributeName).set(converters.toModelNode(paramDescription, params[i]));
      }
    }

    ModelNode result = execute(op);
    String error = getFailureDescription(result);
    if (error != null) {
      if (error.contains(AUTHORIZED_ERROR)) {
        for (Object param : params) {
          // Since read-resource-description does not know the parameters of the operation, i.e. if
          // a vault expression is used or not,
          // check the error code
          // TODO add a separate authorize step where we check ourselves that the operation will
          // pass authorization?
          if (isVaultExpression(param)) {
            throw MESSAGES.notAuthorizedToExecuteOperation(operationName);
          }
        }
      }
      throw new ReflectionException(null, error);
    }

    if (!description.hasDefined(REPLY_PROPERTIES)) {
      return null;
    }
    // TODO we could have more than one reply property
    return converters.fromModelNode(description.get(REPLY_PROPERTIES), result.get(RESULT));
  }