gt: 				for (int j = 0; j < attr.inner_classes_length; j++) {
context: /* Soot - a J*va Optimization Framework
   * Copyright (C) 1997 Clark Verbrugge
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library 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
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 02111-1307, USA.
   */
  
  /*
   * Modified by the Sable Research Group and others 1997-1999.  
   * See the 'credits' file distributed with Soot for the complete list of
   * contributors.  (Soot is distributed at http://www.sable.mcgill.ca/soot)
   */
  
  package soot.coffi;
  
  import java.io.InputStream;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
  import soot.ArrayType;
  import soot.Body;
  import soot.BooleanType;
  import soot.ByteType;
  import soot.CharType;
  import soot.DoubleType;
  import soot.FloatType;
  import soot.G;
  import soot.IntType;
  import soot.Local;
  import soot.LongType;
  import soot.Modifier;
  import soot.RefType;
  import soot.Scene;
  import soot.ShortType;
  import soot.Singletons;
  import soot.SootClass;
  import soot.SootField;
  import soot.SootMethod;
  import soot.SootResolver;
  import soot.Type;
  import soot.UnknownType;
  import soot.VoidType;
  import soot.jimple.Jimple;
  import soot.jimple.JimpleBody;
  import soot.tagkit.AnnotationAnnotationElem;
  import soot.tagkit.AnnotationArrayElem;
  import soot.tagkit.AnnotationClassElem;
  import soot.tagkit.AnnotationConstants;
  import soot.tagkit.AnnotationDefaultTag;
  import soot.tagkit.AnnotationDoubleElem;
  import soot.tagkit.AnnotationElem;
  import soot.tagkit.AnnotationEnumElem;
  import soot.tagkit.AnnotationFloatElem;
  import soot.tagkit.AnnotationIntElem;
  import soot.tagkit.AnnotationLongElem;
  import soot.tagkit.AnnotationStringElem;
  import soot.tagkit.AnnotationTag;
  import soot.tagkit.ConstantValueTag;
  import soot.tagkit.DeprecatedTag;
  import soot.tagkit.DoubleConstantValueTag;
  import soot.tagkit.EnclosingMethodTag;
  import soot.tagkit.FloatConstantValueTag;
  import soot.tagkit.GenericAttribute;
  import soot.tagkit.Host;
  import soot.tagkit.InnerClassTag;
  import soot.tagkit.IntegerConstantValueTag;
  import soot.tagkit.LongConstantValueTag;
  import soot.tagkit.SignatureTag;
  import soot.tagkit.SourceFileTag;
  import soot.tagkit.StringConstantValueTag;
  import soot.tagkit.SyntheticTag;
  import soot.tagkit.VisibilityAnnotationTag;
  import soot.tagkit.VisibilityParameterAnnotationTag;
  
  public class Util {
  	public Util(Singletons.Global g) {
  	}
  
  	public static Util v() {
  		return G.v().soot_coffi_Util();
  	}
  
  	private cp_info[] activeConstantPool = null;
  	private LocalVariableTable_attribute activeVariableTable;
  	/* maps from variable names to local variable slot indexes to soot Locals */
  	private Map<String, Map<Integer, Local>> nameToIndexToLocal;
  	private boolean useFaithfulNaming = false;
  
  	/**
  	 * Set the informations relative to the current method body. This method
  	 * must be called before using getLocalForIndex(...) and
  	 * getLocalForStackOp(...) each time a different current method body is
  	 * considered.
  	 */
  	public void bodySetup(LocalVariableTable_attribute la, LocalVariableTypeTable_attribute lt, cp_info[] ca) {
  		activeVariableTable = la;
  		activeConstantPool = ca;
  		nameToIndexToLocal = null;
  	}
  
  	public void setFaithfulNaming(boolean v) {
  		useFaithfulNaming = v;
  	}
  
  	public boolean isUsingFaithfulNaming() {
  		return useFaithfulNaming;
  	}
  
  	public void resolveFromClassFile(SootClass aClass, InputStream is, String filePath, Collection<Type> references) {
  		SootClass bclass = aClass;
  		String className = bclass.getName();
  		ClassFile coffiClass = new ClassFile(className);
  
  		// Load up class file, and retrieve bclass from class manager.
  		{
  			boolean success = coffiClass.loadClassFile(is);
  
  			if (!success) {
  				if (!Scene.v().allowsPhantomRefs())
  					throw new RuntimeException("Could not load classfile: " + bclass.getName());
  				else {
  					G.v().out.println("Warning: " + className + " is a phantom class!");
  					bclass.setPhantomClass();
  					return;
  				}
  
  			}
  
  			CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.this_class];
  
  			String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
  			name = name.replace('/', '.');
  
  			if (!name.equals(bclass.getName())) {
  				throw new RuntimeException("Error: class " + name + " read in from a classfile in which "
  						+ bclass.getName() + " was expected.");
  			}
  		}
  
  		// Set modifier
  		bclass.setModifiers(coffiClass.access_flags & (~0x0020));
  		// don't want the ACC_SUPER flag, it is always supposed to be set
  		// anyways
  
  		// Set superclass
  		{
  			if (coffiClass.super_class != 0) {
  				// This object is not java.lang.Object, so must have a super
  				// class
  
  				CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.super_class];
  
  				String superName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
  				superName = superName.replace('/', '.');
  
  				references.add(RefType.v(superName));
  				bclass.setSuperclass(SootResolver.v().makeClassRef(superName));
  			}
  		}
  
  		// Add interfaces to the bclass
  		{
  			for (int i = 0; i < coffiClass.interfaces_count; i++) {
  				CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.interfaces[i]];
  
  				String interfaceName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
  
  				interfaceName = interfaceName.replace('/', '.');
  
  				references.add(RefType.v(interfaceName));
  				SootClass interfaceClass = SootResolver.v().makeClassRef(interfaceName);
  				interfaceClass.setModifiers(interfaceClass.getModifiers() | Modifier.INTERFACE);
  				bclass.addInterface(interfaceClass);
  			}
  		}
  
  		// Add every field to the bclass
  		for (int i = 0; i < coffiClass.fields_count; i++) {
  
  			field_info fieldInfo = coffiClass.fields[i];
  
  			String fieldName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[fieldInfo.name_index])).convert();
  
  			String fieldDescriptor = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[fieldInfo.descriptor_index]))
  					.convert();
  
  			int modifiers = fieldInfo.access_flags;
  			Type fieldType = jimpleTypeOfFieldDescriptor(fieldDescriptor);
  
  			SootField field = Scene.v().makeSootField(fieldName, fieldType, modifiers);
  			bclass.addField(field);
  
  			references.add(fieldType);
  
  			// add initialization constant, if any
  			for (int j = 0; j < fieldInfo.attributes_count; j++) {
  				// add constant value attributes
  				if (fieldInfo.attributes[j] instanceof ConstantValue_attribute) {
  
  					ConstantValue_attribute attr = (ConstantValue_attribute) fieldInfo.attributes[j];
  					cp_info cval = coffiClass.constant_pool[attr.constantvalue_index];
  					ConstantValueTag tag;
  					switch (cval.tag) {
  					case cp_info.CONSTANT_Integer:
  						tag = new IntegerConstantValueTag((int) ((CONSTANT_Integer_info) cval).bytes);
  						break;
  					case cp_info.CONSTANT_Float:
  						// tag = new
  						// FloatConstantValueTag((int)((CONSTANT_Float_info)cval).bytes);
  						tag = new FloatConstantValueTag(((CONSTANT_Float_info) cval).convert());
  						break;
  					case cp_info.CONSTANT_Long: {
  						CONSTANT_Long_info lcval = (CONSTANT_Long_info) cval;
  						tag = new LongConstantValueTag((lcval.high << 32) + lcval.low);
  						break;
  					}
  					case cp_info.CONSTANT_Double: {
  						CONSTANT_Double_info dcval = (CONSTANT_Double_info) cval;
  						// tag = new DoubleConstantValueTag((dcval.high << 32) +
  						// dcval.low);
  						tag = new DoubleConstantValueTag(dcval.convert());
  						break;
  					}
  					case cp_info.CONSTANT_String: {
  						CONSTANT_String_info scval = (CONSTANT_String_info) cval;
  						CONSTANT_Utf8_info ucval = (CONSTANT_Utf8_info) coffiClass.constant_pool[scval.string_index];
  						tag = new StringConstantValueTag(ucval.convert());
  						break;
  					}
  					default:
  						throw new RuntimeException("unexpected ConstantValue: " + cval);
  					}
  					field.addTag(tag);
  				}
  				// add synthetic tag
  				else if (fieldInfo.attributes[j] instanceof Synthetic_attribute) {
  					field.addTag(new SyntheticTag());
  				}
  				// add deprecated tag
  				else if (fieldInfo.attributes[j] instanceof Deprecated_attribute) {
  					field.addTag(new DeprecatedTag());
  				}
  				// add signature tag
  				else if (fieldInfo.attributes[j] instanceof Signature_attribute) {
  					String generic_sig = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[((Signature_attribute) fieldInfo.attributes[j]).signature_index]))
  							.convert();
  					field.addTag(new SignatureTag(generic_sig));
  				} else if (fieldInfo.attributes[j] instanceof RuntimeVisibleAnnotations_attribute
  						|| fieldInfo.attributes[j] instanceof RuntimeInvisibleAnnotations_attribute) {
  					addAnnotationVisibilityAttribute(field, fieldInfo.attributes[j], coffiClass, references);
  				} else if (fieldInfo.attributes[j] instanceof Generic_attribute) {
  					Generic_attribute attr = (Generic_attribute) fieldInfo.attributes[j];
  					String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.attribute_name])).convert();
  					field.addTag(new GenericAttribute(name, attr.info));
  				}
  			}
  		}
  
  		// Add every method to the bclass
  		for (int i = 0; i < coffiClass.methods_count; i++) {
  
  			method_info methodInfo = coffiClass.methods[i];
  
  			if ((coffiClass.constant_pool[methodInfo.name_index]) == null) {
  				G.v().out.println("method index: " + methodInfo.toName(coffiClass.constant_pool));
  				throw new RuntimeException("method has no name");
  			}
  
  			String methodName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[methodInfo.name_index])).convert();
  			String methodDescriptor = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[methodInfo.descriptor_index]))
  					.convert();
  
  			List<Type> parameterTypes;
  			Type returnType;
  
  			// Generate parameterTypes & returnType
  			{
  				Type[] types = jimpleTypesOfFieldOrMethodDescriptor(methodDescriptor);
  
  				parameterTypes = new ArrayList<Type>();
  				for (int j = 0; j < types.length - 1; j++) {
  					references.add(types[j]);
  					parameterTypes.add(types[j]);
  				}
  
  				returnType = types[types.length - 1];
  				references.add(returnType);
  			}
  
  			int modifiers = methodInfo.access_flags;
  
  			SootMethod method;
  
  			method = Scene.v().makeSootMethod(methodName, parameterTypes, returnType, modifiers);
  			bclass.addMethod(method);
  
  			methodInfo.jmethod = method;
  
  			// add exceptions to method
  			{
  				for (int j = 0; j < methodInfo.attributes_count; j++) {
  					if (methodInfo.attributes[j] instanceof Exception_attribute) {
  						Exception_attribute exceptions = (Exception_attribute) methodInfo.attributes[j];
  
  						for (int k = 0; k < exceptions.number_of_exceptions; k++) {
  							CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[exceptions.exception_index_table[k]];
  
  							String exceptionName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index]))
  									.convert();
  
  							exceptionName = exceptionName.replace('/', '.');
  
  							references.add(RefType.v(exceptionName));
  							method.addExceptionIfAbsent(SootResolver.v().makeClassRef(exceptionName));
  						}
  					} else if (methodInfo.attributes[j] instanceof Synthetic_attribute) {
  						method.addTag(new SyntheticTag());
  					} else if (methodInfo.attributes[j] instanceof Deprecated_attribute) {
  						method.addTag(new DeprecatedTag());
  					} else if (methodInfo.attributes[j] instanceof Signature_attribute) {
  						String generic_sig = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[((Signature_attribute) methodInfo.attributes[j]).signature_index]))
  								.convert();
  						method.addTag(new SignatureTag(generic_sig));
  					} else if (methodInfo.attributes[j] instanceof RuntimeVisibleAnnotations_attribute
  							|| methodInfo.attributes[j] instanceof RuntimeInvisibleAnnotations_attribute) {
  						addAnnotationVisibilityAttribute(method, methodInfo.attributes[j], coffiClass, references);
  					} else if (methodInfo.attributes[j] instanceof RuntimeVisibleParameterAnnotations_attribute
  							|| methodInfo.attributes[j] instanceof RuntimeInvisibleParameterAnnotations_attribute) {
  						addAnnotationVisibilityParameterAttribute(method, methodInfo.attributes[j], coffiClass,
  								references);
  					} else if (methodInfo.attributes[j] instanceof AnnotationDefault_attribute) {
  						AnnotationDefault_attribute attr = (AnnotationDefault_attribute) methodInfo.attributes[j];
  						element_value[] input = new element_value[1];
  						input[0] = attr.default_value;
  						ArrayList<AnnotationElem> list = createElementTags(1, coffiClass, input);
  						method.addTag(new AnnotationDefaultTag(list.get(0)));
  					} else if (methodInfo.attributes[j] instanceof Generic_attribute) {
  						Generic_attribute attr = (Generic_attribute) methodInfo.attributes[j];
  						String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.attribute_name])).convert();
  						method.addTag(new GenericAttribute(name, attr.info));
  					}
  				}
  			}
  
  			// Go through the constant pool, forcing all mentioned classes to be
  			// resolved.
  			{
  				for (int k = 0; k < coffiClass.constant_pool_count; k++) {
  					if (coffiClass.constant_pool[k] instanceof CONSTANT_Class_info) {
  						CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[k];
  
  						String desc = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
  						String name = desc.replace('/', '.');
  
  						if (name.startsWith("["))
  							references.add(jimpleTypeOfFieldDescriptor(desc));
  						else
  							references.add(RefType.v(name));
  					}
  					if (coffiClass.constant_pool[k] instanceof CONSTANT_Fieldref_info
  							|| coffiClass.constant_pool[k] instanceof CONSTANT_Methodref_info
  							|| coffiClass.constant_pool[k] instanceof CONSTANT_InterfaceMethodref_info) {
  						Type[] types = jimpleTypesOfFieldOrMethodDescriptor(
  								cp_info.getTypeDescr(coffiClass.constant_pool, k));
  						for (Type element : types) {
  							references.add(element);
  						}
  					}
  
  				}
  			}
  		}
  
  		// Set coffi source of method
  		for (int i = 0; i < coffiClass.methods_count; i++) {
  			method_info methodInfo = coffiClass.methods[i];
  			// methodInfo.jmethod.setSource(coffiClass, methodInfo);
  			methodInfo.jmethod.setSource(new CoffiMethodSource(coffiClass, methodInfo));
  		}
  
  		// Set "SourceFile" attribute tag
  		for (int i = 0; i < coffiClass.attributes_count; i++) {
  
  			if (coffiClass.attributes[i] instanceof SourceFile_attribute) {
  
  				SourceFile_attribute attr = (SourceFile_attribute) coffiClass.attributes[i];
  				String sourceFile = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.sourcefile_index])).convert();
  
  				if (sourceFile.indexOf(' ') >= 0) {
  					G.v().out.println(
  							"Warning: Class " + className + " has invalid SourceFile attribute (will be ignored).");
  				} else {
  					bclass.addTag(new SourceFileTag(sourceFile, filePath));
  				}
  
  			}
  			// Set "InnerClass" attribute tag
  			else if (coffiClass.attributes[i] instanceof InnerClasses_attribute) {
  				InnerClasses_attribute attr = (InnerClasses_attribute) coffiClass.attributes[i];
  