// Path: src/lu/uni/snt/cid/Config.java
// public class Config 
// {
// 	public static final int LATEST_API_LEVEL = 25;
// 	public static final int DEFAULT_API_LEVEL = 19;
// 	
// 	public static final String FIELD_VERSION_SDK_INT = "<android.os.Build$VERSION: int SDK_INT>";
// 	public static final String FIELD_VERSION_SDK = "<android.os.Build$VERSION: java.lang.String SDK>";
// 	
// 	public static String apkPath = "";
// 	public static String apkName = "";
// 	public static String androidJars = "";
// 	
// 	
// 	public static boolean DEBUG = false;
// 	public static boolean containsSDKVersionChecker = false;
// 	//public static ConditionalCG ccg = new ConditionalCG();
// }
// 
// Path: src/lu/uni/snt/cid/utils/SootUtils.java
// public class SootUtils 
// {
// 	public static boolean isSuperClass(SootClass original, SootClass tested)
// 	{
// 		List<SootClass> workList = new ArrayList<SootClass>();
// 		
// 		if (original.hasSuperclass())
// 		{
// 			SootClass superCls = original.getSuperclass();
// 			
// 			if (! superCls.getName().equals("java.lang.Object"))
// 			{
// 				workList.add(original.getSuperclass());
// 			}
// 		}
// 		for (Iterator<SootClass> iter = original.getInterfaces().snapshotIterator(); iter.hasNext(); )
// 		{
// 			SootClass sc = iter.next();
// 			workList.add(sc);
// 		}
// 		
// 		while (! workList.isEmpty())
// 		{
// 			SootClass sc = workList.remove(0);
// 			
// 			if (sc.getName().equals(tested.getName()))
// 			{
// 				return true;
// 			}
// 			else
// 			{
// 				if (sc.hasSuperclass())
// 				{
// 					if (! sc.getSuperclass().getName().equals("java.lang.Object"))
// 					{
// 						workList.add(sc.getSuperclass());
// 					}
// 				}
// 				
// 				for (Iterator<SootClass> iter = sc.getInterfaces().snapshotIterator(); iter.hasNext(); )
// 				{
// 					workList.add(iter.next());
// 				}
// 			}
// 		}
// 		
// 		return false;
// 	}
// 	
// 	public static Set<SootClass> getAllSubClasses(SootClass sootClass)
// 	{
// 		Set<SootClass> sootClasses = new HashSet<SootClass>();
// 		
// 		Chain<SootClass> applicationClasses = Scene.v().getApplicationClasses();
// 		for (Iterator<SootClass> iter = applicationClasses.snapshotIterator(); iter.hasNext(); )
// 		{
// 			SootClass sc = iter.next();
// 			
// 			if (isSuperClass(sc, sootClass))
// 			{
// 				sootClasses.add(sc);
// 			}
// 		}
// 		
// 		return sootClasses;
// 	}
// }


import java.util.HashSet;
import java.util.List;
import java.util.Set;
import lu.uni.snt.cid.Config;
import lu.uni.snt.cid.utils.SootUtils;
import soot.Body;
import soot.SootClass;
import soot.SootMethod;
import soot.Unit;
import soot.Value;
import soot.ValueBox;
import soot.jimple.AssignStmt;
import soot.jimple.IfStmt;
import soot.jimple.InterfaceInvokeExpr;
import soot.jimple.ReturnStmt;
import soot.jimple.Stmt;
import soot.toolkits.graph.ExceptionalUnitGraph;
		boolean sdkChecker = false;
		
		while(true)
		{
			if (stmt instanceof AssignStmt)
			{
				AssignStmt assignStmt = (AssignStmt) stmt;
				Value leftOp = assignStmt.getLeftOp();
				
				if (stmt.toString().contains(Config.FIELD_VERSION_SDK_INT))
				{
					sdkIntValues.add(leftOp);
				}
				else
				{
					//Remove killed references
					if (sdkIntValues.contains(leftOp))
					{
						sdkIntValues.remove(leftOp);
					}
				}
			}
			
			if (stmt.containsInvokeExpr())
			{
				Edge edge = ConditionalCallGraph.getEdge(b.getMethod().getSignature(), stmt.getInvokeExpr().getMethod().getSignature());
				edge.conditions.add(conditions.toString());
				
				ConditionalCallGraph.addEdge(edge);
				
// Path: src/lu/uni/snt/cid/Config.java
// public class Config 
// {
// 	public static final int LATEST_API_LEVEL = 25;
// 	public static final int DEFAULT_API_LEVEL = 19;
// 	
// 	public static final String FIELD_VERSION_SDK_INT = "<android.os.Build$VERSION: int SDK_INT>";
// 	public static final String FIELD_VERSION_SDK = "<android.os.Build$VERSION: java.lang.String SDK>";
// 	
// 	public static String apkPath = "";
// 	public static String apkName = "";
// 	public static String androidJars = "";
// 	
// 	
// 	public static boolean DEBUG = false;
// 	public static boolean containsSDKVersionChecker = false;
// 	//public static ConditionalCG ccg = new ConditionalCG();
// }
// 
// Path: src/lu/uni/snt/cid/utils/SootUtils.java
// public class SootUtils 
// {
// 	public static boolean isSuperClass(SootClass original, SootClass tested)
// 	{
// 		List<SootClass> workList = new ArrayList<SootClass>();
// 		
// 		if (original.hasSuperclass())
// 		{
// 			SootClass superCls = original.getSuperclass();
// 			
// 			if (! superCls.getName().equals("java.lang.Object"))
// 			{
// 				workList.add(original.getSuperclass());
// 			}
// 		}
// 		for (Iterator<SootClass> iter = original.getInterfaces().snapshotIterator(); iter.hasNext(); )
// 		{
// 			SootClass sc = iter.next();
// 			workList.add(sc);
// 		}
// 		
// 		while (! workList.isEmpty())
// 		{
// 			SootClass sc = workList.remove(0);
// 			
// 			if (sc.getName().equals(tested.getName()))
// 			{
// 				return true;
// 			}
// 			else
// 			{
// 				if (sc.hasSuperclass())
// 				{
// 					if (! sc.getSuperclass().getName().equals("java.lang.Object"))
// 					{
// 						workList.add(sc.getSuperclass());
// 					}
// 				}
// 				
// 				for (Iterator<SootClass> iter = sc.getInterfaces().snapshotIterator(); iter.hasNext(); )
// 				{
// 					workList.add(iter.next());
// 				}
// 			}
// 		}
// 		
// 		return false;
// 	}
// 	
// 	public static Set<SootClass> getAllSubClasses(SootClass sootClass)
// 	{
// 		Set<SootClass> sootClasses = new HashSet<SootClass>();
// 		
// 		Chain<SootClass> applicationClasses = Scene.v().getApplicationClasses();
// 		for (Iterator<SootClass> iter = applicationClasses.snapshotIterator(); iter.hasNext(); )
// 		{
// 			SootClass sc = iter.next();
// 			
// 			if (isSuperClass(sc, sootClass))
// 			{
// 				sootClasses.add(sc);
// 			}
// 		}
// 		
// 		return sootClasses;
// 	}
// }


// Path: src/lu/uni/snt/cid/ccg/AndroidSDKVersionChecker.java
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import lu.uni.snt.cid.Config;
import lu.uni.snt.cid.utils.SootUtils;
import soot.Body;
import soot.SootClass;
import soot.SootMethod;
import soot.Unit;
import soot.Value;
import soot.ValueBox;
import soot.jimple.AssignStmt;
import soot.jimple.IfStmt;
import soot.jimple.InterfaceInvokeExpr;
import soot.jimple.ReturnStmt;
import soot.jimple.Stmt;
import soot.toolkits.graph.ExceptionalUnitGraph;

		boolean sdkChecker = false;
		
		while(true)
		{
			if (stmt instanceof AssignStmt)
			{
				AssignStmt assignStmt = (AssignStmt) stmt;
				Value leftOp = assignStmt.getLeftOp();
				
				if (stmt.toString().contains(Config.FIELD_VERSION_SDK_INT))
				{
					sdkIntValues.add(leftOp);
				}
				else
				{
					//Remove killed references
					if (sdkIntValues.contains(leftOp))
					{
						sdkIntValues.remove(leftOp);
					}
				}
			}
			
			if (stmt.containsInvokeExpr())
			{
				Edge edge = ConditionalCallGraph.getEdge(b.getMethod().getSignature(), stmt.getInvokeExpr().getMethod().getSignature());
				edge.conditions.add(conditions.toString());
				
				ConditionalCallGraph.addEdge(edge);
				
				if (stmt.getInvokeExpr() instanceof InterfaceInvokeExpr)