/* (non-Javadoc)
   * @see org.jibx.binding.model.ElementBase#prevalidate(org.jibx.binding.model.ValidationContext)
   */
  public void prevalidate(ValidationContext vctx) {

    // first process attributes and check for errors
    super.prevalidate(vctx);
    if (!vctx.isSkipped(this)) {

      // check for ignored attributes
      if (isAllowRepeats()) {
        vctx.addWarning("'allow-repeats' attribute ignored on collection");
      }
      if (isChoice()) {
        vctx.addWarning("'choice' attribute ignored on collection");
      }

      // get the actual collection type and item type
      IClass clas = getType();
      if (clas == null) {
        clas = vctx.getContextObject().getObjectType();
      }
      String tname = m_itemTypeName;
      if (tname == null) {
        String ctype = clas.getName();
        if (ctype.endsWith("[]")) {
          tname = ctype.substring(0, ctype.length() - 2);
        } else {
          tname = "java.lang.Object";
        }
      }
      m_itemTypeClass = vctx.getClassInfo(tname);
      if (m_itemTypeClass == null) {
        vctx.addFatal("Can't find class " + tname);
      }

      // handle input and output bindings separately
      if (vctx.isInBinding()) {

        // check store techniques
        String sname = m_storeMethodName;
        String aname = m_addMethodName;
        if (sname != null && aname != null) {
          vctx.addWarning("Both store-method and add-method " + "supplied; using add-method");
          sname = null;
        }

        // set defaults based on collection type if needed
        if (sname == null && aname == null) {
          if (clas.isSuperclass("java.util.ArrayList")
              || clas.isSuperclass("java.util.Vector")
              || clas.isImplements("Ljava/util/Collection;")) {
            aname = "add";
          } else if (!clas.getName().endsWith("[]")) {
            vctx.addError("Need store-method or add-method for " + "input binding");
          }
        }

        // find the actual method information
        if (sname != null) {
          m_storeMethodItem = clas.getBestMethod(sname, null, new String[] {"int", tname});
          if (m_storeMethodItem == null) {
            vctx.addError("store-method " + sname + " not found in class " + clas.getName());
          }
        }
        if (aname != null) {
          m_addMethodItem = clas.getBestMethod(aname, null, new String[] {tname});
          if (m_addMethodItem == null) {
            vctx.addError("add-method " + aname + " not found in class " + clas.getName());
          }
        }
      }
      if (vctx.isOutBinding()) {

        // precheck load techniques
        String lname = m_loadMethodName;
        String sname = m_sizeMethodName;
        String iname = m_iterMethodName;
        if (lname == null) {
          if (sname != null) {
            vctx.addWarning("size-method requires load-method; " + "ignoring supplied size-method");
            sname = null;
          }
        } else {
          if (sname == null) {
            vctx.addWarning("load-method requires " + "size-method; ignoring supplied load-method");
            lname = null;
          } else {
            if (iname != null) {
              vctx.addWarning("Both load-method and " + "iter-method supplied; using load-method");
              iname = null;
            }
          }
        }

        // set defaults based on collection type if needed
        if (lname == null && iname == null) {
          if (clas.isSuperclass("java.util.ArrayList") || clas.isSuperclass("java.util.Vector")) {
            lname = "get";
            sname = "size";
          } else if (clas.isImplements("Ljava/util/Collection;")) {
            iname = "iterator";
          }
        }

        // postcheck load techniques with defaults set
        if (lname == null) {
          if (iname == null && !clas.getName().endsWith("[]")) {
            vctx.addError(
                "Need load-method and size-method, or " + "iter-method, for output binding");
          }
        } else {
          if (sname == null && iname == null) {
            vctx.addError(
                "Need load-method and size-method," + " or iter-method, for output binding");
          }
        }

        // find the actual method information
        if (lname != null) {
          m_loadMethodItem = clas.getBestMethod(lname, tname, new String[] {"int"});
          if (m_loadMethodItem == null) {
            vctx.addError("load-method " + lname + " not found in class " + clas.getName());
          }
        }
        if (iname != null) {
          m_iterMethodItem = clas.getBestMethod(iname, "java.util.Iterator", new String[0]);
          if (m_iterMethodItem == null) {
            vctx.addError("iter-method " + iname + " not found in class " + clas.getName());
          }
        }
      }
    }
  }