/* Check that all descriptors have been returned */
  private static void checkDescriptors(
      ModelMBeanInfo modelMBeanInfo, Descriptor[] descriptors, String string) {
    int errCount = 0;
    final ArrayList<Descriptor> list = new ArrayList<Descriptor>(descriptors.length);
    list.addAll(Arrays.asList(descriptors));
    System.out.println("Got " + list.size() + " descriptors for " + string);

    // checks that MBean's descriptor is returned.
    //
    final Descriptor mbd = ((MBeanInfo) modelMBeanInfo).getDescriptor();
    if (!mbd.equals(remove(list, mbd))) {
      System.err.println("modelMBeanInfo.getDescriptor(): not found");
      errCount++;
    }

    // checks that MBean's attributes descriptors are returned.
    //
    final MBeanAttributeInfo[] attrs = modelMBeanInfo.getAttributes();
    for (MBeanAttributeInfo att : attrs) {
      final Descriptor ad = att.getDescriptor();
      final String name = att.getName();
      if (!ad.equals(remove(list, ad))) {
        System.err.println("attInfo.getDescriptor(): not found for " + name);
        errCount++;
      }
    }

    // checks that MBean's operations descriptors are returned.
    //
    final MBeanOperationInfo[] ops = modelMBeanInfo.getOperations();
    for (MBeanOperationInfo op : ops) {
      final Descriptor od = op.getDescriptor();
      final String name = op.getName();
      if (!od.equals(remove(list, od))) {
        System.err.println("opInfo.getDescriptor(): not found for " + name);
        errCount++;
      }
    }

    // checks that MBean's notifications descriptors are returned.
    //
    final MBeanNotificationInfo[] ntfs = modelMBeanInfo.getNotifications();
    for (MBeanNotificationInfo ntf : ntfs) {
      final Descriptor nd = ntf.getDescriptor();
      final String name = ntf.getName();
      if (!nd.equals(remove(list, nd))) {
        System.err.println("notifInfo.getDescriptor(): not found for " + name);
        errCount++;
      }
    }
    if (errCount > 0) {
      throw new RuntimeException(string + ": failed with " + errCount + " errors");
    } else if (list.size() != 0) {
      // Check that there are no additional descriptors
      //
      throw new RuntimeException(string + ": Unexpected remaining descriptors: " + list);
    } else System.out.println(string + ": PASSED");
  }
  static boolean equal(OpenMBeanParameterInfo x1, OpenMBeanParameterInfo x2) {
    if (x1 instanceof DescriptorRead) {
      if (!(x2 instanceof DescriptorRead)) return false;
      Descriptor d1 = ((DescriptorRead) x1).getDescriptor();
      Descriptor d2 = ((DescriptorRead) x2).getDescriptor();
      if (!d1.equals(d2)) return false;
    } else if (x2 instanceof DescriptorRead) return false;

    return x1.getName().equals(x2.getName())
        && x1.getOpenType().equals(x2.getOpenType())
        && (x1.hasDefaultValue()
            ? x1.getDefaultValue().equals(x2.getDefaultValue())
            : !x2.hasDefaultValue())
        && (x1.hasMinValue() ? x1.getMinValue().equals(x2.getMinValue()) : !x2.hasMinValue())
        && (x1.hasMaxValue() ? x1.getMaxValue().equals(x2.getMaxValue()) : !x2.hasMaxValue())
        && (x1.hasLegalValues()
            ? x1.getLegalValues().equals(x2.getLegalValues())
            : !x2.hasLegalValues());
  }