/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.geode.management.internal;

import static javax.management.openmbean.SimpleType.BIGDECIMAL;
import static javax.management.openmbean.SimpleType.BIGINTEGER;
import static javax.management.openmbean.SimpleType.BOOLEAN;
import static javax.management.openmbean.SimpleType.BYTE;
import static javax.management.openmbean.SimpleType.CHARACTER;
import static javax.management.openmbean.SimpleType.DATE;
import static javax.management.openmbean.SimpleType.DOUBLE;
import static javax.management.openmbean.SimpleType.FLOAT;
import static javax.management.openmbean.SimpleType.INTEGER;
import static javax.management.openmbean.SimpleType.LONG;
import static javax.management.openmbean.SimpleType.OBJECTNAME;
import static javax.management.openmbean.SimpleType.SHORT;
import static javax.management.openmbean.SimpleType.STRING;
import static javax.management.openmbean.SimpleType.VOID;

import java.beans.ConstructorProperties;
import java.io.InvalidObjectException;
import java.lang.ref.WeakReference;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.WeakHashMap;

import javax.management.JMX;
import javax.management.ObjectName;
import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataInvocationHandler;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.TabularType;

import org.apache.geode.annotations.Immutable;
import org.apache.geode.annotations.internal.MakeNotStatic;
import org.apache.geode.management.ManagementException;

/**
 * It takes care of converting a Java type to an open types
 *
 * A Java type is an instance of java.lang.reflect.Type representing all types in Java.
 *
 * Each Type is associated with an OpenTypeConverter. The OpenTypeConverter defines an OpenType
 * corresponding to the Type, plus a Java class corresponding to the OpenType. For example:
 *
 *
 * Java Type : Integer Open Class :Integer Open Type :SimpleType.INTEGER
 *
 * Apart from simple types, arrays, and collections, Java types are converted through introspection
 * into CompositeType
 */
public abstract class OpenTypeConverter {

  private final Type targetType;

  /**
   * The Java class corresponding to getOpenType(). This is the class named by
   * getOpenType().getClassName(), except that it may be a primitive type or an array of primitive
   * type.
   */
  private final OpenType openType;

  private final Class openClass;

  private static class ConverterMap extends WeakHashMap<Type, WeakReference<OpenTypeConverter>> {
  }

  @MakeNotStatic
  private static final ConverterMap converterMap = new ConverterMap();

  @MakeNotStatic
  private static final Map<Type, Type> inProgress = OpenTypeUtil.newIdentityHashMap();

  /**
   * Following List simply serves to keep a reference to predefined OpenConverters so they don't get
   * garbage collected.
   */
  @MakeNotStatic
  private static final List<OpenTypeConverter> preDefinedConverters = OpenTypeUtil.newList();

  protected OpenTypeConverter(Type targetType, OpenType openType, Class openClass) {
    this.targetType = targetType;
    this.openType = openType;
    this.openClass = openClass;
  }

  /**
   * Convert an instance of openClass into an instance of targetType.
   *
   * @return the java type object
   */
  public Object fromOpenValue(Object value) throws InvalidObjectException {
    if (value == null)
      return null;
    else
      return fromNonNullOpenValue(value);
  }

  abstract Object fromNonNullOpenValue(Object value) throws InvalidObjectException;

  /**
   * Throw an appropriate InvalidObjectException if we will not be able to convert back from the
   * open data to the original Java object.
   */
  void checkReconstructible() throws InvalidObjectException {
    // subclasses can override
  }

  /**
   * Convert an instance of targetType into an instance of openClass.
   *
   * @return open class object
   */
  Object toOpenValue(Object value) throws OpenDataException {
    if (value == null)
      return null;
    else
      return toNonNullOpenValue(value);
  }

  abstract Object toNonNullOpenValue(Object value) throws OpenDataException;

  /**
   * @return True if and only if this OpenTypeConverter's toOpenValue and fromOpenValue methods are
   *         the identity function.
   */
  boolean isIdentity() {
    return false;
  }

  Type getTargetType() {
    return targetType;
  }

  OpenType getOpenType() {
    return openType;
  }

  Class getOpenClass() {
    return openClass;
  }

  /**
   * @return a converter corresponding to a type
   */
  private static synchronized OpenTypeConverter getConverter(Type type) {

    if (type instanceof GenericArrayType) {
      Type component = ((GenericArrayType) type).getGenericComponentType();
      if (component instanceof Class)
        type = Array.newInstance((Class<?>) component, 0).getClass();
    }

    WeakReference<OpenTypeConverter> wr = converterMap.get(type);
    return (wr == null) ? null : wr.get();
  }

  /**
   * Put the converter in the map to avoid future creation
   */
  private static synchronized void putConverter(Type type, OpenTypeConverter conv) {
    WeakReference<OpenTypeConverter> wr = new WeakReference<OpenTypeConverter>(conv);
    converterMap.put(type, wr);
  }

  private static synchronized void putPreDefinedConverter(Type type, OpenTypeConverter conv) {
    putConverter(type, conv);
    preDefinedConverters.add(conv);
  }

  /*
   * Static block to initialize pre defined convertor
   */
  static {

    final OpenType[] simpleTypes = {BIGDECIMAL, BIGINTEGER, BOOLEAN, BYTE, CHARACTER, DATE, DOUBLE,
        FLOAT, INTEGER, LONG, OBJECTNAME, SHORT, STRING, VOID,};

    for (int i = 0; i < simpleTypes.length; i++) {
      final OpenType t = simpleTypes[i];
      Class c;
      try {
        c = Class.forName(t.getClassName(), false, ObjectName.class.getClassLoader());
      } catch (ClassNotFoundException e) {
        throw new Error(e);
      }
      final OpenTypeConverter conv = new IdentityConverter(c, t, c);
      putPreDefinedConverter(c, conv);

      if (c.getName().startsWith("java.lang.")) {
        try {
          final Field typeField = c.getField("TYPE");
          final Class primitiveType = (Class) typeField.get(null);
          final OpenTypeConverter primitiveConv =
              new IdentityConverter(primitiveType, t, primitiveType);
          putPreDefinedConverter(primitiveType, primitiveConv);
          if (primitiveType != void.class) {
            final Class primitiveArrayType = Array.newInstance(primitiveType, 0).getClass();
            final OpenType primitiveArrayOpenType =
                ArrayType.getPrimitiveArrayType(primitiveArrayType);
            final OpenTypeConverter primitiveArrayConv = new IdentityConverter(primitiveArrayType,
                primitiveArrayOpenType, primitiveArrayType);
            putPreDefinedConverter(primitiveArrayType, primitiveArrayConv);
          }
        } catch (NoSuchFieldException e) {

        } catch (IllegalAccessException e) {
          assert (false);
        }
      }
    }
  }

  /**
   * @return the converter for the given Java type, creating it if necessary
   */
  public static synchronized OpenTypeConverter toConverter(Type objType) throws OpenDataException {

    if (inProgress.containsKey(objType)) {
      throw new OpenDataException("Recursive data structure, including " + typeName(objType));
    }

    OpenTypeConverter conv;

    conv = getConverter(objType);
    if (conv != null)
      return conv;

    inProgress.put(objType, objType);
    try {
      conv = makeConverter(objType);
    } catch (OpenDataException e) {
      throw openDataException("Cannot convert type: " + objType, e);
    } finally {
      inProgress.remove(objType);
    }

    putConverter(objType, conv);
    return conv;
  }

  /**
   * @return the open type converter for a given type
   */
  private static OpenTypeConverter makeConverter(Type objType) throws OpenDataException {

    if (objType instanceof GenericArrayType) {
      Type componentType = ((GenericArrayType) objType).getGenericComponentType();
      return makeArrayOrCollectionConverter(objType, componentType);
    } else if (objType instanceof Class) {
      Class objClass = (Class<?>) objType;
      if (objClass.isEnum()) {
        return makeEnumConverter(objClass);
      } else if (objClass.isArray()) {
        Type componentType = objClass.getComponentType();
        return makeArrayOrCollectionConverter(objClass, componentType);
      } else if (JMX.isMXBeanInterface(objClass)) {
        throw openDataException("Cannot obtain array class",
            new ManagementException(" MXBean as an Return Type is not supported"));
      } else {
        return makeCompositeConverter(objClass);
      }
    } else if (objType instanceof ParameterizedType) {
      return makeParameterizedConverter((ParameterizedType) objType);
    } else
      throw new OpenDataException("Cannot map type: " + objType);
  }

  private static <T extends Enum<T>> OpenTypeConverter makeEnumConverter(Class<T> enumClass) {
    return new EnumConverter<T>(enumClass);
  }

  private static OpenTypeConverter makeArrayOrCollectionConverter(Type collectionType,
      Type elementType) throws OpenDataException {

    final OpenTypeConverter elementConverter = toConverter(elementType);
    final OpenType elementOpenType = elementConverter.getOpenType();
    final ArrayType openType = new ArrayType(1, elementOpenType);
    final Class elementOpenClass = elementConverter.getOpenClass();

    final Class openArrayClass;
    final String openArrayClassName;
    if (elementOpenClass.isArray())
      openArrayClassName = "[" + elementOpenClass.getName();
    else
      openArrayClassName = "[L" + elementOpenClass.getName() + ";";
    try {
      openArrayClass = Class.forName(openArrayClassName);
    } catch (ClassNotFoundException e) {
      throw openDataException("Cannot obtain array class", e);
    }

    if (collectionType instanceof ParameterizedType) {
      return new CollectionConverter(collectionType, openType, openArrayClass, elementConverter);
    } else {
      if (elementConverter.isIdentity()) {
        return new IdentityConverter(collectionType, openType, openArrayClass);
      } else {
        return new ArrayConverter(collectionType, openType, openArrayClass, elementConverter);
      }
    }
  }

  @Immutable
  protected static final String[] keyArray = {"key"};

  @Immutable
  protected static final String[] keyValueArray = {"key", "value"};

  private static OpenTypeConverter makeTabularConverter(Type objType, boolean sortedMap,
      Type keyType, Type valueType) throws OpenDataException {

    final String objTypeName = objType.toString();
    final OpenTypeConverter keyConverter = toConverter(keyType);
    final OpenTypeConverter valueConverter = toConverter(valueType);
    final OpenType keyOpenType = keyConverter.getOpenType();
    final OpenType valueOpenType = valueConverter.getOpenType();
    final CompositeType rowType = new CompositeType(objTypeName, objTypeName, keyValueArray,
        keyValueArray, new OpenType[] {keyOpenType, valueOpenType});
    final TabularType tabularType = new TabularType(objTypeName, objTypeName, rowType, keyArray);
    return new TableConverter(objType, sortedMap, tabularType, keyConverter, valueConverter);
  }

  /**
   * Supported types are List<E>, Set<E>, SortedSet<E>, Map<K,V>, SortedMap<K,V>.
   *
   * Subclasses of the above types wont be supported as deserialize info wont be there.
   *
   * Queue<E> won't be supported as Queue is more of a functional data structure rather than a data
   * holder
   *
   * @return the open type converter for a given type
   */
  private static OpenTypeConverter makeParameterizedConverter(ParameterizedType objType)
      throws OpenDataException {

    final Type rawType = objType.getRawType();

    if (rawType instanceof Class) {
      Class c = (Class<?>) rawType;
      if (c == List.class || c == Set.class || c == SortedSet.class) {
        Type[] actuals = ((ParameterizedType) objType).getActualTypeArguments();
        assert (actuals.length == 1);
        if (c == SortedSet.class)
          mustBeComparable(c, actuals[0]);
        return makeArrayOrCollectionConverter(objType, actuals[0]);
      } else {
        boolean sortedMap = (c == SortedMap.class);
        if (c == Map.class || sortedMap) {
          Type[] actuals = ((ParameterizedType) objType).getActualTypeArguments();
          assert (actuals.length == 2);
          if (sortedMap)
            mustBeComparable(c, actuals[0]);
          return makeTabularConverter(objType, sortedMap, actuals[0], actuals[1]);
        }
      }
    }
    throw new OpenDataException("Cannot convert type: " + objType);
  }

  /**
   * @return the open type converrter for a given type
   */
  private static OpenTypeConverter makeCompositeConverter(Class c) throws OpenDataException {

    final List<Method> methods = Arrays.asList(c.getMethods());
    final SortedMap<String, Method> getterMap = OpenTypeUtil.newSortedMap();

    for (Method method : methods) {
      final String propertyName = propertyName(method);

      if (propertyName == null)
        continue;

      Method old = getterMap.put(OpenTypeUtil.toCamelCase(propertyName), method);
      if (old != null) {
        final String msg = "Class " + c.getName() + " has method name clash: " + old.getName()
            + ", " + method.getName();
        throw new OpenDataException(msg);
      }
    }

    final int nitems = getterMap.size();

    if (nitems == 0) {
      throw new OpenDataException("Can't map " + c.getName() + " to an open data type");
    }

    final Method[] getters = new Method[nitems];
    final String[] itemNames = new String[nitems];
    final OpenType[] openTypes = new OpenType[nitems];
    int i = 0;
    for (Map.Entry<String, Method> entry : getterMap.entrySet()) {
      itemNames[i] = entry.getKey();
      final Method getter = entry.getValue();
      getters[i] = getter;
      final Type retType = getter.getGenericReturnType();
      openTypes[i] = toConverter(retType).getOpenType();
      i++;
    }

    CompositeType compositeType = new CompositeType(c.getName(), c.getName(), itemNames, // field
                                                                                         // names
        itemNames, // field descriptions
        openTypes);

    return new CompositeConverter(c, compositeType, itemNames, getters);
  }

  /**
   * Converts from a CompositeData to an instance of the targetClass Various subclasses override its
   * functionality.
   */
  protected abstract static class CompositeBuilder {
    CompositeBuilder(Class targetClass, String[] itemNames) {
      this.targetClass = targetClass;
      this.itemNames = itemNames;
    }

    Class getTargetClass() {
      return targetClass;
    }

    String[] getItemNames() {
      return itemNames;
    }

    /**
     * If the subclass should be appropriate but there is a problem, then the method throws
     * InvalidObjectException.
     *
     * @return If the subclass is appropriate for targetClass, then the method returns null. If the
     *         subclass is not appropriate, then the method returns an explanation of why not.
     */
    abstract String applicable(Method[] getters) throws InvalidObjectException;

    /**
     *
     * @return possible cause if target class is not applicable
     */
    Throwable possibleCause() {
      return null;
    }

    /**
     * @return Actual java types from the composite type
     */
    abstract Object fromCompositeData(CompositeData cd, String[] itemNames,
        OpenTypeConverter[] converters) throws InvalidObjectException;

    private final Class targetClass;
    private final String[] itemNames;
  }

  /**
   * Builder if the target class has a method "public static from(CompositeData)"
   */
  protected static class CompositeBuilderViaFrom extends CompositeBuilder {

    CompositeBuilderViaFrom(Class targetClass, String[] itemNames) {
      super(targetClass, itemNames);
    }

    @Override
    String applicable(Method[] getters) throws InvalidObjectException {
      // See if it has a method "T from(CompositeData)"
      // as is conventional for a CompositeDataView
      Class targetClass = getTargetClass();
      try {
        Method fromMethod = targetClass.getMethod("from", new Class[] {CompositeData.class});

        if (!Modifier.isStatic(fromMethod.getModifiers())) {
          final String msg = "Method from(CompositeData) is not static";
          throw new InvalidObjectException(msg);
        }

        if (fromMethod.getReturnType() != getTargetClass()) {
          final String msg = "Method from(CompositeData) returns "
              + typeName(fromMethod.getReturnType()) + " not " + typeName(targetClass);
          throw new InvalidObjectException(msg);
        }

        this.fromMethod = fromMethod;
        return null;
      } catch (InvalidObjectException e) {
        throw e;
      } catch (Exception e) {
        return "no method from(CompositeData)";
      }
    }

    @Override
    Object fromCompositeData(CompositeData cd, String[] itemNames, OpenTypeConverter[] converters)
        throws InvalidObjectException {
      try {
        return fromMethod.invoke(null, cd);
      } catch (Exception e) {
        final String msg = "Failed to invoke from(CompositeData)";
        throw invalidObjectException(msg, e);
      }
    }

    private Method fromMethod;
  }

  /**
   * This builder never actually returns success. It simply serves to check whether the other
   * builders in the same group have any chance of success. If any getter in the targetClass returns
   * a type that we don't know how to reconstruct, then we will not be able to make a builder, and
   * there is no point in repeating the error about the problematic getter as many times as there
   * are candidate builders. Instead, the "applicable" method will return an explanatory string, and
   * the other builders will be skipped. If all the getters are OK, then the "applicable" method
   * will return an empty string and the other builders will be tried.
   */
  protected static class CompositeBuilderCheckGetters extends CompositeBuilder {
    CompositeBuilderCheckGetters(Class targetClass, String[] itemNames,
        OpenTypeConverter[] getterConverters) {
      super(targetClass, itemNames);
      this.getterConverters = getterConverters;
    }

    @Override
    String applicable(Method[] getters) {
      for (int i = 0; i < getters.length; i++) {
        try {
          getterConverters[i].checkReconstructible();
        } catch (InvalidObjectException e) {
          possibleCause = e;
          return "method " + getters[i].getName() + " returns type "
              + "that cannot be mapped back from OpenData";
        }
      }
      return "";
    }

    @Override
    Throwable possibleCause() {
      return possibleCause;
    }

    @Override
    Object fromCompositeData(CompositeData cd, String[] itemNames, OpenTypeConverter[] converters) {
      throw new Error();
    }

    private final OpenTypeConverter[] getterConverters;
    private Throwable possibleCause;
  }

  /**
   * Builder if the target class has a setter for every getter
   */
  protected static class CompositeBuilderViaSetters extends CompositeBuilder {

    CompositeBuilderViaSetters(Class targetClass, String[] itemNames) {
      super(targetClass, itemNames);
    }

    @Override
    String applicable(Method[] getters) {
      try {
        Constructor c = getTargetClass().getConstructor((Class[]) null);
      } catch (Exception e) {
        return "does not have a public no-arg constructor";
      }

      Method[] setters = new Method[getters.length];
      for (int i = 0; i < getters.length; i++) {
        Method getter = getters[i];
        Class returnType = getter.getReturnType();
        String name = propertyName(getter);
        String setterName = "set" + name;
        Method setter;
        try {
          setter = getTargetClass().getMethod(setterName, returnType);
          if (setter.getReturnType() != void.class)
            throw new Exception();
        } catch (Exception e) {
          return "not all getters have corresponding setters " + "(" + getter + ")";
        }
        setters[i] = setter;
      }
      this.setters = setters;
      return null;
    }

    @Override
    Object fromCompositeData(CompositeData cd, String[] itemNames, OpenTypeConverter[] converters)
        throws InvalidObjectException {
      Object o;
      try {
        o = getTargetClass().newInstance();
        for (int i = 0; i < itemNames.length; i++) {
          if (cd.containsKey(itemNames[i])) {
            Object openItem = cd.get(itemNames[i]);
            Object javaItem = converters[i].fromOpenValue(openItem);
            setters[i].invoke(o, javaItem);
          }
        }
      } catch (Exception e) {
        throw invalidObjectException(e);
      }
      return o;
    }

    private Method[] setters;
  }

  /**
   * Builder if the target class has a constructor that is annotated with @ConstructorProperties so
   * we can derive the corresponding getters.
   */
  protected static class CompositeBuilderViaConstructor extends CompositeBuilder {

    CompositeBuilderViaConstructor(Class targetClass, String[] itemNames) {
      super(targetClass, itemNames);
    }

    @Override
    String applicable(Method[] getters) throws InvalidObjectException {

      final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;

      Class targetClass = getTargetClass();
      Constructor[] constrs = targetClass.getConstructors();

      List<Constructor> annotatedConstrList = OpenTypeUtil.newList();
      for (Constructor constr : constrs) {
        if (Modifier.isPublic(constr.getModifiers())
            && constr.getAnnotation(propertyNamesClass) != null)
          annotatedConstrList.add(constr);
      }

      if (annotatedConstrList.isEmpty())
        return "no constructor has @ConstructorProperties annotation";

      annotatedConstructors = OpenTypeUtil.newList();

      Map<String, Integer> getterMap = OpenTypeUtil.newMap();
      String[] itemNames = getItemNames();
      for (int i = 0; i < itemNames.length; i++)
        getterMap.put(itemNames[i], i);

      Set<BitSet> getterIndexSets = OpenTypeUtil.newSet();
      for (Constructor constr : annotatedConstrList) {
        String[] propertyNames =
            ((ConstructorProperties) constr.getAnnotation(propertyNamesClass)).value();

        Type[] paramTypes = constr.getGenericParameterTypes();
        if (paramTypes.length != propertyNames.length) {
          final String msg = "Number of constructor params does not match "
              + "@ConstructorProperties annotation: " + constr;
          throw new InvalidObjectException(msg);
        }

        for (int i = 0; i < paramTypes.length; i++)
          paramTypes[i] = fixType(paramTypes[i]);

        int[] paramIndexes = new int[getters.length];
        for (int i = 0; i < getters.length; i++)
          paramIndexes[i] = -1;
        BitSet present = new BitSet();

        for (int i = 0; i < propertyNames.length; i++) {
          String propertyName = propertyNames[i];
          if (!getterMap.containsKey(propertyName)) {
            String msg = "@ConstructorProperties includes name " + propertyName
                + " which does not correspond to a property";
            for (String getterName : getterMap.keySet()) {
              if (getterName.equalsIgnoreCase(propertyName)) {
                msg += " (differs only in case from property " + getterName + ")";
              }
            }
            msg += ": " + constr;
            throw new InvalidObjectException(msg);
          }
          int getterIndex = getterMap.get(propertyName);
          paramIndexes[getterIndex] = i;
          if (present.get(getterIndex)) {
            final String msg = "@ConstructorProperties contains property " + propertyName
                + " more than once: " + constr;
            throw new InvalidObjectException(msg);
          }
          present.set(getterIndex);
          Method getter = getters[getterIndex];
          Type propertyType = getter.getGenericReturnType();
          if (!propertyType.equals(paramTypes[i])) {
            final String msg = "@ConstructorProperties gives property " + propertyName + " of type "
                + propertyType + " for parameter " + " of type " + paramTypes[i] + ": " + constr;
            throw new InvalidObjectException(msg);
          }
        }

        if (!getterIndexSets.add(present)) {
          final String msg = "More than one constructor has a @ConstructorProperties "
              + "annotation with this set of names: " + Arrays.toString(propertyNames);
          throw new InvalidObjectException(msg);
        }

        Constr c = new Constr(constr, paramIndexes, present);
        annotatedConstructors.add(c);
      }

      for (BitSet a : getterIndexSets) {
        boolean seen = false;
        for (BitSet b : getterIndexSets) {
          if (a == b)
            seen = true;
          else if (seen) {
            BitSet u = new BitSet();
            u.or(a);
            u.or(b);
            if (!getterIndexSets.contains(u)) {
              Set<String> names = new TreeSet<String>();
              for (int i = u.nextSetBit(0); i >= 0; i = u.nextSetBit(i + 1))
                names.add(itemNames[i]);
              final String msg = "Constructors with @ConstructorProperties annotation "
                  + " would be ambiguous for these items: " + names;
              throw new InvalidObjectException(msg);
            }
          }
        }
      }

      return null;
    }

    @Override
    Object fromCompositeData(CompositeData cd, String[] itemNames, OpenTypeConverter[] converters)
        throws InvalidObjectException {

      CompositeType ct = cd.getCompositeType();
      BitSet present = new BitSet();
      for (int i = 0; i < itemNames.length; i++) {
        if (ct.getType(itemNames[i]) != null)
          present.set(i);
      }

      Constr max = null;
      for (Constr constr : annotatedConstructors) {
        if (subset(constr.presentParams, present)
            && (max == null || subset(max.presentParams, constr.presentParams)))
          max = constr;
      }

      if (max == null) {
        final String msg = "No constructor has a @ConstructorProperties for this set of "
            + "items: " + ct.keySet();
        throw new InvalidObjectException(msg);
      }

      Object[] params = new Object[max.presentParams.cardinality()];
      for (int i = 0; i < itemNames.length; i++) {
        if (!max.presentParams.get(i))
          continue;
        Object openItem = cd.get(itemNames[i]);
        Object javaItem = converters[i].fromOpenValue(openItem);
        int index = max.paramIndexes[i];
        if (index >= 0)
          params[index] = javaItem;
      }

      try {
        return max.constructor.newInstance(params);
      } catch (Exception e) {
        final String msg = "Exception constructing " + getTargetClass().getName();
        throw invalidObjectException(msg, e);
      }
    }

    private static boolean subset(BitSet sub, BitSet sup) {
      BitSet subcopy = (BitSet) sub.clone();
      subcopy.andNot(sup);
      return subcopy.isEmpty();
    }

    private static class Constr {
      final Constructor constructor;
      final int[] paramIndexes;
      final BitSet presentParams;

      Constr(Constructor constructor, int[] paramIndexes, BitSet presentParams) {
        this.constructor = constructor;
        this.paramIndexes = paramIndexes;
        this.presentParams = presentParams;
      }
    }

    private List<Constr> annotatedConstructors;
  }

  /**
   * Builder if the target class is an interface and contains no methods other than getters. Then we
   * can make an instance using a dynamic proxy that forwards the getters to the source
   * CompositeData
   */
  protected static class CompositeBuilderViaProxy extends CompositeBuilder {

    CompositeBuilderViaProxy(Class targetClass, String[] itemNames) {
      super(targetClass, itemNames);
    }

    @Override
    String applicable(Method[] getters) {
      Class targetClass = getTargetClass();
      if (!targetClass.isInterface())
        return "not an interface";
      Set<Method> methods = OpenTypeUtil.newSet(Arrays.asList(targetClass.getMethods()));
      methods.removeAll(Arrays.asList(getters));

      String bad = null;
      for (Method m : methods) {
        String mname = m.getName();
        Class[] mparams = m.getParameterTypes();
        try {
          Method om = Object.class.getMethod(mname, mparams);
          if (!Modifier.isPublic(om.getModifiers()))
            bad = mname;
        } catch (NoSuchMethodException e) {
          bad = mname;
        }

      }
      if (bad != null)
        return "contains methods other than getters (" + bad + ")";
      return null;
    }

    @Override
    Object fromCompositeData(CompositeData cd, String[] itemNames, OpenTypeConverter[] converters) {
      final Class targetClass = getTargetClass();
      return Proxy.newProxyInstance(targetClass.getClassLoader(), new Class[] {targetClass},
          new CompositeDataInvocationHandler(cd));
    }
  }

  static InvalidObjectException invalidObjectException(String msg, Throwable cause) {
    return new InvalidObjectException(msg);
  }

  static InvalidObjectException invalidObjectException(Throwable cause) {
    return invalidObjectException(cause.getMessage(), cause);
  }

  static OpenDataException openDataException(String msg, Throwable cause) {
    return new OpenDataException(msg);
  }

  static OpenDataException openDataException(Throwable cause) {
    return openDataException(cause.getMessage(), cause);
  }

  static void mustBeComparable(Class collection, Type element) throws OpenDataException {
    if (!(element instanceof Class) || !Comparable.class.isAssignableFrom((Class<?>) element)) {
      final String msg = "Parameter class " + element + " of " + collection.getName()
          + " does not implement " + Comparable.class.getName();
      throw new OpenDataException(msg);
    }
  }

  public static String propertyName(Method m) {
    String rest = null;
    String name = m.getName();
    if (name.startsWith("get"))
      rest = name.substring(3);
    else if (name.startsWith("is") && m.getReturnType() == boolean.class)
      rest = name.substring(2);
    if (rest == null || rest.length() == 0 || m.getParameterTypes().length > 0
        || m.getReturnType() == void.class || name.equals("getClass"))
      return null;
    return rest;
  }

  protected static String typeName(Type t) {
    if (t instanceof Class<?>) {
      Class<?> c = (Class<?>) t;
      if (c.isArray())
        return typeName(c.getComponentType()) + "[]";
      else
        return c.getName();
    }
    return t.toString();
  }

  private static Type fixType(Type t) {
    if (!(t instanceof GenericArrayType))
      return t;
    GenericArrayType gat = (GenericArrayType) t;
    Type ultimate = ultimateComponentType(gat);
    if (!(ultimate instanceof Class<?>))
      return t;
    Class<?> component = (Class<?>) fixType(gat.getGenericComponentType());
    return Array.newInstance(component, 0).getClass();
  }

  private static Type ultimateComponentType(GenericArrayType gat) {
    Type component = gat.getGenericComponentType();
    if (component instanceof GenericArrayType)
      return ultimateComponentType((GenericArrayType) component);
    else
      return component;
  }

}
