// 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/util/HierarchyUtil.java
// public class HierarchyUtil {
//     public static Set<XMethod> getResolvedMethods(TypeFrame typeFrame, InvokeInstruction invokeInstruction, ConstantPoolGen cpg) throws ClassNotFoundException, DataflowAnalysisException {
//         Set<JavaClassAndMethod> targetMethodSet = Hierarchy
//                 .resolveMethodCallTargets(invokeInstruction, typeFrame, cpg);
//         Set<XMethod> calledMethods = new HashSet<XMethod>();
//         for (JavaClassAndMethod m : targetMethodSet) {
//             calledMethods.add(XFactory.createXMethod(m));
//         }
//         calledMethods.add(XFactory.createXMethod(invokeInstruction, cpg));
//         return calledMethods;
//     }
// }


import edu.umd.cs.findbugs.SourceLineAnnotation;
import edu.umd.cs.findbugs.ba.*;
import edu.umd.cs.findbugs.ba.type.TypeDataflow;
import edu.umd.cs.findbugs.ba.type.TypeFrame;
import edu.umd.cs.findbugs.classfile.CheckedAnalysisException;
import edu.umd.cs.findbugs.classfile.Global;
import org.apache.bcel.generic.*;
import su.msu.cs.lvk.secbugs.ma.KeyIndicatorProperty;
import su.msu.cs.lvk.secbugs.ma.KeyIndicatorPropertyDatabase;
import su.msu.cs.lvk.secbugs.util.HierarchyUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
        for (int i = 0; i < calledMethod.getNumParams() + shift; ++i) {        	
        	TaintnessValue value = new TaintnessValue();
            value.setTainted(true);
            value.setUntainted(false);
            pushValues.add(value);
            
            if(i==0 && !calledMethod.isStatic()){
            	continue;//first value on stack for non static method : this
            }
            if(parameterIterator.hasNext()){
            	paramSig = parameterIterator.next();
	        	if (paramSig.equals("D") || paramSig.equals("J")){
	        		pushValues.add(value); //for long and double types : 2 slots -> 2 values
	        	}
            }
            
        }

        TypeDataflow typeDataflow;
        TypeFrame typeFact;
        try {
            XMethod caller = XFactory.createXMethod(javaClassAndMethod);
            typeDataflow = Global.getAnalysisCache()
                    .getMethodAnalysis(TypeDataflow.class, caller.getMethodDescriptor());
            typeFact = typeDataflow.getFactAtLocation(getLocation());
        } catch (CheckedAnalysisException e) {
            throw new InvalidBytecodeException("Can't obtain type dataflow for " + calledMethod, e);
        }

        try {
// 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/util/HierarchyUtil.java
// public class HierarchyUtil {
//     public static Set<XMethod> getResolvedMethods(TypeFrame typeFrame, InvokeInstruction invokeInstruction, ConstantPoolGen cpg) throws ClassNotFoundException, DataflowAnalysisException {
//         Set<JavaClassAndMethod> targetMethodSet = Hierarchy
//                 .resolveMethodCallTargets(invokeInstruction, typeFrame, cpg);
//         Set<XMethod> calledMethods = new HashSet<XMethod>();
//         for (JavaClassAndMethod m : targetMethodSet) {
//             calledMethods.add(XFactory.createXMethod(m));
//         }
//         calledMethods.add(XFactory.createXMethod(invokeInstruction, cpg));
//         return calledMethods;
//     }
// }


// Path: plugin/src/java/su/msu/cs/lvk/secbugs/bta/TaintnessFrameModelingVisitor.java
import edu.umd.cs.findbugs.SourceLineAnnotation;
import edu.umd.cs.findbugs.ba.*;
import edu.umd.cs.findbugs.ba.type.TypeDataflow;
import edu.umd.cs.findbugs.ba.type.TypeFrame;
import edu.umd.cs.findbugs.classfile.CheckedAnalysisException;
import edu.umd.cs.findbugs.classfile.Global;
import org.apache.bcel.generic.*;
import su.msu.cs.lvk.secbugs.ma.KeyIndicatorProperty;
import su.msu.cs.lvk.secbugs.ma.KeyIndicatorPropertyDatabase;
import su.msu.cs.lvk.secbugs.util.HierarchyUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

        for (int i = 0; i < calledMethod.getNumParams() + shift; ++i) {        	
        	TaintnessValue value = new TaintnessValue();
            value.setTainted(true);
            value.setUntainted(false);
            pushValues.add(value);
            
            if(i==0 && !calledMethod.isStatic()){
            	continue;//first value on stack for non static method : this
            }
            if(parameterIterator.hasNext()){
            	paramSig = parameterIterator.next();
	        	if (paramSig.equals("D") || paramSig.equals("J")){
	        		pushValues.add(value); //for long and double types : 2 slots -> 2 values
	        	}
            }
            
        }

        TypeDataflow typeDataflow;
        TypeFrame typeFact;
        try {
            XMethod caller = XFactory.createXMethod(javaClassAndMethod);
            typeDataflow = Global.getAnalysisCache()
                    .getMethodAnalysis(TypeDataflow.class, caller.getMethodDescriptor());
            typeFact = typeDataflow.getFactAtLocation(getLocation());
        } catch (CheckedAnalysisException e) {
            throw new InvalidBytecodeException("Can't obtain type dataflow for " + calledMethod, e);
        }

        try {
            Collection<XMethod> calledMethods = HierarchyUtil.getResolvedMethods(typeFact, obj, cpg);