/**
   * Check children of unordered collection for consistency. In an input binding each child element
   * must define a unique qualified name. In an output binding each child element must define a
   * unique type or supply a test method to allow checking when that element should be generated for
   * an object.
   *
   * @param vctx validation context
   * @param children list of child components
   */
  private void checkUnorderedChildren(ValidationContext vctx, ArrayList children) {
    HashMap typemap = new HashMap();
    HashMap namemap = new HashMap();
    for (int i = 0; i < children.size(); i++) {
      ElementBase child = (ElementBase) children.get(i);
      if (child instanceof IComponent && !vctx.isSkipped(child)) {
        IComponent comp = (IComponent) child;
        if (vctx.isInBinding()) {

          // make sure name supplied for unmarshalling
          if (!comp.hasName()) {
            vctx.addFatal(
                "Child components of collection must " + "define element name for unmarshalling",
                comp);
          }

          // names must be distinct in input binding
          String name = comp.getName();
          String uri = comp.getUri();
          if (uri == null) {
            uri = "";
          }
          Object value = namemap.get(name);
          if (value == null) {

            // first instance of name, store directly
            namemap.put(name, comp);

          } else if (value instanceof HashMap) {

            // multiple instances already found, match on URI
            HashMap urimap = (HashMap) value;
            if (urimap.get(uri) != null) {
              vctx.addError("Duplicate names are not " + "allowed in unordered collection", comp);
            } else {
              urimap.put(uri, comp);
            }

          } else {

            // duplicate name, check URI
            IComponent match = (IComponent) value;
            if ((uri == null && match.getUri() == null)
                || (uri != null && uri.equals(match.getUri()))) {
              vctx.addError("Duplicate names are not " + "allowed in unordered collection", comp);
            } else {

              // multiple namespaces for same name, use map
              HashMap urimap = new HashMap();
              urimap.put(uri, comp);
              String muri = match.getUri();
              if (muri == null) {
                muri = "";
              }
              urimap.put(muri, match);
              namemap.put(name, urimap);
            }
          }
        }
        if (vctx.isOutBinding()) {

          // just accumulate lists of each type in this loop
          String type = comp.getType().getName();
          Object value = typemap.get(type);
          if (value == null) {
            typemap.put(type, comp);
          } else if (value instanceof ArrayList) {
            ArrayList types = (ArrayList) value;
            types.add(comp);
          } else {
            ArrayList types = new ArrayList();
            types.add(value);
            types.add(comp);
            typemap.put(type, types);
          }
        }
      }
    }

    // check for duplicate type usage in output binding
    for (Iterator iter = typemap.values().iterator(); iter.hasNext(); ) {
      Object value = iter.next();
      if (value instanceof ArrayList) {

        // multiple instances of type, make sure we can distinguish
        ArrayList types = (ArrayList) value;
        for (int i = 0; i < types.size(); i++) {
          Object child = types.get(i);
          if (child instanceof ValueElement) {
            ValueElement vel = (ValueElement) child;
            if (vel.getTest() == null) {
              vctx.addError(
                  "test-method needed for "
                      + "multiple instances of same type in "
                      + "unordered collection",
                  vel);
            }
          } else if (child instanceof StructureElementBase) {
            StructureElementBase sel = (StructureElementBase) child;
            if (sel.getTest() == null) {
              vctx.addError(
                  "test-method needed for "
                      + "multiple instances of same type in "
                      + "unordered collection",
                  sel);
            }
          }
        }
      }
    }
  }