/**
   * Creates an argument (the one that the user should provide in the command-line) that is
   * equivalent to the modification proposed by the user in the provided PropertyEditorModification
   * object.
   *
   * @param mod the object describing the modification made.
   * @param <T> the type of the property to be retrieved.
   * @return the argument representing the modification.
   * @throws ArgumentException if there is a problem creating the argument.
   */
  private static <T> Argument createArgument(PropertyEditorModification<T> mod)
      throws ArgumentException {
    StringArgument arg;

    PropertyDefinition<T> propertyDefinition = mod.getPropertyDefinition();
    String propName = propertyDefinition.getName();

    switch (mod.getType()) {
      case RESET:
        arg =
            new StringArgument(
                OPTION_DSCFG_LONG_RESET,
                OPTION_DSCFG_SHORT_RESET,
                OPTION_DSCFG_LONG_RESET,
                false,
                true,
                true,
                INFO_PROPERTY_PLACEHOLDER.get(),
                null,
                null,
                INFO_DSCFG_DESCRIPTION_RESET_PROP.get());
        arg.addValue(propName);
        break;
      case REMOVE:
        arg =
            new StringArgument(
                OPTION_DSCFG_LONG_REMOVE,
                OPTION_DSCFG_SHORT_REMOVE,
                OPTION_DSCFG_LONG_REMOVE,
                false,
                true,
                true,
                INFO_VALUE_SET_PLACEHOLDER.get(),
                null,
                null,
                INFO_DSCFG_DESCRIPTION_REMOVE_PROP_VAL.get());
        for (T value : mod.getModificationValues()) {
          arg.addValue(propName + ':' + getArgumentValue(propertyDefinition, value));
        }
        break;
      case ADD:
        arg =
            new StringArgument(
                OPTION_DSCFG_LONG_ADD,
                OPTION_DSCFG_SHORT_ADD,
                OPTION_DSCFG_LONG_ADD,
                false,
                true,
                true,
                INFO_VALUE_SET_PLACEHOLDER.get(),
                null,
                null,
                INFO_DSCFG_DESCRIPTION_ADD_PROP_VAL.get());
        for (T value : mod.getModificationValues()) {
          arg.addValue(propName + ':' + getArgumentValue(propertyDefinition, value));
        }
        break;
      case SET:
        arg =
            new StringArgument(
                OPTION_DSCFG_LONG_SET,
                OPTION_DSCFG_SHORT_SET,
                OPTION_DSCFG_LONG_SET,
                false,
                true,
                true,
                INFO_VALUE_SET_PLACEHOLDER.get(),
                null,
                null,
                INFO_DSCFG_DESCRIPTION_PROP_VAL.get());
        for (T value : mod.getModificationValues()) {
          arg.addValue(propName + ':' + getArgumentValue(propertyDefinition, value));
        }
        break;
      default:
        // Bug
        throw new IllegalStateException("Unknown modification type: " + mod.getType());
    }
    return arg;
  }
  /** Private constructor. */
  private SetPropSubCommandHandler(
      SubCommandArgumentParser parser, ManagedObjectPath<?, ?> path, RelationDefinition<?, ?> r)
      throws ArgumentException {
    this.path = path;

    // Create the sub-command.
    String name = "set-" + r.getName() + "-prop";
    Message description =
        INFO_DSCFG_DESCRIPTION_SUBCMD_SETPROP.get(r.getChildDefinition().getUserFriendlyName());
    this.subCommand = new SubCommand(parser, name, false, 0, 0, null, description);

    // Create the naming arguments.
    this.namingArgs = createNamingArgs(subCommand, path, false);

    // Create the --set argument.
    this.propertySetArgument =
        new StringArgument(
            OPTION_DSCFG_LONG_SET,
            OPTION_DSCFG_SHORT_SET,
            OPTION_DSCFG_LONG_SET,
            false,
            true,
            true,
            INFO_VALUE_SET_PLACEHOLDER.get(),
            null,
            null,
            INFO_DSCFG_DESCRIPTION_PROP_VAL.get());
    this.subCommand.addArgument(this.propertySetArgument);

    // Create the --reset argument.
    this.propertyResetArgument =
        new StringArgument(
            OPTION_DSCFG_LONG_RESET,
            OPTION_DSCFG_SHORT_RESET,
            OPTION_DSCFG_LONG_RESET,
            false,
            true,
            true,
            INFO_PROPERTY_PLACEHOLDER.get(),
            null,
            null,
            INFO_DSCFG_DESCRIPTION_RESET_PROP.get());
    this.subCommand.addArgument(this.propertyResetArgument);

    // Create the --add argument.
    this.propertyAddArgument =
        new StringArgument(
            OPTION_DSCFG_LONG_ADD,
            OPTION_DSCFG_SHORT_ADD,
            OPTION_DSCFG_LONG_ADD,
            false,
            true,
            true,
            INFO_VALUE_SET_PLACEHOLDER.get(),
            null,
            null,
            INFO_DSCFG_DESCRIPTION_ADD_PROP_VAL.get());
    this.subCommand.addArgument(this.propertyAddArgument);

    // Create the --remove argument.
    this.propertyRemoveArgument =
        new StringArgument(
            OPTION_DSCFG_LONG_REMOVE,
            OPTION_DSCFG_SHORT_REMOVE,
            OPTION_DSCFG_LONG_REMOVE,
            false,
            true,
            true,
            INFO_VALUE_SET_PLACEHOLDER.get(),
            null,
            null,
            INFO_DSCFG_DESCRIPTION_REMOVE_PROP_VAL.get());
    this.subCommand.addArgument(this.propertyRemoveArgument);

    // Register the tags associated with the child managed objects.
    addTags(path.getManagedObjectDefinition().getAllTags());
  }