/**
   * Constructs an {@code OpenMBeanParameterInfoSupport} instance, which describes the parameter
   * used in one or more operations or constructors of a class of open MBeans, with the specified
   * {@code name}, {@code openType}, {@code description}, and {@code descriptor}.
   *
   * <p>The {@code descriptor} can contain entries that will define the values returned by certain
   * methods of this class, as explained in the {@link <a href="package-summary.html#constraints">
   * package description</a>}.
   *
   * @param name cannot be a null or empty string.
   * @param description cannot be a null or empty string.
   * @param openType cannot be null.
   * @param descriptor The descriptor for the parameter. This may be null which is equivalent to an
   *     empty descriptor.
   * @throws IllegalArgumentException if {@code name} or {@code description} are null or empty
   *     string, or {@code openType} is null, or the descriptor entries are invalid as described in
   *     the {@link <a href="package-summary.html#constraints">package description</a>}.
   * @since 1.6
   */
  public OpenMBeanParameterInfoSupport(
      String name, String description, OpenType<?> openType, Descriptor descriptor) {

    // Construct parent's state
    //
    super(
        name,
        (openType == null) ? null : openType.getClassName(),
        description,
        ImmutableDescriptor.union(
            descriptor, (openType == null) ? null : openType.getDescriptor()));

    // Initialize this instance's specific state
    //
    this.openType = openType;

    descriptor = getDescriptor(); // replace null by empty
    this.defaultValue = valueFrom(descriptor, "defaultValue", openType);
    this.legalValues = valuesFrom(descriptor, "legalValues", openType);
    this.minValue = comparableValueFrom(descriptor, "minValue", openType);
    this.maxValue = comparableValueFrom(descriptor, "maxValue", openType);

    try {
      check(this);
    } catch (OpenDataException e) {
      throw new IllegalArgumentException(e.getMessage(), e);
    }
  }
  /**
   * Constructs an {@code OpenMBeanOperationInfoSupport} instance, which describes the operation of
   * a class of open MBeans, with the specified {@code name}, {@code description}, {@code
   * signature}, {@code returnOpenType}, {@code impact}, and {@code descriptor}.
   *
   * <p>The {@code signature} array parameter is internally copied, so that subsequent changes to
   * the array referenced by {@code signature} have no effect on this instance.
   *
   * @param name cannot be a null or empty string.
   * @param description cannot be a null or empty string.
   * @param signature can be null or empty if there are no parameters to describe.
   * @param returnOpenType cannot be null: use {@code SimpleType.VOID} for operations that return
   *     nothing.
   * @param impact must be one of {@code ACTION}, {@code ACTION_INFO}, {@code INFO}, or {@code
   *     UNKNOWN}.
   * @param descriptor The descriptor for the operation. This may be null, which is equivalent to an
   *     empty descriptor.
   * @throws IllegalArgumentException if {@code name} or {@code description} are null or empty
   *     string, or {@code returnOpenType} is null, or {@code impact} is not one of {@code ACTION},
   *     {@code ACTION_INFO}, {@code INFO}, or {@code UNKNOWN}.
   * @throws ArrayStoreException If {@code signature} is not an array of instances of a subclass of
   *     {@code MBeanParameterInfo}.
   * @since 1.6
   */
  public OpenMBeanOperationInfoSupport(
      String name,
      String description,
      OpenMBeanParameterInfo[] signature,
      OpenType<?> returnOpenType,
      int impact,
      Descriptor descriptor) {
    super(
        name,
        description,
        arrayCopyCast(signature),
        // must prevent NPE here - we will throw IAE later on if
        // returnOpenType is null
        (returnOpenType == null) ? null : returnOpenType.getClassName(),
        impact,
        ImmutableDescriptor.union(
            descriptor,
            // must prevent NPE here - we will throw IAE later on if
            // returnOpenType is null
            (returnOpenType == null) ? null : returnOpenType.getDescriptor()));

    // check parameters that should not be null or empty
    // (unfortunately it is not done in superclass :-( ! )
    //
    if (name == null || name.trim().equals("")) {
      throw new IllegalArgumentException("Argument name cannot " + "be null or empty");
    }
    if (description == null || description.trim().equals("")) {
      throw new IllegalArgumentException("Argument description cannot " + "be null or empty");
    }
    if (returnOpenType == null) {
      throw new IllegalArgumentException("Argument returnOpenType " + "cannot be null");
    }

    if (impact != ACTION && impact != ACTION_INFO && impact != INFO && impact != UNKNOWN) {
      throw new IllegalArgumentException(
          "Argument impact can only be "
              + "one of ACTION, ACTION_INFO, "
              + "INFO, or UNKNOWN: "
              + impact);
    }

    this.returnOpenType = returnOpenType;
  }