class ParityTagger extends BodyTransformer {
  private static final Logger logger = LoggerFactory.getLogger(ParityTagger.class);

  public ParityTagger(Singletons.Global g) {
  }

  public static ParityTagger v() {
    return G.v().soot_jimple_toolkits_annotation_parity_ParityTagger();
  }

  protected void internalTransform(Body b, String phaseName, Map options) {<FILL_FUNCTION_BODY>}

  private void addColorTag(ValueBox vb, String type) {
    if (type.equals("bottom")) {
      // green
      vb.addTag(new ColorTag(ColorTag.GREEN, "Parity Analysis"));
    } else if (type.equals("top")) {
      // red
      vb.addTag(new ColorTag(ColorTag.RED, "Parity Analysis"));
    } else if (type.equals("even")) {
      // yellow
      vb.addTag(new ColorTag(ColorTag.YELLOW, "Parity Analysis"));
    } else if (type.equals("odd")) {
      // blue
      vb.addTag(new ColorTag(ColorTag.BLUE, "Parity Analysis"));
    }
  }
}


    // System.out.println("parity tagger for method: "+b.getMethod().getName());
    boolean isInteractive = Options.v().interactive_mode();
    Options.v().set_interactive_mode(false);
    ParityAnalysis a;

    if (isInteractive) {
      LiveLocals sll = new SimpleLiveLocals(new BriefUnitGraph(b));
      Options.v().set_interactive_mode(isInteractive);

      a = new ParityAnalysis(new BriefUnitGraph(b), sll);
    } else {
      a = new ParityAnalysis(new BriefUnitGraph(b));
    }

    Iterator sIt = b.getUnits().iterator();
    while (sIt.hasNext()) {

      Stmt s = (Stmt) sIt.next();

      HashMap parityVars = (HashMap) a.getFlowAfter(s);

      Iterator it = parityVars.keySet().iterator();
      while (it.hasNext()) {

        final Value variable = (Value) it.next();
        if ((variable instanceof IntConstant) || (variable instanceof LongConstant)) {
          // don't add string tags (just color tags)
        } else {
          StringTag t = new StringTag("Parity variable: " + variable + " " + parityVars.get(variable), "Parity Analysis");
          s.addTag(t);
        }
      }

      HashMap parityVarsUses = (HashMap) a.getFlowBefore(s);
      HashMap parityVarsDefs = (HashMap) a.getFlowAfter(s);

      // uses

      Iterator valBoxIt = s.getUseBoxes().iterator();

      while (valBoxIt.hasNext()) {
        ValueBox vb = (ValueBox) valBoxIt.next();
        if (parityVarsUses.containsKey(vb.getValue())) {
          // logger.debug("Parity variable for: "+vb.getValue());
          String type = (String) parityVarsUses.get(vb.getValue());
          addColorTag(vb, type);
        }
      }

      // defs

      valBoxIt = s.getDefBoxes().iterator();

      while (valBoxIt.hasNext()) {
        ValueBox vb = (ValueBox) valBoxIt.next();
        if (parityVarsDefs.containsKey(vb.getValue())) {
          // logger.debug("Parity variable for: "+vb.getValue());
          String type = (String) parityVarsDefs.get(vb.getValue());
          addColorTag(vb, type);
        }
      }
    }

    // add key to class
    Iterator keyIt = b.getMethod().getDeclaringClass().getTags().iterator();
    boolean keysAdded = false;
    while (keyIt.hasNext()) {
      Object next = keyIt.next();
      if (next instanceof KeyTag) {
        if (((KeyTag) next).analysisType().equals("Parity Analysis")) {
          keysAdded = true;
        }
      }
    }
    if (!keysAdded) {
      b.getMethod().getDeclaringClass().addTag(new KeyTag(255, 0, 0, "Parity: Top", "Parity Analysis"));
      b.getMethod().getDeclaringClass().addTag(new KeyTag(45, 255, 84, "Parity: Bottom", "Parity Analysis"));
      b.getMethod().getDeclaringClass().addTag(new KeyTag(255, 248, 35, "Parity: Even", "Parity Analysis"));
      b.getMethod().getDeclaringClass().addTag(new KeyTag(174, 210, 255, "Parity: Odd", "Parity Analysis"));
    }
  
<methods>public non-sealed void <init>() ,public final void transform(soot.Body, java.lang.String, Map<java.lang.String,java.lang.String>) ,public final void transform(soot.Body, java.lang.String) ,public final void transform(soot.Body) <variables>private static final Map<java.lang.String,java.lang.String> enabledOnlyMap