private static Map<String, String> resolveProperties(
      final OperationContext context, final ModelNode model) throws OperationFailedException {
    Map<String, String> configurationProperties;
    if (model.hasDefined(PROPERTY)) {
      List<Property> propertyList = model.require(PROPERTY).asPropertyList();
      configurationProperties = new HashMap<String, String>(propertyList.size());

      for (Property current : propertyList) {
        String propertyName = current.getName();
        ModelNode valueNode =
            PropertyResourceDefinition.VALUE.resolveModelAttribute(context, current.getValue());
        String value = valueNode.isDefined() ? valueNode.asString() : null;
        configurationProperties.put(propertyName, value);
      }
      configurationProperties = Collections.unmodifiableMap(configurationProperties);
    } else {
      configurationProperties = Collections.emptyMap();
    }
    return configurationProperties;
  }
  @Override
  public void execute(final OperationContext context, final ModelNode operation)
      throws OperationFailedException {

    // read /subsystem=jgroups/stack=* for update
    final Resource resource = context.readResourceForUpdate(PathAddress.EMPTY_ADDRESS);
    final ModelNode subModel = resource.getModel();

    // validate the protocol type to be added
    ModelNode type = ProtocolResourceDefinition.TYPE.validateOperation(operation);
    PathElement protocolRelativePath = PathElement.pathElement(ModelKeys.PROTOCOL, type.asString());

    // if child resource already exists, throw OFE
    if (resource.hasChild(protocolRelativePath)) {
      throw JGroupsMessages.MESSAGES.protocolAlreadyDefined(protocolRelativePath.toString());
    }

    // now get the created model
    Resource childResource = context.createResource(PathAddress.pathAddress(protocolRelativePath));
    final ModelNode protocol = childResource.getModel();

    // Process attributes
    for (final AttributeDefinition attribute : attributes) {
      // we use PROPERTIES only to allow the user to pass in a list of properties on store add
      // commands
      // don't copy these into the model
      if (attribute.getName().equals(ModelKeys.PROPERTIES)) {
        continue;
      }

      attribute.validateAndSet(operation, protocol);
    }

    // get the current list of protocol names and add the new protocol
    // this list is used to maintain order
    ModelNode protocols = subModel.get(ModelKeys.PROTOCOLS);
    if (!protocols.isDefined()) {
      protocols.setEmptyList();
    }
    protocols.add(type);

    // Process type specific properties if required

    // The protocol parameters  <property name=>value</property>
    if (operation.hasDefined(ModelKeys.PROPERTIES)) {
      for (Property property : operation.get(ModelKeys.PROPERTIES).asPropertyList()) {
        // create a new property=name resource
        final Resource param =
            context.createResource(
                PathAddress.pathAddress(
                    protocolRelativePath,
                    PathElement.pathElement(ModelKeys.PROPERTY, property.getName())));
        final ModelNode value = property.getValue();
        if (!value.isDefined()) {
          throw JGroupsMessages.MESSAGES.propertyNotDefined(
              property.getName(), protocolRelativePath.toString());
        }
        // set the value of the property
        PropertyResourceDefinition.VALUE.validateAndSet(value, param.getModel());
      }
    }
    // This needs a reload
    reloadRequiredStep(context);
    context.stepCompleted();
  }