gt: 					int count = value.getValue();
context: /**
   * Copyright (C) 2010-2015 Gordon Fraser, Andrea Arcuri and EvoSuite
   * contributors
   *
   * This file is part of EvoSuite.
   *
   * EvoSuite is free software: you can redistribute it and/or modify it
   * under the terms of the GNU Lesser Public License as published by the
   * Free Software Foundation, either version 3.0 of the License, or (at your
   * option) any later version.
   *
   * EvoSuite is distributed in the hope that it will be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   * Lesser Public License for more details.
   *
   * You should have received a copy of the GNU Lesser Public License along
   * with EvoSuite. If not, see <http://www.gnu.org/licenses/>.
   */
  /**
   * 
   */
  package org.evosuite.coverage.cbranch;
  
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Map.Entry;
  import java.util.Set;
  
  import org.evosuite.Properties;
  import org.evosuite.coverage.archive.TestsArchive;
  import org.evosuite.setup.CallContext;
  import org.evosuite.testcase.ExecutableChromosome;
  import org.evosuite.testcase.execution.ExecutionResult;
  import org.evosuite.testsuite.AbstractTestSuiteChromosome;
  import org.evosuite.testsuite.TestSuiteFitnessFunction;
  
  /**
   * Context Branch criterion, force the generation of test cases that directly
   * invoke the method where the branch is, i.e., do not consider covered a branch
   * if it is covered by invoking other methods.
   * 
   * @author Gordon Fraser, mattia
   * 
   */
  
  // TODO: Archive handling could be improved to use branchIds and thus reduce
  //       the overhead of calculating the fitness function
  
  // TODO fix count goal, when a suite executes a branch only one time we should
  // return 0.5 and not the distance.
  
  public class CBranchSuiteFitness extends TestSuiteFitnessFunction {
  
  	private static final long serialVersionUID = -4745892521350308986L;
  
  	private final List<CBranchTestFitness> branchGoals;
  
  	private final Map<Integer, Map<CallContext, Set<CBranchTestFitness>>> contextGoalsMap;
  
  	private final Map<Integer, Set<CBranchTestFitness>> privateMethodsGoalsMap;
  
  	private final Map<String, Map<CallContext, CBranchTestFitness>> methodsMap;
  
  	private final Map<String, CBranchTestFitness> privateMethodsMethodsMap;
  
  	private final Set<CBranchTestFitness> toRemoveGoals = new HashSet<>();	
  	private final Set<CBranchTestFitness> removedGoals = new HashSet<>();
  
  	public CBranchSuiteFitness() {
  		contextGoalsMap = new HashMap<>();
  		privateMethodsGoalsMap = new HashMap<>();
  		methodsMap = new HashMap<>();
  		privateMethodsMethodsMap = new HashMap<>();
  
  		CBranchFitnessFactory factory = new CBranchFitnessFactory();
  		branchGoals = factory.getCoverageGoals();
  		for (CBranchTestFitness goal : branchGoals) {
  			if(Properties.TEST_ARCHIVE)
  				TestsArchive.instance.addGoalToCover(this, goal);
  
  			if (goal.getBranchGoal() != null && goal.getBranchGoal().getBranch() != null) {
  				int branchId = goal.getBranchGoal().getBranch().getActualBranchId();
  
  				// if private method do not consider context
  				if (goal.getContext().isEmpty()) {
  					Set<CBranchTestFitness> tempInSet = privateMethodsGoalsMap.get(branchId);
  					if (tempInSet == null) {
  						privateMethodsGoalsMap.put(branchId, tempInSet = new HashSet<>());
  					}
  					tempInSet.add(goal);
  				} else {
  					// if public method consider context
  					Map<CallContext, Set<CBranchTestFitness>> innermap = contextGoalsMap
  							.get(branchId);
  					if (innermap == null) {
  						contextGoalsMap.put(branchId, innermap = new HashMap<>());
  					}
  					Set<CBranchTestFitness> tempInSet = innermap.get(goal.getContext());
  					if (tempInSet == null) {
  						innermap.put(goal.getContext(), tempInSet = new HashSet<>());
  					}
  					tempInSet.add(goal);
  				}
  			} else {
  				String methodName = goal.getTargetClass() + "." + goal.getTargetMethod();
  				// if private method do not consider context
  				if (goal.getContext().isEmpty()) {
  					privateMethodsMethodsMap.put(methodName, goal);
  				} else {
  					// if public method consider context
  					Map<CallContext, CBranchTestFitness> innermap = methodsMap.get(methodName);
  					if (innermap == null) {
  						methodsMap.put(methodName, innermap = new HashMap<>());
  					}
  					innermap.put(goal.getContext(), goal);
  				}
  			}
  			logger.info("Context goal: " + goal.toString());
  		}
  	}
  
  	// private Map<CBranchTestFitness, Double> getDefaultDistanceMap() {
  	// Map<CBranchTestFitness, Double> distanceMap = new
  	// HashMap<CBranchTestFitness, Double>();
  	// for (CBranchTestFitness goal : branchGoals)
  	// distanceMap.put(goal, 1.0);
  	// return distanceMap;
  	// }
  
  	private CBranchTestFitness getContextGoal(String classAndMethodName, CallContext context) {
  		if (privateMethodsMethodsMap.containsKey(classAndMethodName)) {
  			return privateMethodsMethodsMap.get(classAndMethodName);
  		} else if (methodsMap.get(classAndMethodName) == null
  				|| methodsMap.get(classAndMethodName).get(context) == null)
  			return null;
  		else
  			return methodsMap.get(classAndMethodName).get(context);
  	}
  
  	private CBranchTestFitness getContextGoal(Integer branchId, CallContext context, boolean value) {
  		if (privateMethodsGoalsMap.containsKey(branchId)) {
  			for (CBranchTestFitness cBranchTestFitness : privateMethodsGoalsMap.get(branchId)) {
  				if (cBranchTestFitness.getValue() == value) {
  					return cBranchTestFitness;
  				}
  			}
  		} else if (contextGoalsMap.get(branchId) == null
  				|| contextGoalsMap.get(branchId).get(context) == null)
  			return null;
  		else
  			for (CBranchTestFitness cBranchTestFitness : contextGoalsMap.get(branchId).get(context)) {
  				if (cBranchTestFitness.getValue() == value) {
  					return cBranchTestFitness;
  				}
  			}
  		return null;
  	}
  
  	/*
  	 * (non-Javadoc)
  	 * 
  	 * @see
  	 * org.evosuite.ga.FitnessFunction#getFitness(org.evosuite.ga.Chromosome)
  	 */
  	@Override
  	public double getFitness(AbstractTestSuiteChromosome<? extends ExecutableChromosome> suite) {
  		double fitness = 0.0; // branchFitness.getFitness(suite);
  
  		List<ExecutionResult> results = runTestSuite(suite);
  		Map<CBranchTestFitness, Double> distanceMap = new HashMap<>();
  
  		Map<Integer, Integer> callCounter = new HashMap<>();
  		Map<Integer, Integer> branchCounter = new HashMap<>();
  
  		for (ExecutionResult result : results) {
  			// Determine minimum branch distance for each branch in each context
  			assert (result.getTrace().getTrueDistancesContext().keySet().size() == result
  					.getTrace().getFalseDistancesContext().keySet().size());
  
  			for (Integer branchId : result.getTrace().getTrueDistancesContext().keySet()) {
  				Map<CallContext, Double> trueMap = result.getTrace().getTrueDistancesContext()
  						.get(branchId);
  				Map<CallContext, Double> falseMap = result.getTrace().getFalseDistancesContext()
  						.get(branchId);
  
  				for (CallContext context : trueMap.keySet()) {
  					CBranchTestFitness goalT = getContextGoal(branchId, context, true);
  					if (goalT == null)
  						continue;
  					double distanceT = normalize(trueMap.get(context));
  					if (distanceMap.get(goalT) == null || distanceMap.get(goalT) > distanceT) {
  						distanceMap.put(goalT, distanceT);
  					}
  					if (Double.compare(distanceT, 0.0) == 0) {
  						if(removedGoals.contains(goalT))
  							continue;
  						result.test.addCoveredGoal(goalT);
  						if(Properties.TEST_ARCHIVE) {
  							TestsArchive.instance.putTest(this, goalT, result);
  							toRemoveGoals.add(goalT);
  							suite.isToBeUpdated(true);
  						}
  					}
  					// //
  					CBranchTestFitness goalF = getContextGoal(branchId, context, false);
  					if (goalF == null)
  						continue;
  					double distanceF = normalize(falseMap.get(context));
  					if (distanceMap.get(goalF) == null || distanceMap.get(goalF) > distanceF) {
  						distanceMap.put(goalF, distanceF);
  					}
  					if (Double.compare(distanceF, 0.0) == 0) {
  						if(removedGoals.contains(goalF))
  							continue;
  						result.test.addCoveredGoal(goalF);
  						if(Properties.TEST_ARCHIVE) {
  							TestsArchive.instance.putTest(this, goalF, result);
  							toRemoveGoals.add(goalF);
  							suite.isToBeUpdated(true);
  						}
  
  					}
  				}
  
  			}
  
  			for (Entry<Integer, Map<CallContext, Integer>> entry : result.getTrace()
  					.getPredicateContextExecutionCount().entrySet()) {
  				for (Entry<CallContext, Integer> value : entry.getValue().entrySet()) {
  					int count = value.getValue();
  
  					CBranchTestFitness goalT = getContextGoal(entry.getKey(), value.getKey(), true);
  					if (goalT != null) {
  						if (branchCounter.get(goalT.getGenericContextBranchIdentifier()) == null
  								|| branchCounter.get(goalT.getGenericContextBranchIdentifier()) < count) {
  							branchCounter.put(goalT.getGenericContextBranchIdentifier(), count);
  						}
  					} else {
  						CBranchTestFitness goalF = getContextGoal(entry.getKey(), value.getKey(),
  								false);
  						if (goalF != null) {
  							if (branchCounter.get(goalF.getGenericContextBranchIdentifier()) == null
  									|| branchCounter.get(goalF.getGenericContextBranchIdentifier()) < count) {
  								branchCounter.put(goalF.getGenericContextBranchIdentifier(), count);
  							}
  						} else
  							continue;
  					}
  				}
  			}
  
  			for (Entry<String, Map<CallContext, Integer>> entry : result.getTrace()
  					.getMethodContextCount().entrySet()) {
  				for (Entry<CallContext, Integer> value : entry.getValue().entrySet()) {
  					CBranchTestFitness goal = getContextGoal(entry.getKey(), value.getKey());
  					if (goal == null)
  						continue;
  