/**
   * Compares all SubPackage objects of two Package objects.
   *
   * @param xPackage Package from the Schema, of which all Packages should be compared.
   * @param gPackage Package from the SchemaGraph, of which all Packages should be compared.
   */
  private final void compareAllSubPackages(
      de.uni_koblenz.jgralab.schema.Package xPackage, Package gPackage) {
    // Map of SubPackages is cloned
    Map<String, de.uni_koblenz.jgralab.schema.Package> subPackages =
        new HashMap<String, de.uni_koblenz.jgralab.schema.Package>(xPackage.getSubPackages());

    // Loop over all ContainsSubPackage edges
    for (ContainsSubPackage containsSubPackage :
        gPackage.getContainsSubPackageIncidences(OUTGOING)) {

      assertTrue(
          "Omega should be an instance of \"Package\".",
          containsSubPackage.getOmega() instanceof Package);
      Package gSubPackage = containsSubPackage.getOmega();
      de.uni_koblenz.jgralab.schema.Package subpackage =
          schema.getPackage(gSubPackage.get_qualifiedName());

      // The references shouldn't be null
      assertTrue("There is no corresponding Package in Schema.", subpackage != null);
      assertTrue(
          "There is no corresponding Package in Schema.",
          subPackages.containsKey(subpackage.getSimpleName()));

      // Gets, removes and compares both Package objects with each other
      comparePackage(subPackages.remove(subpackage.getSimpleName()), gSubPackage);
    }
    // There shouldn't be any Package left in the map
    assertTrue(
        "There are more Packages in the Schema then in the SchemaGraph.", subPackages.isEmpty());
  }
  /**
   * Compares all Domain objects of two Package objects.
   *
   * @param xPackage Package from the Schema, of which all Domain objects are compared.
   * @param gPackage Package from the SchemaGraph, of which all Domain objects are compared.
   */
  private final void compareAllDomains(
      de.uni_koblenz.jgralab.schema.Package xPackage, Package gPackage) {
    // Gets all Domains (clone of the map) of a Schema
    Map<String, de.uni_koblenz.jgralab.schema.Domain> domains =
        new HashMap<String, de.uni_koblenz.jgralab.schema.Domain>(xPackage.getDomains());

    // Loop over all ContainsDomain edges
    for (ContainsDomain containsDomain : gPackage.getContainsDomainIncidences(OUTGOING)) {
      // Checking if the reference is right
      Domain gDomain = retrieveDomain(containsDomain);

      // Gets the simpleName for querying a the right domain
      String simpleName = schema.getDomain(gDomain.get_qualifiedName()).getSimpleName();

      // Gets, removes and compares at the same time both Domain objects.
      de.uni_koblenz.jgralab.schema.Domain domain = domains.remove(simpleName);
      assertFalse(
          "There is corresponding Domain of name \"" + simpleName + "\" in the Schema.",
          domain == null);

      compareDomain(domain, gDomain);
    }

    clearBasicDomains(domains);

    // After all this, the Domain map should be empty
    assertTrue("There are more Domains in the Schema then in the SchemaGraph.", domains.isEmpty());
  }
  /**
   * Compares all GraphElementClass objects in two Packages.
   *
   * @param xPackage Package from the Schema, of which all GraphElementClass objects should be
   *     compared.
   * @param gPackage Package from the SchemaGraph, of which all GraphElementClass objects should be
   *     compared.
   */
  private final void compareAllGraphElementClasses(
      de.uni_koblenz.jgralab.schema.Package xPackage, Package gPackage) {
    // Gets a cloned map of all VertexClass and EdgeClass objects
    Map<String, de.uni_koblenz.jgralab.schema.VertexClass> vertexClasses =
        new HashMap<String, de.uni_koblenz.jgralab.schema.VertexClass>(xPackage.getVertexClasses());
    Map<String, de.uni_koblenz.jgralab.schema.EdgeClass> edgeClasses =
        new HashMap<String, de.uni_koblenz.jgralab.schema.EdgeClass>(xPackage.getEdgeClasses());

    // This loop prevents the comparison of internal structures
    for (Iterator<Entry<String, de.uni_koblenz.jgralab.schema.VertexClass>> it =
            vertexClasses.entrySet().iterator();
        it.hasNext(); ) {
      if (it.next().getValue().isInternal()) {
        it.remove();
      }
    }

    // This loop prevents the comparison of internal structures
    for (Iterator<Entry<String, de.uni_koblenz.jgralab.schema.EdgeClass>> it =
            edgeClasses.entrySet().iterator();
        it.hasNext(); ) {
      if (it.next().getValue().isInternal()) {
        it.remove();
      }
    }

    // Loop over all ContainsGraphElementClass edges
    for (ContainsGraphElementClass containsGraphElementClass :
        gPackage.getContainsGraphElementClassIncidences(OUTGOING)) {

      // The referenced object should be at least a FraphElementClass
      assertTrue(
          "Omega should be an instance of GraphElementClass.",
          containsGraphElementClass.getOmega() instanceof GraphElementClass);

      Vertex omega = containsGraphElementClass.getOmega();
      assert omega != null;

      // Distinguishing between VertexClass and EdgeClass
      if (omega instanceof VertexClass) {
        VertexClass gVertexClass = (VertexClass) omega;
        // Retrieving the simple name of the corresponding VertexClass
        String simpleName =
            schema.getAttributedElementClass(gVertexClass.get_qualifiedName()).getSimpleName();
        // Queries, removes and compares at the same time two
        // VertexClass objects
        compareVertexClass(vertexClasses.remove(simpleName), gVertexClass);
      } else if (omega instanceof EdgeClass) {
        // The Same for the EdgeClass comparison
        EdgeClass gEdgeClass = (EdgeClass) omega;
        // Retrieving the simple name of the corresponding VertexClass
        String simpleName =
            schema.getAttributedElementClass(gEdgeClass.get_qualifiedName()).getSimpleName();
        // Queries, removes and compares at the same time two EdgeClass
        // objects
        compareEdgeClass(edgeClasses.remove(simpleName), gEdgeClass);
      } else {
        throw new RuntimeException("Unexpected type " + omega);
      }
    }

    // Both maps should be empty.

    assertTrue(
        "There are more VertexClasses in Schema then in the SchemaGraph.", vertexClasses.isEmpty());
    for (de.uni_koblenz.jgralab.schema.EdgeClass e : edgeClasses.values()) {
      System.out.println(e.getQualifiedName());
    }
    assertTrue(
        "There are more EdgeClasses in Schema then in the SchemaGraph.", edgeClasses.isEmpty());
  }