// Path: plugin/src/java/su/msu/cs/lvk/secbugs/ma/KeyIndicatorProperty.java
// public class KeyIndicatorProperty {
//     public enum IndicatorType { UNKNOWN, VALIDATOR, ACCESS }
//     private IndicatorType indicatorType;
// 
//     public KeyIndicatorProperty(IndicatorType indicatorType) {
//         this.indicatorType = indicatorType;
//     }
// 
//     public IndicatorType getIndicatorType() {
//         return indicatorType;
//     }
// 
//     public void setIndicatorType(IndicatorType indicatorType) {
//         this.indicatorType = indicatorType;
//     }
// 
//     public static KeyIndicatorProperty valueOf(String s) {
//         return new KeyIndicatorProperty(IndicatorType.valueOf(s));
//     }
// }
// 
// Path: plugin/src/java/su/msu/cs/lvk/secbugs/ma/KeyIndicatorPropertyDatabase.java
// public class KeyIndicatorPropertyDatabase extends MethodPropertyDatabase<KeyIndicatorProperty> {
//     @Override
//     protected KeyIndicatorProperty decodeProperty(String propStr)
//             throws PropertyDatabaseFormatException {
//         return KeyIndicatorProperty.valueOf(propStr);
//     }
// 
//     @Override
//     protected String encodeProperty(KeyIndicatorProperty property) {
//         return property.getIndicatorType().toString();
//     }
// 
// }


import edu.umd.cs.findbugs.SystemProperties;
import edu.umd.cs.findbugs.ba.*;
import edu.umd.cs.findbugs.classfile.CheckedAnalysisException;
import edu.umd.cs.findbugs.classfile.Global;
import edu.umd.cs.findbugs.classfile.MethodDescriptor;
import org.apache.bcel.Constants;
import org.apache.bcel.generic.*;
import su.msu.cs.lvk.secbugs.ma.KeyIndicatorProperty;
import su.msu.cs.lvk.secbugs.ma.KeyIndicatorPropertyDatabase;

        TaintValueFrame predFact = createFact();
        copy(getResultFact(block), predFact);

        edgeTransfer(edge, predFact);

        TaintValueFrame result = createFact();
        makeFactTop(result);
        meetInto(predFact, edge, result, false);

        return result;
    }

    private TaintValueFrame detaintIfValidated(BasicBlock sourceBlock, int edgeType, TaintValueFrame fact) throws DataflowAnalysisException {
        // call to validator looks like follows:
        // invokevirtual m
        // ifeq	n
        InstructionHandle last = sourceBlock.getLastInstruction();
        if (last != null) {
            InstructionHandle prev = last.getPrev();
            int opcode = last.getInstruction().getOpcode();

            if (edgeType == Edge.FALL_THROUGH_EDGE && opcode == Constants.IFEQ
                    || edgeType == Edge.IFCMP_EDGE && opcode == Constants.IFNE) {
                // It may be a call to validation method,
                // and current block is a then-branch
                if (prev != null && prev.getInstruction() instanceof InvokeInstruction) {
                    InvokeInstruction invoke = (InvokeInstruction) prev.getInstruction();
                    XMethod calledMethod = XFactory.createXMethod(invoke, methodGen.getConstantPool());

// Path: plugin/src/java/su/msu/cs/lvk/secbugs/ma/KeyIndicatorProperty.java
// public class KeyIndicatorProperty {
//     public enum IndicatorType { UNKNOWN, VALIDATOR, ACCESS }
//     private IndicatorType indicatorType;
// 
//     public KeyIndicatorProperty(IndicatorType indicatorType) {
//         this.indicatorType = indicatorType;
//     }
// 
//     public IndicatorType getIndicatorType() {
//         return indicatorType;
//     }
// 
//     public void setIndicatorType(IndicatorType indicatorType) {
//         this.indicatorType = indicatorType;
//     }
// 
//     public static KeyIndicatorProperty valueOf(String s) {
//         return new KeyIndicatorProperty(IndicatorType.valueOf(s));
//     }
// }
// 
// Path: plugin/src/java/su/msu/cs/lvk/secbugs/ma/KeyIndicatorPropertyDatabase.java
// public class KeyIndicatorPropertyDatabase extends MethodPropertyDatabase<KeyIndicatorProperty> {
//     @Override
//     protected KeyIndicatorProperty decodeProperty(String propStr)
//             throws PropertyDatabaseFormatException {
//         return KeyIndicatorProperty.valueOf(propStr);
//     }
// 
//     @Override
//     protected String encodeProperty(KeyIndicatorProperty property) {
//         return property.getIndicatorType().toString();
//     }
// 
// }


// Path: plugin/src/java/su/msu/cs/lvk/secbugs/ta/TaintAnalysis.java
import edu.umd.cs.findbugs.SystemProperties;
import edu.umd.cs.findbugs.ba.*;
import edu.umd.cs.findbugs.classfile.CheckedAnalysisException;
import edu.umd.cs.findbugs.classfile.Global;
import edu.umd.cs.findbugs.classfile.MethodDescriptor;
import org.apache.bcel.Constants;
import org.apache.bcel.generic.*;
import su.msu.cs.lvk.secbugs.ma.KeyIndicatorProperty;
import su.msu.cs.lvk.secbugs.ma.KeyIndicatorPropertyDatabase;


        TaintValueFrame predFact = createFact();
        copy(getResultFact(block), predFact);

        edgeTransfer(edge, predFact);

        TaintValueFrame result = createFact();
        makeFactTop(result);
        meetInto(predFact, edge, result, false);

        return result;
    }

    private TaintValueFrame detaintIfValidated(BasicBlock sourceBlock, int edgeType, TaintValueFrame fact) throws DataflowAnalysisException {
        // call to validator looks like follows:
        // invokevirtual m
        // ifeq	n
        InstructionHandle last = sourceBlock.getLastInstruction();
        if (last != null) {
            InstructionHandle prev = last.getPrev();
            int opcode = last.getInstruction().getOpcode();

            if (edgeType == Edge.FALL_THROUGH_EDGE && opcode == Constants.IFEQ
                    || edgeType == Edge.IFCMP_EDGE && opcode == Constants.IFNE) {
                // It may be a call to validation method,
                // and current block is a then-branch
                if (prev != null && prev.getInstruction() instanceof InvokeInstruction) {
                    InvokeInstruction invoke = (InvokeInstruction) prev.getInstruction();
                    XMethod calledMethod = XFactory.createXMethod(invoke, methodGen.getConstantPool());

                    KeyIndicatorProperty prop = keyIndicatorPropertyDatabase.getProperty(calledMethod.getMethodDescriptor());