private void inspectExtension(ISchema schema, IPluginParent parent, IFile file) {
    IPluginObject[] children = parent.getChildren();

    if (parent instanceof PluginElementNode && parent.getParent() instanceof PluginElementNode) {
      // check if this node corresponds to a Java type attribute which would have been defined has
      // an element
      PluginElementNode node = (PluginElementNode) parent;
      PluginElementNode parentNode = (PluginElementNode) parent.getParent();
      ISchemaElement schemaElement = schema.findElement(parentNode.getName());
      if (schemaElement != null) {
        ISchemaAttribute attInfo = schemaElement.getAttribute(node.getName());
        if (attInfo != null && attInfo.getKind() == IMetaAttribute.JAVA)
          checkMatch(node.getAttribute("class"), file); // $NON-NLS-1$
      }
    }

    for (int i = 0; i < children.length; i++) {
      IPluginElement child = (IPluginElement) children[i];
      ISchemaElement schemaElement = schema.findElement(child.getName());
      if (schemaElement != null) {
        IPluginAttribute[] attributes = child.getAttributes();
        for (int j = 0; j < attributes.length; j++) {
          IPluginAttribute attr = attributes[j];
          ISchemaAttribute attInfo = schemaElement.getAttribute(attr.getName());
          if (attInfo != null
              && attInfo.getKind() == IMetaAttribute.JAVA
              && attr instanceof IDocumentAttributeNode) checkMatch(attr, file);
        }
      }
      inspectExtension(schema, child, file);
    }
  }
  private void validateExtensionAttribute(Element element, Attr attr, ISchemaAttribute attInfo) {
    ISchemaSimpleType type = attInfo.getType();

    int kind = attInfo.getKind();
    if (kind == IMetaAttribute.JAVA) {
      validateJavaAttribute(element, attr);
    } else if (kind == IMetaAttribute.RESOURCE) {
      validateResourceAttribute(element, attr);
    } else if (kind == IMetaAttribute.IDENTIFIER) {
      validateIdentifierAttribute(element, attr, attInfo);
    } else if (kind == IMetaAttribute.STRING) {
      ISchemaRestriction restriction = type.getRestriction();
      if (restriction != null) {
        validateRestrictionAttribute(element, attr, restriction);
      }
    } else if (type.getName().equals("boolean")) { // $NON-NLS-1$
      validateBoolean(element, attr);
    }

    validateTranslatableString(element, attr, attInfo.isTranslatable());

    if (attInfo.isDeprecated()) {
      reportDeprecatedAttribute(element, attr);
    }
  }
 private void validateIdentifierAttribute(Element element, Attr attr, ISchemaAttribute attInfo) {
   int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_UNKNOWN_IDENTIFIER);
   if (severity != CompilerFlags.IGNORE) {
     String value = attr.getValue();
     String basedOn = attInfo.getBasedOn();
     // only validate if we have a valid value and basedOn value
     if (value != null && basedOn != null && value.length() > 0 && basedOn.length() > 0) {
       Map attributes = PDESchemaHelper.getValidAttributes(attInfo);
       if (!attributes.containsKey(value)) { // report error if we are missing something
         report(
             NLS.bind(
                 MDECoreMessages.ExtensionsErrorReporter_unknownIdentifier,
                 (new String[] {attr.getValue(), attr.getName()})),
             getLine(element, attr.getName()),
             severity,
             MDEMarkerFactory.CAT_OTHER);
       }
     }
   }
 }
  private void validateRequiredExtensionAttributes(Element element, ISchemaElement schemaElement) {
    int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_NO_REQUIRED_ATT);
    if (severity == CompilerFlags.IGNORE) return;

    ISchemaAttribute[] attInfos = schemaElement.getAttributes();
    for (int i = 0; i < attInfos.length; i++) {
      ISchemaAttribute attInfo = attInfos[i];
      if (attInfo.getUse() == ISchemaAttribute.REQUIRED) {
        boolean found = element.getAttributeNode(attInfo.getName()) != null;
        if (!found && attInfo.getKind() == IMetaAttribute.JAVA) {
          NodeList children = element.getChildNodes();
          for (int j = 0; j < children.getLength(); j++) {
            if (attInfo.getName().equals(children.item(j).getNodeName())) {
              found = true;
              break;
            }
          }
        }
        if (!found) {
          reportMissingRequiredAttribute(element, attInfo.getName(), severity);
        }
      }
    }
  }
  protected void validateElement(Element element, ISchema schema, boolean isTopLevel) {
    String elementName = element.getNodeName();
    ISchemaElement schemaElement = schema.findElement(elementName);

    // Validate element occurrence violations
    if ((schemaElement != null) && (schemaElement.getType() instanceof ISchemaComplexType)) {
      validateMaxElementMult(element, schemaElement);
      validateMinElementMult(element, schemaElement);
    }

    ISchemaElement parentSchema = null;
    if (!"extension".equals(elementName)) { // $NON-NLS-1$
      Node parent = element.getParentNode();
      parentSchema = schema.findElement(parent.getNodeName());
    } else if (isTopLevel == false) {
      // This is an "extension" element; but, not a top level one.
      // It is nested within another "extension" element somewhere
      // e.g. "extension" element is a child element of another element
      // that is not a "plugin" elment
      // element
      // Report illegal element
      int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_UNKNOWN_ELEMENT);
      reportIllegalElement(element, severity);
      return;
    }

    if (parentSchema != null) {
      int severity = CompilerFlags.getFlag(fProject, CompilerFlags.P_UNKNOWN_ELEMENT);
      if (severity != CompilerFlags.IGNORE) {
        HashSet allowedElements = new HashSet();
        computeAllowedElements(parentSchema.getType(), allowedElements);
        if (!allowedElements.contains(elementName)) {
          reportIllegalElement(element, severity);
          return;
        }
      }
    }
    if (schemaElement == null && parentSchema != null) {
      ISchemaAttribute attr = parentSchema.getAttribute(elementName);
      if (attr != null && attr.getKind() == IMetaAttribute.JAVA) {
        if (attr.isDeprecated())
          reportDeprecatedAttribute(element, element.getAttributeNode("class")); // $NON-NLS-1$
        validateJavaAttribute(element, element.getAttributeNode("class")); // $NON-NLS-1$			
      }
    } else {
      if (schemaElement != null) {
        validateRequiredExtensionAttributes(element, schemaElement);
        validateExistingExtensionAttributes(element, element.getAttributes(), schemaElement);
        validateInternalExtensionAttribute(element, schemaElement);
        if (schemaElement.isDeprecated()) {
          if (schemaElement instanceof ISchemaRootElement)
            reportDeprecatedRootElement(
                element, ((ISchemaRootElement) schemaElement).getDeprecatedSuggestion());
          else reportDeprecatedElement(element);
        }
        if (schemaElement.hasTranslatableContent()) validateTranslatableElementContent(element);
        // Bug 213457 - look up elements based on the schema in which the parent is found
        schema = schemaElement.getSchema();
      }
      NodeList children = element.getChildNodes();
      for (int i = 0; i < children.getLength(); i++) {
        validateElement((Element) children.item(i), schema, false);
      }
    }
  }