private CompositeDataSupport(SortedMap<String, Object> items, CompositeType compositeType)
      throws OpenDataException {

    // Check compositeType is not null
    //
    if (compositeType == null) {
      throw new IllegalArgumentException("Argument compositeType cannot be null.");
    }

    // item names defined in compositeType:
    Set<String> namesFromType = compositeType.keySet();
    Set<String> namesFromItems = items.keySet();

    // This is just a comparison, but we do it this way for a better
    // exception message.
    if (!namesFromType.equals(namesFromItems)) {
      Set<String> extraFromType = new TreeSet<String>(namesFromType);
      extraFromType.removeAll(namesFromItems);
      Set<String> extraFromItems = new TreeSet<String>(namesFromItems);
      extraFromItems.removeAll(namesFromType);
      if (!extraFromType.isEmpty() || !extraFromItems.isEmpty()) {
        throw new OpenDataException(
            "Item names do not match CompositeType: "
                + "names in items but not in CompositeType: "
                + extraFromItems
                + "; names in CompositeType but not in items: "
                + extraFromType);
      }
    }

    // Check each value, if not null, is of the open type defined for the
    // corresponding item
    for (String name : namesFromType) {
      Object value = items.get(name);
      if (value != null) {
        OpenType<?> itemType = compositeType.getType(name);
        if (!itemType.isValue(value)) {
          throw new OpenDataException(
              "Argument value of wrong type for item "
                  + name
                  + ": value "
                  + value
                  + ", type "
                  + itemType);
        }
      }
    }

    // Initialize internal fields: compositeType and contents
    //
    this.compositeType = compositeType;
    this.contents = items;
  }
  /**
   * Returns the value of the item whose name is <tt>key</tt>.
   *
   * @throws IllegalArgumentException if <tt>key</tt> is a null or empty String.
   * @throws InvalidKeyException if <tt>key</tt> is not an existing item name for this
   *     <tt>CompositeData</tt> instance.
   */
  public Object get(String key) {

    if ((key == null) || (key.trim().equals(""))) {
      throw new IllegalArgumentException("Argument key cannot be a null or empty String.");
    }
    if (!contents.containsKey(key.trim())) {
      throw new InvalidKeyException(
          "Argument key=\""
              + key.trim()
              + "\" is not an existing item name for this CompositeData instance.");
    }
    return contents.get(key.trim());
  }