private Map<Integer, Set<Integer>> getKillMap(
      List<Assertion> assertions, Map<Mutation, ExecutionResult> mutationResults) {
    Map<Integer, Set<Integer>> killMap = new HashMap<Integer, Set<Integer>>();

    int num = 0;
    for (Assertion assertion : assertions) {
      Set<Integer> killedMutations = new HashSet<Integer>();
      for (Mutation m : mutationResults.keySet()) {

        boolean isKilled = false;
        for (OutputTrace<?> trace : mutationResults.get(m).getTraces()) {
          if (trace.isDetectedBy(assertion)) {
            isKilled = true;
            break;
          }
        }
        if (isKilled) {
          killedMutations.add(m.getId());
          assertion.addKilledMutation(m);
        }
      }
      killMap.put(num, killedMutations);
      num++;
    }

    return killMap;
  }
  @Override
  public void addAssertions(TestCase test) {
    if (!(test instanceof StructuredTestCase))
      throw new IllegalArgumentException("Expecting StructuredTestCase");

    StructuredTestCase structuredTest = (StructuredTestCase) test;

    Set<String> targetMethods = structuredTest.getTargetMethods();

    List<Mutation> mutants = MutationPool.getMutants();

    ExecutionResult origResult = runTest(test);
    Map<Mutation, ExecutionResult> mutationResults = new HashMap<Mutation, ExecutionResult>();

    // execute on all mutants in the target method that were touched
    for (Mutation mutant : mutants) {
      if (!origResult.getTrace().wasMutationTouched(mutant.getId())) continue;
      if (!targetMethods.contains(mutant.getMethodName())) {
        continue;
      }

      ExecutionResult mutationResult = runTest(test, mutant);
      mutationResults.put(mutant, mutationResult);
    }

    addAssertions(structuredTest, origResult, mutationResults);
  }
  /** {@inheritDoc} */
  @Override
  public List<Mutation> apply(
      MethodNode mn,
      String className,
      String methodName,
      BytecodeInstruction instruction,
      Frame frame) {

    List<Mutation> mutations = new LinkedList<Mutation>();
    Object value = getValue(instruction.getASMNode());

    for (Object replacement : getReplacement(value)) {
      // insert mutation into bytecode with conditional
      LdcInsnNode mutation = new LdcInsnNode(replacement);
      // insert mutation into pool
      String summary = NAME + " - " + value + " -> " + replacement;
      if (replacement instanceof String) {
        summary = summary.replace("*/", "*_/");
      }
      Mutation mutationObject =
          MutationPool.addMutation(
              className,
              methodName,
              summary,
              instruction,
              mutation,
              Mutation.getDefaultInfectionDistance());
      mutations.add(mutationObject);
    }

    return mutations;
  }