void test() {
   testDir.mkdirs();
   compile(null, hierarchyKind.source);
   actionKind.doAction(this);
   DiagnosticChecker dc = new DiagnosticChecker();
   compile(dc, testKind.source);
   if (testKind.completionFailure(versionKind, actionKind, hierarchyKind) != dc.errorFound) {
     if (dc.errorFound) {
       error(
           "Unexpected completion failure"
               + "\nhierarhcyKind "
               + hierarchyKind
               + "\ntestKind "
               + testKind
               + "\nactionKind "
               + actionKind);
     } else {
       error(
           "Missing completion failure "
               + "\nhierarhcyKind "
               + hierarchyKind
               + "\ntestKind "
               + testKind
               + "\nactionKind "
               + actionKind);
     }
   }
 }
 public static void main(String[] args) throws Exception {
   String SCRATCH_DIR = System.getProperty("user.dir");
   JavaCompiler javacTool = ToolProvider.getSystemJavaCompiler();
   int n = 0;
   for (VersionKind versionKind : VersionKind.values()) {
     for (HierarchyKind hierarchyKind : HierarchyKind.values()) {
       for (TestKind testKind : TestKind.values()) {
         for (ActionKind actionKind : ActionKind.values()) {
           File testDir = new File(SCRATCH_DIR, "test" + n);
           new EagerInterfaceCompletionTest(
                   javacTool, testDir, versionKind, hierarchyKind, testKind, actionKind)
               .test();
           n++;
         }
       }
     }
   }
   if (nerrors > 0) {
     throw new AssertionError("Some errors have been detected");
   }
 }
  private void testAB1(TestKind kind, final Comparison comparison) {
    final List<Diff> differences = comparison.getDifferences();

    // We should have no less and no more than 5 differences
    // Was 6 with UML 4.0 but NamedElement::clientDependency has been made derived in UML 5.0
    assertEquals(5, differences.size());

    Predicate<? super Diff> addInterfaceRealizationDescription = null;
    Predicate<? super Diff> addClientInInterfaceRealizationDescription = null;
    Predicate<? super Diff> addSupplierInInterfaceRealizationDescription = null;
    Predicate<? super Diff> addContractInInterfaceRealizationDescription = null;

    if (kind.equals(TestKind.DELETE)) {
      addInterfaceRealizationDescription =
          removedFromReference("model.Class0", "substitution", "model.Class0.Substitution0");
      addClientInInterfaceRealizationDescription =
          removedFromReference("model.Class0.Substitution0", "client", "model.Class0");
      addSupplierInInterfaceRealizationDescription =
          removedFromReference("model.Class0.Substitution0", "supplier", "model.Class1");
      addContractInInterfaceRealizationDescription =
          changedReference("model.Class0.Substitution0", "contract", "model.Class1", null);
    } else {
      addInterfaceRealizationDescription =
          addedToReference(
              "model.Class0",
              "substitution", //$NON-NLS-1$
              "model.Class0.Substitution0");
      addClientInInterfaceRealizationDescription =
          addedToReference("model.Class0.Substitution0", "client", "model.Class0");
      addSupplierInInterfaceRealizationDescription =
          addedToReference("model.Class0.Substitution0", "supplier", "model.Class1");
      addContractInInterfaceRealizationDescription =
          changedReference("model.Class0.Substitution0", "contract", null, "model.Class1");
    }

    final Diff addInterfaceRealization =
        Iterators.find(differences.iterator(), addInterfaceRealizationDescription);
    final Diff addClientInInterfaceRealization =
        Iterators.find(differences.iterator(), addClientInInterfaceRealizationDescription);
    final Diff addSupplierInInterfaceRealization =
        Iterators.find(differences.iterator(), addSupplierInInterfaceRealizationDescription);
    final Diff addContractInInterfaceRealization =
        Iterators.find(differences.iterator(), addContractInInterfaceRealizationDescription);

    assertNotNull(addInterfaceRealization);
    assertNotNull(addClientInInterfaceRealization);
    assertNotNull(addSupplierInInterfaceRealization);
    assertNotNull(addContractInInterfaceRealization);

    // CHECK EXTENSION
    assertEquals(1, count(differences, instanceOf(DirectedRelationshipChange.class)));
    Diff addUMLDependency = null;
    if (kind.equals(TestKind.ADD)) {
      addUMLDependency =
          Iterators.find(
              differences.iterator(),
              and(instanceOf(DirectedRelationshipChange.class), ofKind(DifferenceKind.ADD)));
    } else {
      addUMLDependency =
          Iterators.find(
              differences.iterator(),
              and(instanceOf(DirectedRelationshipChange.class), ofKind(DifferenceKind.DELETE)));
    }
    assertNotNull(addUMLDependency);
    assertEquals(4, addUMLDependency.getRefinedBy().size());
    assertTrue(addUMLDependency.getRefinedBy().contains(addClientInInterfaceRealization));
    assertTrue(addUMLDependency.getRefinedBy().contains(addSupplierInInterfaceRealization));
    assertTrue(addUMLDependency.getRefinedBy().contains(addContractInInterfaceRealization));
    assertTrue(addUMLDependency.getRefinedBy().contains(addInterfaceRealization));

    // CHECK REQUIREMENT
    if (kind.equals(TestKind.ADD)) {
      assertEquals(1, addClientInInterfaceRealization.getRequires().size());
      assertTrue(addClientInInterfaceRealization.getRequires().contains(addInterfaceRealization));
      assertEquals(1, addSupplierInInterfaceRealization.getRequires().size());
      assertTrue(addSupplierInInterfaceRealization.getRequires().contains(addInterfaceRealization));
      assertEquals(1, addContractInInterfaceRealization.getRequires().size());
      assertTrue(addContractInInterfaceRealization.getRequires().contains(addInterfaceRealization));

      assertEquals(0, addInterfaceRealization.getRequires().size());
      assertEquals(0, addUMLDependency.getRequires().size());
    } else {
      assertEquals(0, addClientInInterfaceRealization.getRequires().size());
      assertEquals(0, addSupplierInInterfaceRealization.getRequires().size());
      assertEquals(0, addContractInInterfaceRealization.getRequires().size());

      assertEquals(3, addInterfaceRealization.getRequires().size());
      assertTrue(addInterfaceRealization.getRequires().contains(addClientInInterfaceRealization));
      assertTrue(addInterfaceRealization.getRequires().contains(addSupplierInInterfaceRealization));
      assertTrue(addInterfaceRealization.getRequires().contains(addContractInInterfaceRealization));

      assertEquals(0, addUMLDependency.getRequires().size());
    }

    // CHECK EQUIVALENCE
    assertEquals(0, comparison.getEquivalences().size());
    assertNull(addClientInInterfaceRealization.getEquivalence());

    testIntersections(comparison);
  }
  private void testAB1(TestKind kind, final Comparison comparison) {
    final List<Diff> differences = comparison.getDifferences();

    // We should have no less and no more than 10 differences
    assertEquals(10, differences.size());

    Predicate<? super Diff> addTimeConstraintDescription = null;
    Predicate<? super Diff> addTimeIntervalDescription = null;
    Predicate<? super Diff> addTimeExpressionMinDescription = null;
    Predicate<? super Diff> addTimeExpressionMaxDescription = null;
    Predicate<? super Diff> addMinValueDescription = null;
    Predicate<? super Diff> addMaxValueDescription = null;
    Predicate<? super Diff> addConstrainedElementInTimeConstraintDescription = null;
    Predicate<? super Diff> addMinInTimeIntervalDescription = null;
    Predicate<? super Diff> addMaxInTimeIntervalDescription = null;

    if (kind.equals(TestKind.DELETE)) {
      addTimeConstraintDescription = removed("model.interaction0.TimeConstraint0"); // $NON-NLS-1$
      addTimeIntervalDescription =
          removed("model.interaction0.TimeConstraint0.TimeInterval"); // $NON-NLS-1$
      addTimeExpressionMinDescription = removed("model.TimeIntervalMin0"); // $NON-NLS-1$
      addTimeExpressionMaxDescription = removed("model.TimeIntervalMax0");
      addMinValueDescription = removed("model.TimeIntervalMin0.min"); // $NON-NLS-1$
      addMaxValueDescription = removed("model.TimeIntervalMax0.max"); // $NON-NLS-1$
      addConstrainedElementInTimeConstraintDescription =
          removedFromReference(
              "model.interaction0.TimeConstraint0",
              "constrainedElement",
              "model.interaction0.Message0Send0");
      addMinInTimeIntervalDescription =
          changedReference(
              "model.interaction0.TimeConstraint0.TimeInterval",
              "min",
              "model.TimeIntervalMin0",
              null);
      addMaxInTimeIntervalDescription =
          changedReference(
              "model.interaction0.TimeConstraint0.TimeInterval",
              "max",
              "model.TimeIntervalMax0",
              null);
    } else {
      addTimeConstraintDescription = added("model.interaction0.TimeConstraint0"); // $NON-NLS-1$
      addTimeIntervalDescription =
          added("model.interaction0.TimeConstraint0.TimeInterval"); // $NON-NLS-1$
      addTimeExpressionMinDescription = added("model.TimeIntervalMin0"); // $NON-NLS-1$
      addTimeExpressionMaxDescription = added("model.TimeIntervalMax0");
      addMinValueDescription = added("model.TimeIntervalMin0.min"); // $NON-NLS-1$
      addMaxValueDescription = added("model.TimeIntervalMax0.max"); // $NON-NLS-1$
      addConstrainedElementInTimeConstraintDescription =
          addedToReference(
              "model.interaction0.TimeConstraint0",
              "constrainedElement",
              "model.interaction0.Message0Send0");
      addMinInTimeIntervalDescription =
          changedReference(
              "model.interaction0.TimeConstraint0.TimeInterval",
              "min",
              null,
              "model.TimeIntervalMin0");
      addMaxInTimeIntervalDescription =
          changedReference(
              "model.interaction0.TimeConstraint0.TimeInterval",
              "max",
              null,
              "model.TimeIntervalMax0");
    }

    final Diff addTimeConstraint =
        Iterators.find(differences.iterator(), addTimeConstraintDescription);
    final Diff addTimeInterval = Iterators.find(differences.iterator(), addTimeIntervalDescription);
    final Diff addTimeExpressionMin =
        Iterators.find(differences.iterator(), addTimeExpressionMinDescription);
    final Diff addTimeExpressionMax =
        Iterators.find(differences.iterator(), addTimeExpressionMaxDescription);
    final Diff addMinValue = Iterators.find(differences.iterator(), addMinValueDescription);
    final Diff addMaxValue = Iterators.find(differences.iterator(), addMaxValueDescription);
    final Diff addConstrainedElementInTimeConstraint =
        Iterators.find(differences.iterator(), addConstrainedElementInTimeConstraintDescription);
    final Diff addMinInTimeInterval =
        Iterators.find(differences.iterator(), addMinInTimeIntervalDescription);
    final Diff addMaxInTimeInterval =
        Iterators.find(differences.iterator(), addMaxInTimeIntervalDescription);

    assertNotNull(addTimeConstraint);
    assertNotNull(addTimeInterval);
    assertNotNull(addTimeExpressionMin);
    assertNotNull(addTimeExpressionMax);
    assertNotNull(addMinValue);
    assertNotNull(addMaxValue);
    assertNotNull(addConstrainedElementInTimeConstraint);
    assertNotNull(addMinInTimeInterval);
    assertNotNull(addMaxInTimeInterval);

    // CHECK EXTENSION
    assertEquals(1, count(differences, instanceOf(IntervalConstraintChange.class)));
    Diff addUMLMessage = null;
    if (kind.equals(TestKind.ADD)) {
      addUMLMessage =
          Iterators.find(
              differences.iterator(),
              and(instanceOf(IntervalConstraintChange.class), ofKind(DifferenceKind.ADD)));
    } else {
      addUMLMessage =
          Iterators.find(
              differences.iterator(),
              and(instanceOf(IntervalConstraintChange.class), ofKind(DifferenceKind.DELETE)));
    }
    assertNotNull(addUMLMessage);
    assertEquals(9, addUMLMessage.getRefinedBy().size());
    assertTrue(addUMLMessage.getRefinedBy().contains(addConstrainedElementInTimeConstraint));
    assertTrue(addUMLMessage.getRefinedBy().contains(addTimeInterval));
    assertTrue(addUMLMessage.getRefinedBy().contains(addMinInTimeInterval));
    assertTrue(addUMLMessage.getRefinedBy().contains(addMaxInTimeInterval));
    assertTrue(addUMLMessage.getRefinedBy().contains(addMinValue));
    assertTrue(addUMLMessage.getRefinedBy().contains(addMaxValue));
    assertTrue(addUMLMessage.getRefinedBy().contains(addTimeExpressionMin));
    assertTrue(addUMLMessage.getRefinedBy().contains(addTimeExpressionMax));
    assertTrue(addUMLMessage.getRefinedBy().contains(addTimeConstraint));

    // CHECK REQUIREMENT
    if (kind.equals(TestKind.ADD)) {

      assertEquals(0, addTimeConstraint.getRequires().size());

      assertEquals(1, addTimeInterval.getRequires().size());
      assertTrue(addTimeInterval.getRequires().contains(addTimeConstraint));

      assertEquals(0, addTimeExpressionMin.getRequires().size());
      assertEquals(0, addTimeExpressionMax.getRequires().size());

      assertEquals(1, addMinValue.getRequires().size());
      assertTrue(addMinValue.getRequires().contains(addTimeExpressionMin));

      assertEquals(1, addMaxValue.getRequires().size());
      assertTrue(addMaxValue.getRequires().contains(addTimeExpressionMax));

      assertEquals(1, addConstrainedElementInTimeConstraint.getRequires().size());
      assertTrue(addTimeInterval.getRequires().contains(addTimeConstraint));

      assertEquals(2, addMinInTimeInterval.getRequires().size());
      assertTrue(addMinInTimeInterval.getRequires().contains(addTimeInterval));
      assertTrue(addMinInTimeInterval.getRequires().contains(addTimeExpressionMin));

      assertEquals(2, addMaxInTimeInterval.getRequires().size());
      assertTrue(addMaxInTimeInterval.getRequires().contains(addTimeInterval));
      assertTrue(addMaxInTimeInterval.getRequires().contains(addTimeExpressionMax));

    } else {
      assertEquals(2, addTimeConstraint.getRequires().size());
      assertTrue(addTimeConstraint.getRequires().contains(addConstrainedElementInTimeConstraint));
      assertTrue(addTimeConstraint.getRequires().contains(addTimeInterval));

      assertEquals(2, addTimeInterval.getRequires().size());
      assertTrue(addTimeInterval.getRequires().contains(addMinInTimeInterval));
      assertTrue(addTimeInterval.getRequires().contains(addMaxInTimeInterval));

      assertEquals(2, addTimeExpressionMin.getRequires().size());
      assertTrue(addTimeExpressionMin.getRequires().contains(addMinValue));
      assertTrue(addTimeExpressionMin.getRequires().contains(addMinInTimeInterval));

      assertEquals(2, addTimeExpressionMax.getRequires().size());
      assertTrue(addTimeExpressionMax.getRequires().contains(addMaxValue));
      assertTrue(addTimeExpressionMax.getRequires().contains(addMaxInTimeInterval));

      assertEquals(0, addMinValue.getRequires().size());

      assertEquals(0, addMaxValue.getRequires().size());

      assertEquals(0, addConstrainedElementInTimeConstraint.getRequires().size());

      assertEquals(0, addMinInTimeInterval.getRequires().size());

      assertEquals(0, addMaxInTimeInterval.getRequires().size());
    }

    // CHECK EQUIVALENCE
    assertEquals(0, comparison.getEquivalences().size());

    testIntersections(comparison);
  }