@Override
 public void execute(OperationContext context, ModelNode operation)
     throws OperationFailedException {
   PathAddress address =
       context.getCurrentAddress().append(BinaryTableResourceDefinition.PATH);
   ModelNode table = Operations.getAttributeValue(operation);
   for (Class<? extends org.jboss.as.clustering.controller.Attribute> attributeClass :
       Arrays.asList(
           BinaryTableResourceDefinition.Attribute.class,
           TableResourceDefinition.Attribute.class)) {
     for (org.jboss.as.clustering.controller.Attribute attribute :
         attributeClass.getEnumConstants()) {
       ModelNode writeAttributeOperation =
           Operations.createWriteAttributeOperation(
               address, attribute, table.get(attribute.getDefinition().getName()));
       context.addStep(
           writeAttributeOperation,
           context
               .getResourceRegistration()
               .getAttributeAccess(
                   PathAddress.pathAddress(BinaryTableResourceDefinition.PATH),
                   attribute.getDefinition().getName())
               .getWriteHandler(),
           context.getCurrentStage());
     }
   }
 }
 @Override
 public void execute(OperationContext context, ModelNode operation)
     throws OperationFailedException {
   PathAddress address =
       context.getCurrentAddress().append(BinaryTableResourceDefinition.PATH);
   ModelNode readResourceOperation =
       Util.createOperation(ModelDescriptionConstants.READ_RESOURCE_OPERATION, address);
   operation.get(ModelDescriptionConstants.ATTRIBUTES_ONLY).set(true);
   context.addStep(
       readResourceOperation, new ReadResourceHandler(), context.getCurrentStage());
 }
 @Override
 public void execute(OperationContext context, ModelNode operation)
     throws OperationFailedException {
   if (operation.hasDefined(this.attribute.getName())) {
     // Translate deprecated table attribute into separate add table operation
     ModelNode addTableOperation =
         Util.createAddOperation(context.getCurrentAddress().append(this.path));
     ModelNode parameters = operation.get(this.attribute.getName());
     for (Property parameter : parameters.asPropertyList()) {
       addTableOperation.get(parameter.getName()).set(parameter.getValue());
     }
     context.addStep(
         addTableOperation,
         context
             .getResourceRegistration()
             .getOperationHandler(
                 PathAddress.pathAddress(this.path), ModelDescriptionConstants.ADD),
         context.getCurrentStage());
   }
 }
  @Override
  public void execute(OperationContext context, ModelNode operation)
      throws OperationFailedException {
    NAME.validateOperation(operation);
    final ModelNode nameModel =
        GlobalOperationAttributes.NAME.resolveModelAttribute(context, operation);
    final PathAddress address = context.getCurrentAddress();
    final ImmutableManagementResourceRegistration registry = context.getResourceRegistration();
    if (registry == null) {
      throw new OperationFailedException(ControllerLogger.ROOT_LOGGER.noSuchResourceType(address));
    }
    final boolean useEnhancedSyntax = containsEnhancedSyntax(nameModel.asString(), registry);
    final String attributeName;
    final String attributeExpression;
    if (useEnhancedSyntax) {
      attributeExpression = nameModel.asString();
      attributeName = extractAttributeName(nameModel.asString());
    } else {
      attributeName = nameModel.asString();
      attributeExpression = attributeName;
    }

    final AttributeAccess attributeAccess =
        registry.getAttributeAccess(PathAddress.EMPTY_ADDRESS, attributeName);
    if (attributeAccess == null) {
      throw new OperationFailedException(
          ControllerLogger.ROOT_LOGGER.unknownAttribute(attributeName));
    } else if (attributeAccess.getAccessType() != AttributeAccess.AccessType.READ_WRITE) {
      throw new OperationFailedException(
          ControllerLogger.ROOT_LOGGER.attributeNotWritable(attributeName));
    } else {

      // Authorize
      ModelNode currentValue;
      if (attributeAccess.getStorageType() == AttributeAccess.Storage.CONFIGURATION) {
        ModelNode model = context.readResourceForUpdate(PathAddress.EMPTY_ADDRESS).getModel();
        currentValue = model.has(attributeName) ? model.get(attributeName) : new ModelNode();
      } else {
        currentValue = new ModelNode();
      }
      AuthorizationResult authorizationResult =
          context.authorize(operation, attributeName, currentValue);
      if (authorizationResult.getDecision() == AuthorizationResult.Decision.DENY) {
        throw ControllerLogger.ROOT_LOGGER.unauthorized(
            operation.require(OP).asString(), address, authorizationResult.getExplanation());
      }

      if (attributeAccess.getStorageType() == AttributeAccess.Storage.CONFIGURATION
          && !registry.isRuntimeOnly()) {
        // if the attribute is stored in the configuration, we can read its
        // old and new value from the resource's model before and after executing its write handler
        final ModelNode oldValue = currentValue.clone();
        doExecuteInternal(
            context,
            operation,
            attributeAccess,
            attributeName,
            currentValue,
            useEnhancedSyntax,
            attributeExpression);
        ModelNode model = context.readResource(PathAddress.EMPTY_ADDRESS).getModel();
        ModelNode newValue = model.has(attributeName) ? model.get(attributeName) : new ModelNode();
        emitAttributeValueWrittenNotification(context, address, attributeName, oldValue, newValue);

      } else {
        assert attributeAccess.getStorageType() == AttributeAccess.Storage.RUNTIME;

        // if the attribute is a runtime attribute, its old and new values must
        // be read using the attribute's read handler and the write operation
        // must be sandwiched between the 2 calls to the read handler.
        // Each call to the read handlers will have their own results while
        // the call to the write handler will use this OSH context result.

        OperationContext.Stage currentStage = context.getCurrentStage();

        final ModelNode readAttributeOperation =
            Util.createOperation(READ_ATTRIBUTE_OPERATION, address);
        readAttributeOperation.get(NAME.getName()).set(attributeName);
        ReadAttributeHandler readAttributeHandler = new ReadAttributeHandler(null, null, false);

        // create 2 model nodes to store the result of the read-attribute operations
        // before and after writing the value
        final ModelNode oldValue = new ModelNode();
        final ModelNode newValue = new ModelNode();

        // We're going to add a bunch of steps, but we want them to execute right away
        // so we use the 'addFirst=true' param to addStep. That means we add them
        // in reverse order of how they will execute

        // 4th OSH is to emit the notification
        context.addStep(
            new OperationStepHandler() {
              @Override
              public void execute(OperationContext context, ModelNode operation)
                  throws OperationFailedException {
                // aggregate data from the 2 read-attribute operations
                emitAttributeValueWrittenNotification(
                    context, address, attributeName, oldValue.get(RESULT), newValue.get(RESULT));
              }
            },
            currentStage,
            true);

        // 3rd OSH is to read the new value
        context.addStep(newValue, readAttributeOperation, readAttributeHandler, currentStage, true);

        // 2nd OSH is to write the value
        context.addStep(
            new OperationStepHandler() {
              @Override
              public void execute(OperationContext context, ModelNode operation)
                  throws OperationFailedException {
                doExecuteInternal(
                    context,
                    operation,
                    attributeAccess,
                    attributeName,
                    oldValue.get(RESULT),
                    useEnhancedSyntax,
                    attributeExpression);
              }
            },
            currentStage,
            true);

        // 1st OSH is to read the old value
        context.addStep(oldValue, readAttributeOperation, readAttributeHandler, currentStage, true);
      }
    }
  }