@Test
  public void testSimpleInt()
      throws NoSuchMethodException, SecurityException, ClassNotFoundException,
          ConstructionFailedException {
    Properties.TARGET_CLASS = TrivialInt.class.getCanonicalName();
    TestChromosome test1 = new TestChromosome();
    test1.setTestCase(getIntTest(-1000000));
    TestChromosome test2 = (TestChromosome) test1.clone();

    TestSuiteChromosome suite = new TestSuiteChromosome();
    BranchCoverageSuiteFitness fitness = new BranchCoverageSuiteFitness();

    assertEquals(4.0, fitness.getFitness(suite), 0.0F);
    suite.addTest(test1);
    assertEquals(1.0, fitness.getFitness(suite), 0.0F);
    suite.addTest(test2);
    assertEquals(1.0, fitness.getFitness(suite), 0.01F); // 0.99...

    Properties.P_TEST_CHANGE = 1.0;
    Properties.P_TEST_DELETE = 0.0;
    Properties.P_TEST_INSERT = 0.0;
    Properties.PRIMITIVE_POOL = 0.0;
    double oldFitness = suite.getFitness();
    int notChanged = 0;
    for (int i = 0; i < 10000; i++) {
      TestChromosome testNew = (TestChromosome) test1.clone();
      testNew.mutate();
      if (testNew.isChanged()) {
        suite.deleteTest(test1);
        suite.addTest(testNew);
        double newFitness = fitness.getFitness(suite);
        if (newFitness < oldFitness) {
          test1 = testNew;
          oldFitness = newFitness;
          System.out.println(
              ""
                  + i
                  + ":"
                  + ((IntPrimitiveStatement) test1.getTestCase().getStatement(1)).getValue());
          if (newFitness == 0.0) {
            System.out.println("Iterations: " + i);
            System.out.println("Not changed: " + notChanged);
            break;
          }
        } else {
          suite.deleteTest(testNew);
          suite.addTest(test1);
          fitness.getFitness(suite);
        }
      } else {
        notChanged++;
      }
    }

    System.out.println("Fitness: " + fitness.getFitness(suite));
    System.out.println("Test suite: " + suite);
    assertEquals(0.0, fitness.getFitness(suite), 0.1F);
  }
  @Test
  public void testOnSpecificTest()
      throws ClassNotFoundException, ConstructionFailedException, NoSuchMethodException,
          SecurityException {
    Properties.TARGET_CLASS = DseBar.class.getCanonicalName();
    Class<?> sut =
        TestGenerationContext.getInstance()
            .getClassLoaderForSUT()
            .loadClass(Properties.TARGET_CLASS);
    Class<?> fooClass =
        TestGenerationContext.getInstance()
            .getClassLoaderForSUT()
            .loadClass(DseFoo.class.getCanonicalName());
    GenericClass clazz = new GenericClass(sut);

    DefaultTestCase test = new DefaultTestCase();

    // String string0 = "baz5";
    VariableReference stringVar = test.addStatement(new StringPrimitiveStatement(test, "baz5"));

    // DseFoo dseFoo0 = new DseFoo();
    GenericConstructor fooConstructor =
        new GenericConstructor(fooClass.getConstructors()[0], fooClass);
    ConstructorStatement fooConstructorStatement =
        new ConstructorStatement(test, fooConstructor, Arrays.asList(new VariableReference[] {}));
    VariableReference fooVar = test.addStatement(fooConstructorStatement);

    Method fooIncMethod = fooClass.getMethod("inc", new Class<?>[] {});
    GenericMethod incMethod = new GenericMethod(fooIncMethod, fooClass);
    test.addStatement(
        new MethodStatement(test, incMethod, fooVar, Arrays.asList(new VariableReference[] {})));
    test.addStatement(
        new MethodStatement(test, incMethod, fooVar, Arrays.asList(new VariableReference[] {})));
    test.addStatement(
        new MethodStatement(test, incMethod, fooVar, Arrays.asList(new VariableReference[] {})));
    test.addStatement(
        new MethodStatement(test, incMethod, fooVar, Arrays.asList(new VariableReference[] {})));
    test.addStatement(
        new MethodStatement(test, incMethod, fooVar, Arrays.asList(new VariableReference[] {})));

    // DseBar dseBar0 = new DseBar(string0);
    GenericConstructor gc = new GenericConstructor(clazz.getRawClass().getConstructors()[0], clazz);
    ConstructorStatement constructorStatement =
        new ConstructorStatement(test, gc, Arrays.asList(new VariableReference[] {stringVar}));
    VariableReference callee = test.addStatement(constructorStatement);

    // dseBar0.coverMe(dseFoo0);
    Method m = clazz.getRawClass().getMethod("coverMe", new Class<?>[] {fooClass});
    GenericMethod method = new GenericMethod(m, sut);
    MethodStatement ms =
        new MethodStatement(test, method, callee, Arrays.asList(new VariableReference[] {fooVar}));
    test.addStatement(ms);
    System.out.println(test);

    TestSuiteChromosome suite = new TestSuiteChromosome();
    BranchCoverageSuiteFitness fitness = new BranchCoverageSuiteFitness();

    BranchCoverageMap.getInstance().searchStarted(null);
    assertEquals(4.0, fitness.getFitness(suite), 0.1F);
    suite.addTest(test);
    assertEquals(1.0, fitness.getFitness(suite), 0.1F);

    System.out.println("Test suite: " + suite);

    TestSuiteLocalSearch localSearch = TestSuiteLocalSearch.getLocalSearch();
    LocalSearchObjective<TestSuiteChromosome> localObjective =
        new DefaultLocalSearchObjective<TestSuiteChromosome>();
    localObjective.addFitnessFunction(fitness);
    localSearch.doSearch(suite, localObjective);
    System.out.println("Fitness: " + fitness.getFitness(suite));
    System.out.println("Test suite: " + suite);
    assertEquals(0.0, fitness.getFitness(suite), 0.1F);
    BranchCoverageMap.getInstance().searchFinished(null);
  }
  @Test
  public void testTwoInts()
      throws NoSuchMethodException, SecurityException, ClassNotFoundException,
          ConstructionFailedException {
    Properties.TARGET_CLASS = IntExampleWithNoElse.class.getCanonicalName();
    TestChromosome test1 = new TestChromosome();
    test1.setTestCase(getTwoIntTest(1, 22, 22, 22));
    TestChromosome test2 = new TestChromosome();
    test2.setTestCase(getTwoIntTest(-23423423, 234234234, -23423423, 234234234));
    TestChromosome test3 = new TestChromosome();
    test3.setTestCase(getTwoIntTest(0, 0, 0, 0));

    TestSuiteChromosome suite = new TestSuiteChromosome();
    BranchCoverageSuiteFitness fitness = new BranchCoverageSuiteFitness();

    assertEquals(6.0, fitness.getFitness(suite), 0.0F);
    suite.addTest(test1);
    assertEquals(2.0, fitness.getFitness(suite), 0.0F);
    suite.addTest(test2);
    suite.addTest(test3);

    Class<?> sut =
        TestGenerationContext.getInstance()
            .getClassLoaderForSUT()
            .loadClass(Properties.TARGET_CLASS);
    Method m = sut.getMethod("testMe", new Class<?>[] {int.class, int.class});
    GenericMethod method = new GenericMethod(m, sut);

    TestCluster.getInstance().addTestCall(method);

    Properties.P_TEST_CHANGE = 0.0;
    Properties.P_TEST_DELETE = 1.0;
    Properties.P_TEST_INSERT = 0.0;

    double oldFitness = fitness.getFitness(suite);
    int notChanged = 0;
    System.out.println("Original: " + test1);
    for (int i = 0; i < 100; i++) {
      TestChromosome testNew = (TestChromosome) test1.clone();
      testNew.mutate();
      if (testNew.isChanged()) {
        System.out.println("Trying: " + testNew);
        suite.deleteTest(test1);
        suite.addTest(testNew);
        double newFitness = fitness.getFitness(suite);
        if (newFitness < oldFitness) {
          test1 = testNew;
          oldFitness = newFitness;
          if (newFitness == 0.0) {
            System.out.println("Iterations: " + i);
            System.out.println("Not changed: " + notChanged);
            break;
          }
        } else {
          suite.deleteTest(testNew);
          suite.addTest(test1);
          fitness.getFitness(suite);
        }
      } else {
        notChanged++;
      }
    }

    System.out.println("Fitness: " + fitness.getFitness(suite));
    System.out.println("Test suite: " + suite);
    assertEquals(0.0, fitness.getFitness(suite), 0.1F);
  }
  @Test
  public void testSimpleInt()
      throws NoSuchMethodException, SecurityException, ClassNotFoundException,
          ConstructionFailedException {
    Properties.TARGET_CLASS = TrivialInt.class.getCanonicalName();
    TestChromosome test1 = new TestChromosome();
    test1.setTestCase(getIntTest(2938, -1000000));
    TestChromosome test2 = (TestChromosome) test1.clone();

    TestSuiteChromosome suite = new TestSuiteChromosome();
    BranchCoverageSuiteFitness fitness = new BranchCoverageSuiteFitness();

    assertEquals(4.0, fitness.getFitness(suite), 0.0F);
    suite.addTest(test1);
    assertEquals(1.0, fitness.getFitness(suite), 0.0F);
    suite.addTest(test2);
    assertEquals(1.0, fitness.getFitness(suite), 0.01F); // 0.99...

    Class<?> sut =
        TestGenerationContext.getInstance()
            .getClassLoaderForSUT()
            .loadClass(Properties.TARGET_CLASS);
    Method m = sut.getMethod("testMe", new Class<?>[] {int.class});
    GenericMethod method = new GenericMethod(m, sut);

    TestCluster.getInstance().addTestCall(method);

    Properties.P_TEST_CHANGE = 0.0;
    Properties.P_TEST_DELETE = 1.0;
    Properties.P_TEST_INSERT = 0.0;

    double oldFitness = suite.getFitness();
    int notChanged = 0;
    for (int i = 0; i < 100; i++) {
      TestChromosome testNew = (TestChromosome) test1.clone();
      testNew.mutate();
      if (testNew.isChanged()) {
        suite.deleteTest(test1);
        suite.addTest(testNew);
        System.out.println(testNew.getTestCase().toCode());
        double newFitness = fitness.getFitness(suite);
        if (newFitness < oldFitness) {
          System.out.println("Improved: " + newFitness);
          test1 = testNew;
          oldFitness = newFitness;
          System.out.println(
              ""
                  + i
                  + ":"
                  + ((IntPrimitiveStatement) test1.getTestCase().getStatement(1)).getValue());
          if (newFitness == 0.0) {
            System.out.println("Iterations: " + i);
            System.out.println("Not changed: " + notChanged);
            break;
          }
        } else {
          System.out.println("Not improved: " + newFitness);
          suite.deleteTest(testNew);
          suite.addTest(test1);
          fitness.getFitness(suite);
        }
      } else {
        notChanged++;
      }
    }

    System.out.println("Fitness: " + fitness.getFitness(suite));
    System.out.println("Test suite: " + suite);
    assertEquals(0.0, fitness.getFitness(suite), 0.1F);
  }
  // Not working yet
  // @Override
  public double getFitnessAlternative(
      AbstractTestSuiteChromosome<? extends ExecutableChromosome> individual) {
    TestSuiteChromosome suite = (TestSuiteChromosome) individual;
    List<ExecutionResult> results = runTestSuite(suite);
    if (DefUseCoverageFactory.detectAliasingGoals(results)) {
      logger.debug("New total number of goals: " + goals.size());
      totalGoals = initTotalGoals();
      for (DefUsePairType type : totalGoals.keySet()) {
        logger.info(type + ":" + totalGoals.get(type));
      }
    }

    Map<Definition, Set<TestChromosome>> passedDefinitions =
        new HashMap<Definition, Set<TestChromosome>>();
    Map<Definition, Integer> passedDefinitionCount = new HashMap<Definition, Integer>();
    Map<String, Set<TestChromosome>> executedMethods = new HashMap<String, Set<TestChromosome>>();
    Map<String, Integer> executedMethodsCount = new HashMap<String, Integer>();

    for (Definition def : maxDefinitionCount.keySet()) {
      passedDefinitionCount.put(def, 0);
    }
    for (String methodName : maxMethodCount.keySet()) {
      executedMethodsCount.put(methodName, 0);
    }

    for (TestChromosome test : suite.getTestChromosomes()) {
      ExecutionResult result = test.getLastExecutionResult();

      if (result.hasTimeout()) {
        logger.debug("Skipping test with timeout");
        double fitness = goals.size() * 100;
        updateIndividual(this, individual, fitness);
        suite.setCoverage(this, 0.0);
        logger.debug("Test case has timed out, setting fitness to max value " + fitness);
        return fitness;
      }

      for (Entry<Integer, Integer> entry :
          result.getTrace().getDefinitionExecutionCount().entrySet()) {
        Definition def = DefUsePool.getDefinitionByDefId(entry.getKey());
        if (def == null) {
          logger.warn("Could not find def " + entry.getKey());
          continue;
        }
        if (!passedDefinitions.containsKey(def))
          passedDefinitions.put(def, new HashSet<TestChromosome>());

        if (!passedDefinitionCount.containsKey(def)) {
          // logger.warn("Weird, definition is not known: " + def);
          passedDefinitionCount.put(def, 0);
        }
        passedDefinitions.get(def).add(test);
        passedDefinitionCount.put(def, passedDefinitionCount.get(def) + entry.getValue());
      }

      for (Entry<String, Integer> entry : result.getTrace().getMethodExecutionCount().entrySet()) {
        if (executedMethodsCount.containsKey(entry.getKey()))
          executedMethodsCount.put(
              entry.getKey(), executedMethodsCount.get(entry.getKey()) + entry.getValue());
        if (!executedMethods.containsKey(entry.getKey())) {
          executedMethods.put(entry.getKey(), new HashSet<TestChromosome>());
        }
        executedMethods.get(entry.getKey()).add(test);
      }
      /*
      for (Integer id : result.getTrace().getPassedDefIDs()) {
      	Definition def = DefUsePool.getDefinitionByDefId(id);
      	if (!passedDefinitions.containsKey(def))
      		passedDefinitions.put(def, new HashSet<TestChromosome>());

      	passedDefinitions.get(def).add(test);
      	passedDefinitionCount.put(def, passedDefinitionCount.get(def) + 1);
      }
      */
    }

    // 1. Need to reach each definition
    double fitness = branchFitness.getFitness(individual);
    // logger.info("Branch fitness: " + fitness);

    // 3. For all covered defs, calculate minimal use distance
    // Set<DefUseCoverageTestFitness> coveredGoalsSet =
    // DefUseExecutionTraceAnalyzer.getCoveredGoals(results);
    Set<DefUseCoverageTestFitness> coveredGoalsSet =
        new HashSet<
            DefUseCoverageTestFitness>(); // DefUseExecutionTraceAnalyzer.getCoveredGoals(results);

    initCoverageMaps();
    Set<Definition> notFullyCoveredDefs = new HashSet<Definition>();
    boolean methodIsNotFullyCovered = false;

    for (DefUseCoverageTestFitness goal : goals) {
      if (coveredGoalsSet.contains(goal)) {
        continue;
      }

      double goalFitness = 2.0;
      Set<TestChromosome> coveringTests = new HashSet<TestChromosome>();

      if (goal.isParameterGoal()) {
        String methodKey =
            goal.getGoalUse().getClassName() + "." + goal.getGoalUse().getMethodName();
        if (executedMethods.containsKey(methodKey)) {
          coveringTests.addAll(executedMethods.get(methodKey));
        }
      } else {
        if (passedDefinitions.containsKey(goal.getGoalDefinition())) {
          coveringTests.addAll(passedDefinitions.get(goal.getGoalDefinition()));
        }
      }
      if (coveringTests.isEmpty()) {
        logger.debug("No tests cover " + goal);
      } else {
        logger.debug("Checking " + coveringTests.size() + " tests covering " + goal);
      }
      //			for (TestChromosome test : passedDefinitions.get(goal.getGoalDefinition())) {
      for (TestChromosome test : coveringTests) {
        // for (TestChromosome test : suite.getTestChromosomes()) {

        ExecutionResult result = test.getLastExecutionResult();
        DefUseFitnessCalculator calculator = new DefUseFitnessCalculator(goal, test, result);
        // double resultFitness = goal.getFitness(test, result);
        double resultFitness = calculator.calculateDUFitness();

        if (resultFitness < goalFitness) goalFitness = resultFitness;
        if (goalFitness == 0.0) {
          result.test.addCoveredGoal(goal);
          coveredGoalsSet.add(goal);
          break;
        }
      }
      if (goalFitness > 0.0) {
        if (goal.isParameterGoal()) notFullyCoveredDefs.add(goal.getGoalDefinition());
        else methodIsNotFullyCovered = true;
      }

      fitness += goalFitness;
    }

    // 2. Need to execute each definition X times
    // TODO ...unless all defuse pairs are covered?
    for (Entry<Definition, Integer> defCount : maxDefinitionCount.entrySet()) {
      if (notFullyCoveredDefs.contains(defCount.getKey())) {
        int executionCount = passedDefinitionCount.get(defCount.getKey());
        int max = defCount.getValue();
        if (executionCount < max) {
          fitness += normalize(max - executionCount);
        }
      }
    }
    if (methodIsNotFullyCovered) {
      for (Entry<String, Integer> methodCount : maxMethodCount.entrySet()) {
        int executionCount = executedMethodsCount.get(methodCount.getKey());
        int max = methodCount.getValue();
        if (executionCount < max) {
          fitness += normalize(max - executionCount);
        }
      }
    }

    countCoveredGoals(coveredGoalsSet);
    trackCoverageStatistics(suite);
    updateIndividual(this, individual, fitness);

    int coveredGoalCount = countCoveredGoals();
    int totalGoalCount = countTotalGoals();
    if (fitness == 0.0 && coveredGoalCount < totalGoalCount)
      throw new IllegalStateException(
          "Fitness 0 implies 100% coverage "
              + coveredGoalCount
              + " / "
              + totalGoals
              + " (covered / total)");

    return fitness;
  }