gt: 				for (AbstractState s : stateArray) {
context: /*
   * Main.java - This file is part of the Jakstab project.
   * Copyright 2007-2012 Johannes Kinder <jk@jakstab.org>
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, see <http://www.gnu.org/licenses/>.
   */
  
  package org.jakstab;
  
  import java.io.*;
  import java.util.*;
  
  import org.jakstab.transformation.DeadCodeElimination;
  import org.jakstab.transformation.ExpressionSubstitution;
  import org.jakstab.util.*;
  import org.jakstab.analysis.*;
  import org.jakstab.analysis.composite.CompositeState;
  import org.jakstab.analysis.explicit.BasedNumberValuation;
  import org.jakstab.analysis.explicit.BoundedAddressTracking;
  import org.jakstab.analysis.procedures.ProcedureAnalysis;
  import org.jakstab.analysis.procedures.ProcedureState;
  import org.jakstab.asm.*;
  import org.jakstab.cfa.Location;
  import org.jakstab.loader.*;
  import org.jakstab.rtl.expressions.ExpressionFactory;
  import org.jakstab.ssl.Architecture;
  
  import com.google.common.collect.HashMultimap;
  import com.google.common.collect.SetMultimap;
  
  import antlr.ANTLRException;
  
  public class Main {
  
  	private static Logger logger = Logger.getLogger(Main.class);;
  
  	private final static String version = "0.8.3";
  
  	private static volatile Algorithm activeAlgorithm;
  	private static volatile Thread mainThread;
  	
  	public static void main(String[] args) {
  
  		mainThread = Thread.currentThread();
  		StatsTracker stats = StatsTracker.getInstance();
  
  		// Parse command line
  		Options.parseOptions(args);
  
  		logger.error(Characters.DOUBLE_LINE_FULL_WIDTH);
  		logger.error("   Jakstab " + version);
  		logger.error("   Copyright 2007-2012  Johannes Kinder  <johannes.kinder@epfl.ch>");
  		logger.error("");
  		logger.error("   Jakstab comes with ABSOLUTELY NO WARRANTY. This is free software,");
  		logger.error("   and you are welcome to redistribute it under certain conditions.");
  		logger.error("   Refer to LICENSE for details.");
  		logger.error(Characters.DOUBLE_LINE_FULL_WIDTH);
  
  		/////////////////////////
  		// Parse SSL file
  
  		Architecture arch;
  		try {
  			arch = new Architecture(Options.sslFilename.getValue());
  		} catch (IOException e) {
  			logger.fatal("Unable to open SSL file!", e);
  			return;
  		} catch (ANTLRException e)  {
  			logger.fatal("Error parsing SSL file!", e);
  			return;
  		}
  
  		long overallStartTime = System.currentTimeMillis();
  
  		/////////////////////////
  		// Parse executable
  
  		Program program = Program.createProgram(arch);
  
  		File mainFile = new File(Options.mainFilename).getAbsoluteFile();
  
  		String baseFileName = null; 
  
  		try {
  			// Load additional modules
  			for (String moduleName : Options.moduleFilenames) {
  				logger.warn("Parsing " + moduleName + "...");
  				File moduleFile = new File(moduleName).getAbsoluteFile();
  				program.loadModule(moduleFile);
  				
  				// If we are processing drivers, use the driver's name as base name
  				if (Options.wdm.getValue() && moduleFile.getName().toLowerCase().endsWith(".sys")) {
  					baseFileName = getBaseFileName(moduleFile);
  				}
  			}
  			// Load main module last
  			logger.warn("Parsing " + Options.mainFilename + "...");
  			program.loadMainModule(mainFile);
  			
  			// Use main module as base name if we have none yet
  			if (baseFileName == null)
  				baseFileName = getBaseFileName(mainFile);
  
  		} catch (FileNotFoundException e) {
  			logger.fatal("File not found: " + e.getMessage());
  			return;
  		} catch (IOException e) {
  			logger.fatal("IOException while parsing executable!", e);
  			//e.printStackTrace();
  			return;
  		} catch (BinaryParseException e) {
  			logger.fatal("Error during parsing!", e);
  			//e.printStackTrace();
  			return;
  		}
  		logger.info("Finished parsing executable.");
  
  
  		// Change entry point if requested
  		if (Options.startAddress.getValue() > 0) {
  			logger.verbose("Setting start address to 0x" + Long.toHexString(Options.startAddress.getValue()));
  			program.setEntryAddress(new AbsoluteAddress(Options.startAddress.getValue()));
  		}
  
  		// Add surrounding "%DF := 1; call entrypoint; halt;" 
  		program.installHarness(Options.heuristicEntryPoints.getValue() ? new HeuristicHarness() : new DefaultHarness());
  
  		int slashIdx = baseFileName.lastIndexOf('\\');
  		if (slashIdx < 0) slashIdx = baseFileName.lastIndexOf('/');
  		if (slashIdx < 0) slashIdx = -1;
  		slashIdx++;
  		stats.record(baseFileName.substring(slashIdx));
  		stats.record(version);
  
  
  		//StatsPlotter.create(baseFileName + "_states.dat");
  		//StatsPlotter.plot("#Time(ms)\tStates\tInstructions\tGC Time\tSpeed(st/s)");		
  		
  		// Catches control-c and System.exit
  		Thread shutdownThread = new Thread() {
  			@Override
  			public void run() {
  				if (mainThread.isAlive() && activeAlgorithm != null) {
  					//stop = true; // Used for CFI checks
  					activeAlgorithm.stop();
  					try {
  						mainThread.join();
  					} catch (InterruptedException e) {
  						e.printStackTrace();
  					}
  				}
  			}
  		};
  		Runtime.getRuntime().addShutdownHook(shutdownThread);
  
  		// Add shutdown on return pressed for eclipse
  		if (!Options.background.getValue() && System.console() == null) {
  			logger.info("No console detected (eclipse?). Press return to terminate analysis and print statistics.");
  			Thread eclipseShutdownThread = new Thread() { 
  				public void run() { 
  					try { 
  						System.in.read(); 
  					} catch (IOException e) { 
  						e.printStackTrace(); 
  					} 
  					System.exit(1);
  				} 
  			};
  			// yices.dll blocks for input on load for some reason, so load it before we start reading from System.in  
  			// If you are having problems with that, uncomment the next line
  			// org.jakstab.solver.yices.YicesWrapper.getVersion();
  			eclipseShutdownThread.start();
  		}
  		
  
  		// Necessary to stop shutdown thread on exceptions being thrown
  		try {
  
  			/////////////////////////
  			// Reconstruct Control Flow
  			ControlFlowReconstruction cfr = new ControlFlowReconstruction(program);
  			// Execute the algorithm
  			try {
  				runAlgorithm(cfr);
  			} catch (RuntimeException r) {
  				logger.error("!! Runtime exception during Control Flow Reconstruction! Trying to shut down gracefully.");
  				r.printStackTrace();
  			}
  			long overallEndTime = System.currentTimeMillis();
  
  			ReachedSet reached = cfr.getReachedStates();
  			if (Options.dumpStates.getValue()) {
  				// output
  				logger.fatal("=================");
  				logger.fatal(" Reached states:");
  				logger.fatal("=================");
  				AbstractState[] stateArray = reached.toArray(new AbstractState[reached.size()]);
  				Arrays.sort(stateArray, new Comparator<AbstractState>() {
  					@Override
  					public int compare(AbstractState o1, AbstractState o2) {
  						return ((CompositeState)o1).getLocation().compareTo(((CompositeState)o2).getLocation());
  					}
  				});
  				Location lastLoc = null;
  