code: public ModelNode fromChangeset(Map<String, Object> changeSet, ModelNode address, ModelNode... extraSteps)
      {
  
          ModelNode protoType = new ModelNode();
          protoType.get(ADDRESS).set(address.get(ADDRESS));
          protoType.get(OP).set(WRITE_ATTRIBUTE_OPERATION);
  
          ModelNode operation = new ModelNode();
          operation.get(OP).set(COMPOSITE);
          operation.get(ADDRESS).setEmptyList();
  
          List<ModelNode> steps = new ArrayList<ModelNode>();
  
          List<PropertyBinding> propertyBindings = metaData.getBeanMetaData(type).getProperties();
  
          Map<String, ModelNode> flattenedSteps = new HashMap<String, ModelNode>();
          for(PropertyBinding binding : propertyBindings)
          {
              Object value = changeSet.get(binding.getJavaName());
              if (value == null) continue;
  
              ModelNode step = protoType.clone();
  
              // account for flattened sub-attribute paths
              String detypedName = binding.getDetypedName();
              String[] splitDetypedName = detypedName.split("/");
  
              step.get(NAME).set(splitDetypedName[0]);
              splitDetypedName[0] = VALUE;
              ModelNode nodeToSetValueUpon = step.get(splitDetypedName);
  
              if (binding.isFlattened()) { // unflatten
                  String attributePath = detypedName.substring(0, detypedName.lastIndexOf("/"));
                  ModelNode savedStep = flattenedSteps.get(attributePath);
                  if (savedStep == null) {
                      setValue(binding, nodeToSetValueUpon, value);
                      flattenedSteps.put(attributePath, step);
                  } else {
                      setValue(binding, savedStep.get(splitDetypedName), value);
                  }
  
              } else {
                  setValue(binding, nodeToSetValueUpon, value);
                  steps.add(step);
              }
          }
  
          // add steps for flattened attributes
          for (ModelNode step : flattenedSteps.values()) steps.add(step);
  
          // add extra steps
          steps.addAll(Arrays.asList(extraSteps));
  
          operation.get(STEPS).set(steps);
          System.out.println(operation);
          return operation;
      }
docs: Turns a changeset into a composite write attribute operation.
  
  @param changeSet
  @param address the entity address
  @return composite operation