You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2014/05/31 00:51:30 UTC

svn commit: r1598766 [5/12] - in /commons/proper/bcel/trunk/src: main/java/org/apache/bcel/ main/java/org/apache/bcel/classfile/ main/java/org/apache/bcel/generic/ main/java/org/apache/bcel/util/ main/java/org/apache/bcel/verifier/exc/ main/java/org/ap...

Modified: commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass2Verifier.java
URL: http://svn.apache.org/viewvc/commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass2Verifier.java?rev=1598766&r1=1598765&r2=1598766&view=diff
==============================================================================
--- commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass2Verifier.java (original)
+++ commons/proper/bcel/trunk/src/main/java/org/apache/bcel/verifier/statics/Pass2Verifier.java Fri May 30 22:51:27 2014
@@ -84,171 +84,171 @@ import org.apache.bcel.verifier.exc.Loca
  */
 public final class Pass2Verifier extends PassVerifier implements Constants{
 
-	/**
-	 * The LocalVariableInfo instances used by Pass3bVerifier.
-	 * localVariablesInfos[i] denotes the information for the
-	 * local variables of method number i in the
-	 * JavaClass this verifier operates on.
-	 */
-	private LocalVariablesInfo[] localVariablesInfos;
-	
-	/** The Verifier that created this. */
-	private Verifier myOwner;
-
-	/**
-	 * Should only be instantiated by a Verifier.
-	 *
-	 * @see Verifier
-	 */
-	public Pass2Verifier(Verifier owner){
-		myOwner = owner;
-	}
-
-	/**
-	 * Returns a LocalVariablesInfo object containing information
-	 * about the usage of the local variables in the Code attribute
-	 * of the said method or <B>null</B> if the class file this
-	 * Pass2Verifier operates on could not be pass-2-verified correctly.
-	 * The method number method_nr is the method you get using
-	 * <B>Repository.lookupClass(myOwner.getClassname()).getMethods()[method_nr];</B>.
-	 * You should not add own information. Leave that to JustIce.
-	 */
-	public LocalVariablesInfo getLocalVariablesInfo(int method_nr){
-		if (this.verify() != VerificationResult.VR_OK) {
+    /**
+     * The LocalVariableInfo instances used by Pass3bVerifier.
+     * localVariablesInfos[i] denotes the information for the
+     * local variables of method number i in the
+     * JavaClass this verifier operates on.
+     */
+    private LocalVariablesInfo[] localVariablesInfos;
+
+    /** The Verifier that created this. */
+    private Verifier myOwner;
+
+    /**
+     * Should only be instantiated by a Verifier.
+     *
+     * @see Verifier
+     */
+    public Pass2Verifier(Verifier owner){
+        myOwner = owner;
+    }
+
+    /**
+     * Returns a LocalVariablesInfo object containing information
+     * about the usage of the local variables in the Code attribute
+     * of the said method or <B>null</B> if the class file this
+     * Pass2Verifier operates on could not be pass-2-verified correctly.
+     * The method number method_nr is the method you get using
+     * <B>Repository.lookupClass(myOwner.getClassname()).getMethods()[method_nr];</B>.
+     * You should not add own information. Leave that to JustIce.
+     */
+    public LocalVariablesInfo getLocalVariablesInfo(int method_nr){
+        if (this.verify() != VerificationResult.VR_OK) {
             return null; // It's cached, don't worry.
         }
-		if (method_nr < 0 || method_nr >= localVariablesInfos.length){
-			throw new AssertionViolatedException("Method number out of range.");
-		}
-		return localVariablesInfos[method_nr];
-	}
-	
-	/**
-	 * Pass 2 is the pass where static properties of the
-	 * class file are checked without looking into "Code"
-	 * arrays of methods.
-	 * This verification pass is usually invoked when
-	 * a class is resolved; and it may be possible that
-	 * this verification pass has to load in other classes
-	 * such as superclasses or implemented interfaces.
-	 * Therefore, Pass 1 is run on them.<BR>
-	 * Note that most referenced classes are <B>not</B> loaded
-	 * in for verification or for an existance check by this
-	 * pass; only the syntactical correctness of their names
-	 * and descriptors (a.k.a. signatures) is checked.<BR>
-	 * Very few checks that conceptually belong here
-	 * are delayed until pass 3a in JustIce. JustIce does
-	 * not only check for syntactical correctness but also
-	 * for semantical sanity - therefore it needs access to
-	 * the "Code" array of methods in a few cases. Please
-	 * see the pass 3a documentation, too.
-	 *
-	 * @see org.apache.bcel.verifier.statics.Pass3aVerifier
-	 */
-	@Override
+        if (method_nr < 0 || method_nr >= localVariablesInfos.length){
+            throw new AssertionViolatedException("Method number out of range.");
+        }
+        return localVariablesInfos[method_nr];
+    }
+
+    /**
+     * Pass 2 is the pass where static properties of the
+     * class file are checked without looking into "Code"
+     * arrays of methods.
+     * This verification pass is usually invoked when
+     * a class is resolved; and it may be possible that
+     * this verification pass has to load in other classes
+     * such as superclasses or implemented interfaces.
+     * Therefore, Pass 1 is run on them.<BR>
+     * Note that most referenced classes are <B>not</B> loaded
+     * in for verification or for an existance check by this
+     * pass; only the syntactical correctness of their names
+     * and descriptors (a.k.a. signatures) is checked.<BR>
+     * Very few checks that conceptually belong here
+     * are delayed until pass 3a in JustIce. JustIce does
+     * not only check for syntactical correctness but also
+     * for semantical sanity - therefore it needs access to
+     * the "Code" array of methods in a few cases. Please
+     * see the pass 3a documentation, too.
+     *
+     * @see org.apache.bcel.verifier.statics.Pass3aVerifier
+     */
+    @Override
     public VerificationResult do_verify(){
-	    try {
-		VerificationResult vr1 = myOwner.doPass1();
-		if (vr1.equals(VerificationResult.VR_OK)){
-			
-			// For every method, we could have information about the local variables out of LocalVariableTable attributes of
-			// the Code attributes.
-			localVariablesInfos = new LocalVariablesInfo[Repository.lookupClass(myOwner.getClassName()).getMethods().length];
-
-			VerificationResult vr = VerificationResult.VR_OK; // default.
-			try{
-				constant_pool_entries_satisfy_static_constraints();
-				field_and_method_refs_are_valid();
-				every_class_has_an_accessible_superclass();
-				final_methods_are_not_overridden();
-			}
-			catch (ClassConstraintException cce){
-				vr = new VerificationResult(VerificationResult.VERIFIED_REJECTED, cce.getMessage());
-			}
-			return vr;
-		} else {
+        try {
+        VerificationResult vr1 = myOwner.doPass1();
+        if (vr1.equals(VerificationResult.VR_OK)){
+
+            // For every method, we could have information about the local variables out of LocalVariableTable attributes of
+            // the Code attributes.
+            localVariablesInfos = new LocalVariablesInfo[Repository.lookupClass(myOwner.getClassName()).getMethods().length];
+
+            VerificationResult vr = VerificationResult.VR_OK; // default.
+            try{
+                constant_pool_entries_satisfy_static_constraints();
+                field_and_method_refs_are_valid();
+                every_class_has_an_accessible_superclass();
+                final_methods_are_not_overridden();
+            }
+            catch (ClassConstraintException cce){
+                vr = new VerificationResult(VerificationResult.VERIFIED_REJECTED, cce.getMessage());
+            }
+            return vr;
+        } else {
             return VerificationResult.VR_NOTYET;
         }
 
-	    } catch (ClassNotFoundException e) {
-		// FIXME: this might not be the best way to handle missing classes.
-		throw new AssertionViolatedException("Missing class: " + e, e);
-	    }
-	}
-
-	/**
-	 * Ensures that every class has a super class and that
-	 * <B>final</B> classes are not subclassed.
-	 * This means, the class this Pass2Verifier operates
-	 * on has proper super classes (transitively) up to
-	 * java.lang.Object.
-	 * The reason for really loading (and Pass1-verifying)
-	 * all of those classes here is that we need them in
-	 * Pass2 anyway to verify no final methods are overridden
-	 * (that could be declared anywhere in the ancestor hierarchy).
-	 *
-	 * @throws ClassConstraintException otherwise.
-	 */
-	private void every_class_has_an_accessible_superclass(){
-	    try {
-		Set<String> hs = new HashSet<String>(); // save class names to detect circular inheritance
-		JavaClass jc = Repository.lookupClass(myOwner.getClassName());
-		int supidx = -1;
-
-		while (supidx != 0){
-			supidx = jc.getSuperclassNameIndex();
-		
-			if (supidx == 0){
-				if (jc != Repository.lookupClass(Type.OBJECT.getClassName())){
-					throw new ClassConstraintException("Superclass of '"+jc.getClassName()+"' missing but not "+Type.OBJECT.getClassName()+" itself!");
-				}
-			}
-			else{
-				String supername = jc.getSuperclassName();
-				if (! hs.add(supername)){	// If supername already is in the list
-					throw new ClassConstraintException("Circular superclass hierarchy detected.");
-				}
-				Verifier v = VerifierFactory.getVerifier(supername);
-				VerificationResult vr = v.doPass1();
-
-				if (vr != VerificationResult.VR_OK){
-					throw new ClassConstraintException("Could not load in ancestor class '"+supername+"'.");
-				}
-				jc = Repository.lookupClass(supername);
-
-				if (jc.isFinal()){
-					throw new ClassConstraintException("Ancestor class '"+supername+"' has the FINAL access modifier and must therefore not be subclassed.");
-				}
-			}
-		}
-
-	    } catch (ClassNotFoundException e) {
-		// FIXME: this might not be the best way to handle missing classes.
-		throw new AssertionViolatedException("Missing class: " + e, e);
-	    }
-	}
-
-	/**
-	 * Ensures that <B>final</B> methods are not overridden.
-	 * <B>Precondition to run this method:
-	 * constant_pool_entries_satisfy_static_constraints() and
-	 * every_class_has_an_accessible_superclass() have to be invoked before
-	 * (in that order).</B>
-	 *
-	 * @throws ClassConstraintException otherwise.
-	 * @see #constant_pool_entries_satisfy_static_constraints()
-	 * @see #every_class_has_an_accessible_superclass()
-	 */
-	private void final_methods_are_not_overridden(){
-	    try {
-		Map<String, String> hashmap = new HashMap<String, String>();
-		JavaClass jc = Repository.lookupClass(myOwner.getClassName());
-		
-		int supidx = -1;
-		while (supidx != 0){
-			supidx = jc.getSuperclassNameIndex();
+        } catch (ClassNotFoundException e) {
+        // FIXME: this might not be the best way to handle missing classes.
+        throw new AssertionViolatedException("Missing class: " + e, e);
+        }
+    }
+
+    /**
+     * Ensures that every class has a super class and that
+     * <B>final</B> classes are not subclassed.
+     * This means, the class this Pass2Verifier operates
+     * on has proper super classes (transitively) up to
+     * java.lang.Object.
+     * The reason for really loading (and Pass1-verifying)
+     * all of those classes here is that we need them in
+     * Pass2 anyway to verify no final methods are overridden
+     * (that could be declared anywhere in the ancestor hierarchy).
+     *
+     * @throws ClassConstraintException otherwise.
+     */
+    private void every_class_has_an_accessible_superclass(){
+        try {
+        Set<String> hs = new HashSet<String>(); // save class names to detect circular inheritance
+        JavaClass jc = Repository.lookupClass(myOwner.getClassName());
+        int supidx = -1;
+
+        while (supidx != 0){
+            supidx = jc.getSuperclassNameIndex();
+
+            if (supidx == 0){
+                if (jc != Repository.lookupClass(Type.OBJECT.getClassName())){
+                    throw new ClassConstraintException("Superclass of '"+jc.getClassName()+"' missing but not "+Type.OBJECT.getClassName()+" itself!");
+                }
+            }
+            else{
+                String supername = jc.getSuperclassName();
+                if (! hs.add(supername)){    // If supername already is in the list
+                    throw new ClassConstraintException("Circular superclass hierarchy detected.");
+                }
+                Verifier v = VerifierFactory.getVerifier(supername);
+                VerificationResult vr = v.doPass1();
+
+                if (vr != VerificationResult.VR_OK){
+                    throw new ClassConstraintException("Could not load in ancestor class '"+supername+"'.");
+                }
+                jc = Repository.lookupClass(supername);
+
+                if (jc.isFinal()){
+                    throw new ClassConstraintException("Ancestor class '"+supername+"' has the FINAL access modifier and must therefore not be subclassed.");
+                }
+            }
+        }
+
+        } catch (ClassNotFoundException e) {
+        // FIXME: this might not be the best way to handle missing classes.
+        throw new AssertionViolatedException("Missing class: " + e, e);
+        }
+    }
+
+    /**
+     * Ensures that <B>final</B> methods are not overridden.
+     * <B>Precondition to run this method:
+     * constant_pool_entries_satisfy_static_constraints() and
+     * every_class_has_an_accessible_superclass() have to be invoked before
+     * (in that order).</B>
+     *
+     * @throws ClassConstraintException otherwise.
+     * @see #constant_pool_entries_satisfy_static_constraints()
+     * @see #every_class_has_an_accessible_superclass()
+     */
+    private void final_methods_are_not_overridden(){
+        try {
+        Map<String, String> hashmap = new HashMap<String, String>();
+        JavaClass jc = Repository.lookupClass(myOwner.getClassName());
+
+        int supidx = -1;
+        while (supidx != 0){
+            supidx = jc.getSuperclassNameIndex();
 
-			Method[] methods = jc.getMethods();
+            Method[] methods = jc.getMethods();
             for (Method method : methods) {
                 String name_and_sig = (method.getName() + method.getSignature());
 
@@ -270,113 +270,113 @@ public final class Pass2Verifier extends
                     }
                 }
             }
-		
-			jc = Repository.lookupClass(jc.getSuperclassName());	// Well, for OBJECT this returns OBJECT so it works (could return anything but must not throw an Exception).
-		}
-
-	    } catch (ClassNotFoundException e) {
-		// FIXME: this might not be the best way to handle missing classes.
-		throw new AssertionViolatedException("Missing class: " + e, e);
-	    }
-
-	}
-
-	/**
-	 * Ensures that the constant pool entries satisfy the static constraints
-	 * as described in The Java Virtual Machine Specification, 2nd Edition.
-	 *
-	 * @throws ClassConstraintException otherwise.
-	 */
-	private void constant_pool_entries_satisfy_static_constraints(){
-	    try {
-		// Most of the consistency is handled internally by BCEL; here
-		// we only have to verify if the indices of the constants point
-		// to constants of the appropriate type and such.
-		JavaClass jc = Repository.lookupClass(myOwner.getClassName());
-		new CPESSC_Visitor(jc); // constructor implicitly traverses jc
-
-	    } catch (ClassNotFoundException e) {
-		// FIXME: this might not be the best way to handle missing classes.
-		throw new AssertionViolatedException("Missing class: " + e, e);
-	    }
-	}
-
-	/**
-	 * A Visitor class that ensures the constant pool satisfies the static
-	 * constraints.
+
+            jc = Repository.lookupClass(jc.getSuperclassName());    // Well, for OBJECT this returns OBJECT so it works (could return anything but must not throw an Exception).
+        }
+
+        } catch (ClassNotFoundException e) {
+        // FIXME: this might not be the best way to handle missing classes.
+        throw new AssertionViolatedException("Missing class: " + e, e);
+        }
+
+    }
+
+    /**
+     * Ensures that the constant pool entries satisfy the static constraints
+     * as described in The Java Virtual Machine Specification, 2nd Edition.
+     *
+     * @throws ClassConstraintException otherwise.
+     */
+    private void constant_pool_entries_satisfy_static_constraints(){
+        try {
+        // Most of the consistency is handled internally by BCEL; here
+        // we only have to verify if the indices of the constants point
+        // to constants of the appropriate type and such.
+        JavaClass jc = Repository.lookupClass(myOwner.getClassName());
+        new CPESSC_Visitor(jc); // constructor implicitly traverses jc
+
+        } catch (ClassNotFoundException e) {
+        // FIXME: this might not be the best way to handle missing classes.
+        throw new AssertionViolatedException("Missing class: " + e, e);
+        }
+    }
+
+    /**
+     * A Visitor class that ensures the constant pool satisfies the static
+     * constraints.
    * The visitXXX() methods throw ClassConstraintException instances otherwise.
    *
    * @see #constant_pool_entries_satisfy_static_constraints()
-	 */
-	private class CPESSC_Visitor extends org.apache.bcel.classfile.EmptyVisitor{
-		private Class<?> CONST_Class;
-		/*
+     */
+    private class CPESSC_Visitor extends org.apache.bcel.classfile.EmptyVisitor{
+        private Class<?> CONST_Class;
+        /*
         private Class<?> CONST_Fieldref;
-		private Class<?> CONST_Methodref;
-		private Class<?> CONST_InterfaceMethodref;
+        private Class<?> CONST_Methodref;
+        private Class<?> CONST_InterfaceMethodref;
         */
-		private Class<?> CONST_String;
-		private Class<?> CONST_Integer;
-		private Class<?> CONST_Float;
-		private Class<?> CONST_Long;
-		private Class<?> CONST_Double;
-		private Class<?> CONST_NameAndType;
-		private Class<?> CONST_Utf8;
-
-		private final JavaClass jc;
-		private final ConstantPool cp; // ==jc.getConstantPool() -- only here to save typing work and computing power.
-		private final int cplen; // == cp.getLength() -- to save computing power.
-		private DescendingVisitor carrier;
-
-		private Set<String> field_names = new HashSet<String>();
-		private Set<String> field_names_and_desc = new HashSet<String>();
-		private Set<String> method_names_and_desc = new HashSet<String>();
-
-		private CPESSC_Visitor(JavaClass _jc){
-			jc = _jc;
-			cp = _jc.getConstantPool();
-			cplen = cp.getLength();
+        private Class<?> CONST_String;
+        private Class<?> CONST_Integer;
+        private Class<?> CONST_Float;
+        private Class<?> CONST_Long;
+        private Class<?> CONST_Double;
+        private Class<?> CONST_NameAndType;
+        private Class<?> CONST_Utf8;
+
+        private final JavaClass jc;
+        private final ConstantPool cp; // ==jc.getConstantPool() -- only here to save typing work and computing power.
+        private final int cplen; // == cp.getLength() -- to save computing power.
+        private DescendingVisitor carrier;
+
+        private Set<String> field_names = new HashSet<String>();
+        private Set<String> field_names_and_desc = new HashSet<String>();
+        private Set<String> method_names_and_desc = new HashSet<String>();
+
+        private CPESSC_Visitor(JavaClass _jc){
+            jc = _jc;
+            cp = _jc.getConstantPool();
+            cplen = cp.getLength();
 
-			CONST_Class = org.apache.bcel.classfile.ConstantClass.class;
-			/*
+            CONST_Class = org.apache.bcel.classfile.ConstantClass.class;
+            /*
             CONST_Fieldref = org.apache.bcel.classfile.ConstantFieldref.class;
-			CONST_Methodref = org.apache.bcel.classfile.ConstantMethodref.class;
-			CONST_InterfaceMethodref = org.apache.bcel.classfile.ConstantInterfaceMethodref.class;
+            CONST_Methodref = org.apache.bcel.classfile.ConstantMethodref.class;
+            CONST_InterfaceMethodref = org.apache.bcel.classfile.ConstantInterfaceMethodref.class;
             */
-			CONST_String = org.apache.bcel.classfile.ConstantString.class;
-			CONST_Integer = org.apache.bcel.classfile.ConstantInteger.class;
-			CONST_Float = org.apache.bcel.classfile.ConstantFloat.class;
-			CONST_Long = org.apache.bcel.classfile.ConstantLong.class;
-			CONST_Double = org.apache.bcel.classfile.ConstantDouble.class;
-			CONST_NameAndType = org.apache.bcel.classfile.ConstantNameAndType.class;
-			CONST_Utf8 = org.apache.bcel.classfile.ConstantUtf8.class;
-
-			carrier = new DescendingVisitor(_jc, this);
-			carrier.visit();
-		}
-
-		private void checkIndex(Node referrer, int index, Class<?> shouldbe){
-			if ((index < 0) || (index >= cplen)){
-				throw new ClassConstraintException("Invalid index '"+index+"' used by '"+tostring(referrer)+"'.");
-			}
-			Constant c = cp.getConstant(index);
-			if (! shouldbe.isInstance(c)){
-				/* String isnot = shouldbe.toString().substring(shouldbe.toString().lastIndexOf(".")+1); //Cut all before last "." */
-				throw new ClassCastException("Illegal constant '"+tostring(c)+"' at index '"+index+"'. '"+tostring(referrer)+"' expects a '"+shouldbe+"'.");
-			}
-		}
-		///////////////////////////////////////
-		// ClassFile structure (vmspec2 4.1) //
-		///////////////////////////////////////
-		@Override
+            CONST_String = org.apache.bcel.classfile.ConstantString.class;
+            CONST_Integer = org.apache.bcel.classfile.ConstantInteger.class;
+            CONST_Float = org.apache.bcel.classfile.ConstantFloat.class;
+            CONST_Long = org.apache.bcel.classfile.ConstantLong.class;
+            CONST_Double = org.apache.bcel.classfile.ConstantDouble.class;
+            CONST_NameAndType = org.apache.bcel.classfile.ConstantNameAndType.class;
+            CONST_Utf8 = org.apache.bcel.classfile.ConstantUtf8.class;
+
+            carrier = new DescendingVisitor(_jc, this);
+            carrier.visit();
+        }
+
+        private void checkIndex(Node referrer, int index, Class<?> shouldbe){
+            if ((index < 0) || (index >= cplen)){
+                throw new ClassConstraintException("Invalid index '"+index+"' used by '"+tostring(referrer)+"'.");
+            }
+            Constant c = cp.getConstant(index);
+            if (! shouldbe.isInstance(c)){
+                /* String isnot = shouldbe.toString().substring(shouldbe.toString().lastIndexOf(".")+1); //Cut all before last "." */
+                throw new ClassCastException("Illegal constant '"+tostring(c)+"' at index '"+index+"'. '"+tostring(referrer)+"' expects a '"+shouldbe+"'.");
+            }
+        }
+        ///////////////////////////////////////
+        // ClassFile structure (vmspec2 4.1) //
+        ///////////////////////////////////////
+        @Override
         public void visitJavaClass(JavaClass obj){
-			Attribute[] atts = obj.getAttributes();
-			boolean foundSourceFile = false;
-			boolean foundInnerClasses = false;
-
-			// Is there an InnerClass referenced?
-			// This is a costly check; existing verifiers don't do it!
-			boolean hasInnerClass = new InnerClassDetector(jc).innerClassReferenced();
+            Attribute[] atts = obj.getAttributes();
+            boolean foundSourceFile = false;
+            boolean foundInnerClasses = false;
+
+            // Is there an InnerClass referenced?
+            // This is a costly check; existing verifiers don't do it!
+            boolean hasInnerClass = new InnerClassDetector(jc).innerClassReferenced();
 
             for (Attribute att : atts) {
                 if ((!(att instanceof SourceFile)) &&
@@ -408,171 +408,171 @@ public final class Pass2Verifier extends
                 }
 
             }
-			if (hasInnerClass && !foundInnerClasses){
-				//throw new ClassConstraintException("A Classfile structure (like '"+tostring(obj)+"') must have exactly one InnerClasses attribute if at least one Inner Class is referenced (which is the case). No InnerClasses attribute was found.");
-				//vmspec2, page 125 says it would be a constraint: but existing verifiers
-				//don't check it and javac doesn't satisfy it when it comes to anonymous
-				//inner classes
-				addMessage("A Classfile structure (like '"+tostring(obj)+"') must have exactly one InnerClasses attribute if at least one Inner Class is referenced (which is the case). No InnerClasses attribute was found.");
-			}
-		}
-		/////////////////////////////
-		// CONSTANTS (vmspec2 4.4) //
-		/////////////////////////////
-		@Override
+            if (hasInnerClass && !foundInnerClasses){
+                //throw new ClassConstraintException("A Classfile structure (like '"+tostring(obj)+"') must have exactly one InnerClasses attribute if at least one Inner Class is referenced (which is the case). No InnerClasses attribute was found.");
+                //vmspec2, page 125 says it would be a constraint: but existing verifiers
+                //don't check it and javac doesn't satisfy it when it comes to anonymous
+                //inner classes
+                addMessage("A Classfile structure (like '"+tostring(obj)+"') must have exactly one InnerClasses attribute if at least one Inner Class is referenced (which is the case). No InnerClasses attribute was found.");
+            }
+        }
+        /////////////////////////////
+        // CONSTANTS (vmspec2 4.4) //
+        /////////////////////////////
+        @Override
         public void visitConstantClass(ConstantClass obj){
-			if (obj.getTag() != Constants.CONSTANT_Class){
-				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
-			}
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+            if (obj.getTag() != Constants.CONSTANT_Class){
+                throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
+            }
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
 
-		}
-		@Override
+        }
+        @Override
         public void visitConstantFieldref(ConstantFieldref obj){
-			if (obj.getTag() != Constants.CONSTANT_Fieldref){
-				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
-			}
-			checkIndex(obj, obj.getClassIndex(), CONST_Class);
-			checkIndex(obj, obj.getNameAndTypeIndex(), CONST_NameAndType);
-		}
-		@Override
+            if (obj.getTag() != Constants.CONSTANT_Fieldref){
+                throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
+            }
+            checkIndex(obj, obj.getClassIndex(), CONST_Class);
+            checkIndex(obj, obj.getNameAndTypeIndex(), CONST_NameAndType);
+        }
+        @Override
         public void visitConstantMethodref(ConstantMethodref obj){
-			if (obj.getTag() != Constants.CONSTANT_Methodref){
-				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
-			}
-			checkIndex(obj, obj.getClassIndex(), CONST_Class);
-			checkIndex(obj, obj.getNameAndTypeIndex(), CONST_NameAndType);
-		}
-		@Override
+            if (obj.getTag() != Constants.CONSTANT_Methodref){
+                throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
+            }
+            checkIndex(obj, obj.getClassIndex(), CONST_Class);
+            checkIndex(obj, obj.getNameAndTypeIndex(), CONST_NameAndType);
+        }
+        @Override
         public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj){
-			if (obj.getTag() != Constants.CONSTANT_InterfaceMethodref){
-				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
-			}
-			checkIndex(obj, obj.getClassIndex(), CONST_Class);
-			checkIndex(obj, obj.getNameAndTypeIndex(), CONST_NameAndType);
-		}
-		@Override
+            if (obj.getTag() != Constants.CONSTANT_InterfaceMethodref){
+                throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
+            }
+            checkIndex(obj, obj.getClassIndex(), CONST_Class);
+            checkIndex(obj, obj.getNameAndTypeIndex(), CONST_NameAndType);
+        }
+        @Override
         public void visitConstantString(ConstantString obj){
-			if (obj.getTag() != Constants.CONSTANT_String){
-				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
-			}
-			checkIndex(obj, obj.getStringIndex(), CONST_Utf8);
-		}
-		@Override
+            if (obj.getTag() != Constants.CONSTANT_String){
+                throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
+            }
+            checkIndex(obj, obj.getStringIndex(), CONST_Utf8);
+        }
+        @Override
         public void visitConstantInteger(ConstantInteger obj){
-			if (obj.getTag() != Constants.CONSTANT_Integer){
-				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
-			}
-			// no indices to check
-		}
-		@Override
+            if (obj.getTag() != Constants.CONSTANT_Integer){
+                throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
+            }
+            // no indices to check
+        }
+        @Override
         public void visitConstantFloat(ConstantFloat obj){
-			if (obj.getTag() != Constants.CONSTANT_Float){
-				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
-			}
-			//no indices to check
-		}
-		@Override
+            if (obj.getTag() != Constants.CONSTANT_Float){
+                throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
+            }
+            //no indices to check
+        }
+        @Override
         public void visitConstantLong(ConstantLong obj){
-			if (obj.getTag() != Constants.CONSTANT_Long){
-				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
-			}
-			//no indices to check
-		}
-		@Override
+            if (obj.getTag() != Constants.CONSTANT_Long){
+                throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
+            }
+            //no indices to check
+        }
+        @Override
         public void visitConstantDouble(ConstantDouble obj){
-			if (obj.getTag() != Constants.CONSTANT_Double){
-				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
-			}
-			//no indices to check
-		}
-		@Override
+            if (obj.getTag() != Constants.CONSTANT_Double){
+                throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
+            }
+            //no indices to check
+        }
+        @Override
         public void visitConstantNameAndType(ConstantNameAndType obj){
-			if (obj.getTag() != Constants.CONSTANT_NameAndType){
-				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
-			}
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
-			//checkIndex(obj, obj.getDescriptorIndex(), CONST_Utf8); //inconsistently named in BCEL, see below.
-			checkIndex(obj, obj.getSignatureIndex(), CONST_Utf8);
-		}
-		@Override
+            if (obj.getTag() != Constants.CONSTANT_NameAndType){
+                throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
+            }
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+            //checkIndex(obj, obj.getDescriptorIndex(), CONST_Utf8); //inconsistently named in BCEL, see below.
+            checkIndex(obj, obj.getSignatureIndex(), CONST_Utf8);
+        }
+        @Override
         public void visitConstantUtf8(ConstantUtf8 obj){
-			if (obj.getTag() != Constants.CONSTANT_Utf8){
-				throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
-			}
-			//no indices to check
-		}
-		//////////////////////////
-		// FIELDS (vmspec2 4.5) //
-		//////////////////////////
-		@Override
+            if (obj.getTag() != Constants.CONSTANT_Utf8){
+                throw new ClassConstraintException("Wrong constant tag in '"+tostring(obj)+"'.");
+            }
+            //no indices to check
+        }
+        //////////////////////////
+        // FIELDS (vmspec2 4.5) //
+        //////////////////////////
+        @Override
         public void visitField(Field obj){
 
-			if (jc.isClass()){
-				int maxone=0;
-				if (obj.isPrivate()) {
+            if (jc.isClass()){
+                int maxone=0;
+                if (obj.isPrivate()) {
                     maxone++;
                 }
-				if (obj.isProtected()) {
+                if (obj.isProtected()) {
                     maxone++;
                 }
-				if (obj.isPublic()) {
+                if (obj.isPublic()) {
                     maxone++;
                 }
-				if (maxone > 1){
-					throw new ClassConstraintException("Field '"+tostring(obj)+"' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set.");
-				}
-
-				if (obj.isFinal() && obj.isVolatile()){
-					throw new ClassConstraintException("Field '"+tostring(obj)+"' must only have at most one of its ACC_FINAL, ACC_VOLATILE modifiers set.");
-				}
-			}
-			else{ // isInterface!
-				if (!obj.isPublic()){
-					throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_PUBLIC modifier set but hasn't!");
-				}
-				if (!obj.isStatic()){
-					throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_STATIC modifier set but hasn't!");
-				}
-				if (!obj.isFinal()){
-					throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_FINAL modifier set but hasn't!");
-				}
-			}
-
-			if ((obj.getAccessFlags() & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_STATIC|ACC_FINAL|ACC_VOLATILE|ACC_TRANSIENT)) > 0){
-				addMessage("Field '"+tostring(obj)+"' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, ACC_TRANSIENT set (ignored).");
-			}
-
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
-
-			String name = obj.getName();
-			if (! validFieldName(name)){
-				throw new ClassConstraintException("Field '"+tostring(obj)+"' has illegal name '"+obj.getName()+"'.");
-			}
-
-			// A descriptor is often named signature in BCEL
-			checkIndex(obj, obj.getSignatureIndex(), CONST_Utf8);
-
-			String sig  = ((ConstantUtf8) (cp.getConstant(obj.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor)
-
-			try{
-				Type.getType(sig);  /* Don't need the return value */
-			}
-			catch (ClassFormatException cfe){
+                if (maxone > 1){
+                    throw new ClassConstraintException("Field '"+tostring(obj)+"' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set.");
+                }
+
+                if (obj.isFinal() && obj.isVolatile()){
+                    throw new ClassConstraintException("Field '"+tostring(obj)+"' must only have at most one of its ACC_FINAL, ACC_VOLATILE modifiers set.");
+                }
+            }
+            else{ // isInterface!
+                if (!obj.isPublic()){
+                    throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_PUBLIC modifier set but hasn't!");
+                }
+                if (!obj.isStatic()){
+                    throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_STATIC modifier set but hasn't!");
+                }
+                if (!obj.isFinal()){
+                    throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_FINAL modifier set but hasn't!");
+                }
+            }
+
+            if ((obj.getAccessFlags() & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_STATIC|ACC_FINAL|ACC_VOLATILE|ACC_TRANSIENT)) > 0){
+                addMessage("Field '"+tostring(obj)+"' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, ACC_TRANSIENT set (ignored).");
+            }
+
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+
+            String name = obj.getName();
+            if (! validFieldName(name)){
+                throw new ClassConstraintException("Field '"+tostring(obj)+"' has illegal name '"+obj.getName()+"'.");
+            }
+
+            // A descriptor is often named signature in BCEL
+            checkIndex(obj, obj.getSignatureIndex(), CONST_Utf8);
+
+            String sig  = ((ConstantUtf8) (cp.getConstant(obj.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor)
+
+            try{
+                Type.getType(sig);  /* Don't need the return value */
+            }
+            catch (ClassFormatException cfe){
                 throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'.", cfe);
-			}
+            }
 
-			String nameanddesc = (name+sig);
-			if (field_names_and_desc.contains(nameanddesc)){
-				throw new ClassConstraintException("No two fields (like '"+tostring(obj)+"') are allowed have same names and descriptors!");
-			}
-			if (field_names.contains(name)){
-				addMessage("More than one field of name '"+name+"' detected (but with different type descriptors). This is very unusual.");
-			}
-			field_names_and_desc.add(nameanddesc);
-			field_names.add(name);
+            String nameanddesc = (name+sig);
+            if (field_names_and_desc.contains(nameanddesc)){
+                throw new ClassConstraintException("No two fields (like '"+tostring(obj)+"') are allowed have same names and descriptors!");
+            }
+            if (field_names.contains(name)){
+                addMessage("More than one field of name '"+name+"' detected (but with different type descriptors). This is very unusual.");
+            }
+            field_names_and_desc.add(nameanddesc);
+            field_names.add(name);
 
-			Attribute[] atts = obj.getAttributes();
+            Attribute[] atts = obj.getAttributes();
             for (Attribute att : atts) {
                 if ((!(att instanceof ConstantValue)) &&
                         (!(att instanceof Synthetic)) &&
@@ -583,105 +583,105 @@ public final class Pass2Verifier extends
                     addMessage("Attribute '" + tostring(att) + "' as an attribute of Field '" + tostring(obj) + "' is not a ConstantValue and is therefore only of use for debuggers and such.");
                 }
             }
-		}
-		///////////////////////////
-		// METHODS (vmspec2 4.6) //
-		///////////////////////////
-		@Override
+        }
+        ///////////////////////////
+        // METHODS (vmspec2 4.6) //
+        ///////////////////////////
+        @Override
         public void visitMethod(Method obj){
 
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+
+            String name = obj.getName();
+            if (! validMethodName(name, true)){
+                throw new ClassConstraintException("Method '"+tostring(obj)+"' has illegal name '"+name+"'.");
+            }
+
+            // A descriptor is often named signature in BCEL
+            checkIndex(obj, obj.getSignatureIndex(), CONST_Utf8);
+
+            String sig  = ((ConstantUtf8) (cp.getConstant(obj.getSignatureIndex()))).getBytes(); // Method's signature(=descriptor)
 
-			String name = obj.getName();
-			if (! validMethodName(name, true)){
-				throw new ClassConstraintException("Method '"+tostring(obj)+"' has illegal name '"+name+"'.");
-			}
-
-			// A descriptor is often named signature in BCEL
-			checkIndex(obj, obj.getSignatureIndex(), CONST_Utf8);
-
-			String sig  = ((ConstantUtf8) (cp.getConstant(obj.getSignatureIndex()))).getBytes(); // Method's signature(=descriptor)
-
-			Type t;
-			Type[] ts; // needed below the try block.
-			try{
-				t  = Type.getReturnType(sig);
-				ts = Type.getArgumentTypes(sig);
-			}
-			catch (ClassFormatException cfe){
+            Type t;
+            Type[] ts; // needed below the try block.
+            try{
+                t  = Type.getReturnType(sig);
+                ts = Type.getArgumentTypes(sig);
+            }
+            catch (ClassFormatException cfe){
                 throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by Method '"+tostring(obj)+"'.", cfe);
-			}
+            }
 
-			// Check if referenced objects exist.
-			Type act = t;
-			if (act instanceof ArrayType) {
+            // Check if referenced objects exist.
+            Type act = t;
+            if (act instanceof ArrayType) {
                 act = ((ArrayType) act).getBasicType();
             }
-			if (act instanceof ObjectType){
-				Verifier v = VerifierFactory.getVerifier( ((ObjectType) act).getClassName() );
-				VerificationResult vr = v.doPass1();
-				if (vr != VerificationResult.VR_OK) {
-					throw new ClassConstraintException("Method '"+tostring(obj)+"' has a return type that does not pass verification pass 1: '"+vr+"'.");
-				}
-			}
-
-			for (Type element : ts) {
-				act = element;
-				if (act instanceof ArrayType) {
+            if (act instanceof ObjectType){
+                Verifier v = VerifierFactory.getVerifier( ((ObjectType) act).getClassName() );
+                VerificationResult vr = v.doPass1();
+                if (vr != VerificationResult.VR_OK) {
+                    throw new ClassConstraintException("Method '"+tostring(obj)+"' has a return type that does not pass verification pass 1: '"+vr+"'.");
+                }
+            }
+
+            for (Type element : ts) {
+                act = element;
+                if (act instanceof ArrayType) {
                     act = ((ArrayType) act).getBasicType();
                 }
-				if (act instanceof ObjectType){
-					Verifier v = VerifierFactory.getVerifier( ((ObjectType) act).getClassName() );
-					VerificationResult vr = v.doPass1();
-					if (vr != VerificationResult.VR_OK) {
-						throw new ClassConstraintException("Method '"+tostring(obj)+"' has an argument type that does not pass verification pass 1: '"+vr+"'.");
-					}
-				}
-			}
-
-			// Nearly forgot this! Funny return values are allowed, but a non-empty arguments list makes a different method out of it!
-			if (name.equals(STATIC_INITIALIZER_NAME) && (ts.length != 0)){
-				throw new ClassConstraintException("Method '"+tostring(obj)+"' has illegal name '"+name+"'. It's name resembles the class or interface initialization method which it isn't because of its arguments (==descriptor).");
-			}
-
-			if (jc.isClass()){
-				int maxone=0;
-				if (obj.isPrivate()) {
+                if (act instanceof ObjectType){
+                    Verifier v = VerifierFactory.getVerifier( ((ObjectType) act).getClassName() );
+                    VerificationResult vr = v.doPass1();
+                    if (vr != VerificationResult.VR_OK) {
+                        throw new ClassConstraintException("Method '"+tostring(obj)+"' has an argument type that does not pass verification pass 1: '"+vr+"'.");
+                    }
+                }
+            }
+
+            // Nearly forgot this! Funny return values are allowed, but a non-empty arguments list makes a different method out of it!
+            if (name.equals(STATIC_INITIALIZER_NAME) && (ts.length != 0)){
+                throw new ClassConstraintException("Method '"+tostring(obj)+"' has illegal name '"+name+"'. It's name resembles the class or interface initialization method which it isn't because of its arguments (==descriptor).");
+            }
+
+            if (jc.isClass()){
+                int maxone=0;
+                if (obj.isPrivate()) {
                     maxone++;
                 }
-				if (obj.isProtected()) {
+                if (obj.isProtected()) {
                     maxone++;
                 }
-				if (obj.isPublic()) {
+                if (obj.isPublic()) {
                     maxone++;
                 }
-				if (maxone > 1){
-					throw new ClassConstraintException("Method '"+tostring(obj)+"' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set.");
-				}
+                if (maxone > 1){
+                    throw new ClassConstraintException("Method '"+tostring(obj)+"' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set.");
+                }
 
-				if (obj.isAbstract()){
-					if (obj.isFinal()) {
+                if (obj.isAbstract()){
+                    if (obj.isFinal()) {
                         throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_FINAL modifier set.");
                     }
-					if (obj.isNative()) {
+                    if (obj.isNative()) {
                         throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_NATIVE modifier set.");
                     }
-					if (obj.isPrivate()) {
+                    if (obj.isPrivate()) {
                         throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_PRIVATE modifier set.");
                     }
-					if (obj.isStatic()) {
+                    if (obj.isStatic()) {
                         throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_STATIC modifier set.");
                     }
-					if (obj.isStrictfp()) {
+                    if (obj.isStrictfp()) {
                         throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_STRICT modifier set.");
                     }
-					if (obj.isSynchronized()) {
+                    if (obj.isSynchronized()) {
                         throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_SYNCHRONIZED modifier set.");
                     }
-				}
-			}
-			else{ // isInterface!
-				if (!name.equals(STATIC_INITIALIZER_NAME)){//vmspec2, p.116, 2nd paragraph
+                }
+            }
+            else{ // isInterface!
+                if (!name.equals(STATIC_INITIALIZER_NAME)){//vmspec2, p.116, 2nd paragraph
                     if (jc.getMajor() >= MAJOR_1_8) {
                         if (!(obj.isPublic() ^ obj.isPrivate())) {
                             throw new ClassConstraintException("Interface method '" + tostring(obj) + "' must have exactly one of its ACC_PUBLIC and ACC_PRIVATE modifiers set.");
@@ -711,43 +711,43 @@ public final class Pass2Verifier extends
                         }
                     }
                 }
-			}
+            }
+
+            // A specific instance initialization method... (vmspec2,Page 116).
+            if (name.equals(CONSTRUCTOR_NAME)){
+                //..may have at most one of ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC set: is checked above.
+                //..may also have ACC_STRICT set, but none of the other flags in table 4.5 (vmspec2, page 115)
+                if (    obj.isStatic() ||
+                            obj.isFinal() ||
+                            obj.isSynchronized() ||
+                            obj.isNative() ||
+                            obj.isAbstract() ){
+                    throw new ClassConstraintException("Instance initialization method '"+tostring(obj)+"' must not have any of the ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT modifiers set.");
+                }
+            }
 
-			// A specific instance initialization method... (vmspec2,Page 116).
-			if (name.equals(CONSTRUCTOR_NAME)){
-				//..may have at most one of ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC set: is checked above.
-				//..may also have ACC_STRICT set, but none of the other flags in table 4.5 (vmspec2, page 115)
-				if (	obj.isStatic() ||
-							obj.isFinal() ||
-							obj.isSynchronized() ||
-							obj.isNative() ||
-							obj.isAbstract() ){
-					throw new ClassConstraintException("Instance initialization method '"+tostring(obj)+"' must not have any of the ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT modifiers set.");
-				}
-			}
-
-			// Class and interface initialization methods...
-			if (name.equals(STATIC_INITIALIZER_NAME)){
-				if ((obj.getAccessFlags() & (~ACC_STRICT)) > 0){
-					addMessage("Class or interface initialization method '"+tostring(obj)+"' has superfluous access modifier(s) set: everything but ACC_STRICT is ignored.");
-				}
-				if (obj.isAbstract()){
-					throw new ClassConstraintException("Class or interface initialization method '"+tostring(obj)+"' must not be abstract. This contradicts the Java Language Specification, Second Edition (which omits this constraint) but is common practice of existing verifiers.");
-				}
-			}
-
-			if ((obj.getAccessFlags() & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_STATIC|ACC_FINAL|ACC_SYNCHRONIZED|ACC_NATIVE|ACC_ABSTRACT|ACC_STRICT)) > 0){
-				addMessage("Method '"+tostring(obj)+"' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT set (ignored).");
-			}
-
-			String nameanddesc = (name+sig);
-			if (method_names_and_desc.contains(nameanddesc)){
-				throw new ClassConstraintException("No two methods (like '"+tostring(obj)+"') are allowed have same names and desciptors!");
-			}
-			method_names_and_desc.add(nameanddesc);
+            // Class and interface initialization methods...
+            if (name.equals(STATIC_INITIALIZER_NAME)){
+                if ((obj.getAccessFlags() & (~ACC_STRICT)) > 0){
+                    addMessage("Class or interface initialization method '"+tostring(obj)+"' has superfluous access modifier(s) set: everything but ACC_STRICT is ignored.");
+                }
+                if (obj.isAbstract()){
+                    throw new ClassConstraintException("Class or interface initialization method '"+tostring(obj)+"' must not be abstract. This contradicts the Java Language Specification, Second Edition (which omits this constraint) but is common practice of existing verifiers.");
+                }
+            }
 
-			Attribute[] atts = obj.getAttributes();
-			int num_code_atts = 0;
+            if ((obj.getAccessFlags() & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_STATIC|ACC_FINAL|ACC_SYNCHRONIZED|ACC_NATIVE|ACC_ABSTRACT|ACC_STRICT)) > 0){
+                addMessage("Method '"+tostring(obj)+"' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT set (ignored).");
+            }
+
+            String nameanddesc = (name+sig);
+            if (method_names_and_desc.contains(nameanddesc)){
+                throw new ClassConstraintException("No two methods (like '"+tostring(obj)+"') are allowed have same names and desciptors!");
+            }
+            method_names_and_desc.add(nameanddesc);
+
+            Attribute[] atts = obj.getAttributes();
+            int num_code_atts = 0;
             for (Attribute att : atts) {
                 if ((!(att instanceof Code)) &&
                         (!(att instanceof ExceptionTable)) &&
@@ -766,723 +766,723 @@ public final class Pass2Verifier extends
                     num_code_atts++;
                 }
             }
-			if ( !obj.isNative() && !obj.isAbstract() && num_code_atts != 1){
-				throw new ClassConstraintException("Non-native, non-abstract methods like '"+tostring(obj)+"' must have exactly one Code attribute (found: "+num_code_atts+").");
-			}
-		}
-		///////////////////////////////////////////////////////
-		// ClassFile-structure-ATTRIBUTES (vmspec2 4.1, 4.7) //
-		///////////////////////////////////////////////////////
-		@Override
+            if ( !obj.isNative() && !obj.isAbstract() && num_code_atts != 1){
+                throw new ClassConstraintException("Non-native, non-abstract methods like '"+tostring(obj)+"' must have exactly one Code attribute (found: "+num_code_atts+").");
+            }
+        }
+        ///////////////////////////////////////////////////////
+        // ClassFile-structure-ATTRIBUTES (vmspec2 4.1, 4.7) //
+        ///////////////////////////////////////////////////////
+        @Override
         public void visitSourceFile(SourceFile obj){//vmspec2 4.7.7
 
-			// zero or one SourceFile attr per ClassFile: see visitJavaClass()
+            // zero or one SourceFile attr per ClassFile: see visitJavaClass()
+
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+
+            String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
+            if (! name.equals("SourceFile")){
+                throw new ClassConstraintException("The SourceFile attribute '"+tostring(obj)+"' is not correctly named 'SourceFile' but '"+name+"'.");
+            }
+
+            checkIndex(obj, obj.getSourceFileIndex(), CONST_Utf8);
 
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+            String sourcefilename = ((ConstantUtf8) cp.getConstant(obj.getSourceFileIndex())).getBytes(); //==obj.getSourceFileName() ?
+            String sourcefilenamelc = sourcefilename.toLowerCase(Locale.ENGLISH);
 
-			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
-			if (! name.equals("SourceFile")){
-				throw new ClassConstraintException("The SourceFile attribute '"+tostring(obj)+"' is not correctly named 'SourceFile' but '"+name+"'.");
-			}
-
-			checkIndex(obj, obj.getSourceFileIndex(), CONST_Utf8);
-
-			String sourcefilename = ((ConstantUtf8) cp.getConstant(obj.getSourceFileIndex())).getBytes(); //==obj.getSourceFileName() ?
-			String sourcefilenamelc = sourcefilename.toLowerCase(Locale.ENGLISH);
-
-			if (	(sourcefilename.indexOf('/') != -1) ||
-						(sourcefilename.indexOf('\\') != -1) ||
-						(sourcefilename.indexOf(':') != -1) ||
-						(sourcefilenamelc.lastIndexOf(".java") == -1)	){
-				addMessage("SourceFile attribute '"+tostring(obj)+"' has a funny name: remember not to confuse certain parsers working on javap's output. Also, this name ('"+sourcefilename+"') is considered an unqualified (simple) file name only.");
-			}
-		}
-		@Override
+            if (    (sourcefilename.indexOf('/') != -1) ||
+                        (sourcefilename.indexOf('\\') != -1) ||
+                        (sourcefilename.indexOf(':') != -1) ||
+                        (sourcefilenamelc.lastIndexOf(".java") == -1)    ){
+                addMessage("SourceFile attribute '"+tostring(obj)+"' has a funny name: remember not to confuse certain parsers working on javap's output. Also, this name ('"+sourcefilename+"') is considered an unqualified (simple) file name only.");
+            }
+        }
+        @Override
         public void visitDeprecated(Deprecated obj){//vmspec2 4.7.10
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
 
-			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
-			if (! name.equals("Deprecated")){
-				throw new ClassConstraintException("The Deprecated attribute '"+tostring(obj)+"' is not correctly named 'Deprecated' but '"+name+"'.");
-			}
-		}
-		@Override
+            String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
+            if (! name.equals("Deprecated")){
+                throw new ClassConstraintException("The Deprecated attribute '"+tostring(obj)+"' is not correctly named 'Deprecated' but '"+name+"'.");
+            }
+        }
+        @Override
         public void visitSynthetic(Synthetic obj){//vmspec2 4.7.6
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
-			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
-			if (! name.equals("Synthetic")){
-				throw new ClassConstraintException("The Synthetic attribute '"+tostring(obj)+"' is not correctly named 'Synthetic' but '"+name+"'.");
-			}
-		}
-		@Override
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+            String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
+            if (! name.equals("Synthetic")){
+                throw new ClassConstraintException("The Synthetic attribute '"+tostring(obj)+"' is not correctly named 'Synthetic' but '"+name+"'.");
+            }
+        }
+        @Override
         public void visitInnerClasses(InnerClasses obj){//vmspec2 4.7.5
 
-			// exactly one InnerClasses attr per ClassFile if some inner class is refernced: see visitJavaClass()
+            // exactly one InnerClasses attr per ClassFile if some inner class is refernced: see visitJavaClass()
+
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+
+            String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
+            if (! name.equals("InnerClasses")){
+                throw new ClassConstraintException("The InnerClasses attribute '"+tostring(obj)+"' is not correctly named 'InnerClasses' but '"+name+"'.");
+            }
 
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+            InnerClass[] ics = obj.getInnerClasses();
 
-			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
-			if (! name.equals("InnerClasses")){
-				throw new ClassConstraintException("The InnerClasses attribute '"+tostring(obj)+"' is not correctly named 'InnerClasses' but '"+name+"'.");
-			}
-
-			InnerClass[] ics = obj.getInnerClasses();
-
-			for (InnerClass ic : ics) {
-				checkIndex(obj, ic.getInnerClassIndex(), CONST_Class);
-				int outer_idx = ic.getOuterClassIndex();
-				if (outer_idx != 0){
-					checkIndex(obj, outer_idx, CONST_Class);
-				}
-				int innername_idx = ic.getInnerNameIndex();
-				if (innername_idx != 0){
-					checkIndex(obj, innername_idx, CONST_Utf8);
-				}
-				int acc = ic.getInnerAccessFlags();
-				acc = acc & (~ (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT));
-				if (acc != 0){
-					addMessage("Unknown access flag for inner class '"+tostring(ic)+"' set (InnerClasses attribute '"+tostring(obj)+"').");
-				}
-			}
-			// Semantical consistency is not yet checked by Sun, see vmspec2 4.7.5.
-			// [marked TODO in JustIce]
-		}
-		////////////////////////////////////////////////////////
-		// field_info-structure-ATTRIBUTES (vmspec2 4.5, 4.7) //
-		////////////////////////////////////////////////////////
-		@Override
+            for (InnerClass ic : ics) {
+                checkIndex(obj, ic.getInnerClassIndex(), CONST_Class);
+                int outer_idx = ic.getOuterClassIndex();
+                if (outer_idx != 0){
+                    checkIndex(obj, outer_idx, CONST_Class);
+                }
+                int innername_idx = ic.getInnerNameIndex();
+                if (innername_idx != 0){
+                    checkIndex(obj, innername_idx, CONST_Utf8);
+                }
+                int acc = ic.getInnerAccessFlags();
+                acc = acc & (~ (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT));
+                if (acc != 0){
+                    addMessage("Unknown access flag for inner class '"+tostring(ic)+"' set (InnerClasses attribute '"+tostring(obj)+"').");
+                }
+            }
+            // Semantical consistency is not yet checked by Sun, see vmspec2 4.7.5.
+            // [marked TODO in JustIce]
+        }
+        ////////////////////////////////////////////////////////
+        // field_info-structure-ATTRIBUTES (vmspec2 4.5, 4.7) //
+        ////////////////////////////////////////////////////////
+        @Override
         public void visitConstantValue(ConstantValue obj){//vmspec2 4.7.2
-			// Despite its name, this really is an Attribute,
-			// not a constant!
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
-
-			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
-			if (! name.equals("ConstantValue")){
-				throw new ClassConstraintException("The ConstantValue attribute '"+tostring(obj)+"' is not correctly named 'ConstantValue' but '"+name+"'.");
-			}
-
-			Object pred = carrier.predecessor();
-			if (pred instanceof Field){ //ConstantValue attributes are quite senseless if the predecessor is not a field.
-				Field f = (Field) pred;
-				// Field constraints have been checked before -- so we are safe using their type information.
-				Type field_type = Type.getType(((ConstantUtf8) (cp.getConstant(f.getSignatureIndex()))).getBytes());
-
-				int index = obj.getConstantValueIndex();
-				if ((index < 0) || (index >= cplen)){
-					throw new ClassConstraintException("Invalid index '"+index+"' used by '"+tostring(obj)+"'.");
-				}
-				Constant c = cp.getConstant(index);
-
-				if (CONST_Long.isInstance(c) && field_type.equals(Type.LONG)){
-					return;
-				}
-				if (CONST_Float.isInstance(c) && field_type.equals(Type.FLOAT)){
-					return;
-				}
-				if (CONST_Double.isInstance(c) && field_type.equals(Type.DOUBLE)){
-					return;
-				}
-				if (CONST_Integer.isInstance(c) && (field_type.equals(Type.INT) || field_type.equals(Type.SHORT) || field_type.equals(Type.CHAR) || field_type.equals(Type.BYTE) || field_type.equals(Type.BOOLEAN))){
-					return;
-				}
-				if (CONST_String.isInstance(c) && field_type.equals(Type.STRING)){
-					return;
-				}
-
-				throw new ClassConstraintException("Illegal type of ConstantValue '"+obj+"' embedding Constant '"+c+"'. It is referenced by field '"+tostring(f)+"' expecting a different type: '"+field_type+"'.");
-			}
-		}
-		// SYNTHETIC: see above
-		// DEPRECATED: see above
-		/////////////////////////////////////////////////////////
-		// method_info-structure-ATTRIBUTES (vmspec2 4.6, 4.7) //
-		/////////////////////////////////////////////////////////
-		@Override
+            // Despite its name, this really is an Attribute,
+            // not a constant!
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+
+            String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
+            if (! name.equals("ConstantValue")){
+                throw new ClassConstraintException("The ConstantValue attribute '"+tostring(obj)+"' is not correctly named 'ConstantValue' but '"+name+"'.");
+            }
+
+            Object pred = carrier.predecessor();
+            if (pred instanceof Field){ //ConstantValue attributes are quite senseless if the predecessor is not a field.
+                Field f = (Field) pred;
+                // Field constraints have been checked before -- so we are safe using their type information.
+                Type field_type = Type.getType(((ConstantUtf8) (cp.getConstant(f.getSignatureIndex()))).getBytes());
+
+                int index = obj.getConstantValueIndex();
+                if ((index < 0) || (index >= cplen)){
+                    throw new ClassConstraintException("Invalid index '"+index+"' used by '"+tostring(obj)+"'.");
+                }
+                Constant c = cp.getConstant(index);
+
+                if (CONST_Long.isInstance(c) && field_type.equals(Type.LONG)){
+                    return;
+                }
+                if (CONST_Float.isInstance(c) && field_type.equals(Type.FLOAT)){
+                    return;
+                }
+                if (CONST_Double.isInstance(c) && field_type.equals(Type.DOUBLE)){
+                    return;
+                }
+                if (CONST_Integer.isInstance(c) && (field_type.equals(Type.INT) || field_type.equals(Type.SHORT) || field_type.equals(Type.CHAR) || field_type.equals(Type.BYTE) || field_type.equals(Type.BOOLEAN))){
+                    return;
+                }
+                if (CONST_String.isInstance(c) && field_type.equals(Type.STRING)){
+                    return;
+                }
+
+                throw new ClassConstraintException("Illegal type of ConstantValue '"+obj+"' embedding Constant '"+c+"'. It is referenced by field '"+tostring(f)+"' expecting a different type: '"+field_type+"'.");
+            }
+        }
+        // SYNTHETIC: see above
+        // DEPRECATED: see above
+        /////////////////////////////////////////////////////////
+        // method_info-structure-ATTRIBUTES (vmspec2 4.6, 4.7) //
+        /////////////////////////////////////////////////////////
+        @Override
         public void visitCode(Code obj){//vmspec2 4.7.3
-		    try {
-			// No code attribute allowed for native or abstract methods: see visitMethod(Method).
-			// Code array constraints are checked in Pass3 (3a and 3b).
-
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
-
-			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
-			if (! name.equals("Code")){
-				throw new ClassConstraintException("The Code attribute '"+tostring(obj)+"' is not correctly named 'Code' but '"+name+"'.");
-			}
-
-			Method m = null; // satisfy compiler
-			if (!(carrier.predecessor() instanceof Method)){
-				addMessage("Code attribute '"+tostring(obj)+"' is not declared in a method_info structure but in '"+carrier.predecessor()+"'. Ignored.");
-				return;
-			}
-			else{
-				m = (Method) carrier.predecessor();	// we can assume this method was visited before;
-																						// i.e. the data consistency was verified.
-			}
-
-			if (obj.getCode().length == 0){
-				throw new ClassConstraintException("Code array of Code attribute '"+tostring(obj)+"' (method '"+m+"') must not be empty.");
-			}
-
-			//In JustIce, the check for correct offsets into the code array is delayed to Pass 3a.
-			CodeException[] exc_table = obj.getExceptionTable();
-			for (CodeException element : exc_table) {
-				int exc_index = element.getCatchType();
-				if (exc_index != 0){ // if 0, it catches all Throwables
-					checkIndex(obj, exc_index, CONST_Class);
-					ConstantClass cc = (ConstantClass) (cp.getConstant(exc_index));
-					checkIndex(cc, cc.getNameIndex(), CONST_Utf8); // cannot be sure this ConstantClass has already been visited (checked)!
-					String cname = ((ConstantUtf8) cp.getConstant(cc.getNameIndex())).getBytes().replace('/','.');
-
-					Verifier v = VerifierFactory.getVerifier(cname);
-					VerificationResult vr = v.doPass1();
-
-					if (vr != VerificationResult.VR_OK){
-						throw new ClassConstraintException("Code attribute '"+tostring(obj)+"' (method '"+m+"') has an exception_table entry '"+tostring(element)+"' that references '"+cname+"' as an Exception but it does not pass verification pass 1: "+vr);
-					}
-					else{
-						// We cannot safely trust any other "instanceof" mechanism. We need to transitively verify
-						// the ancestor hierarchy.
-						JavaClass e = Repository.lookupClass(cname);
-						JavaClass t = Repository.lookupClass(Type.THROWABLE.getClassName());
-						JavaClass o = Repository.lookupClass(Type.OBJECT.getClassName());
-						while (e != o){
-							if (e == t) {
+            try {
+            // No code attribute allowed for native or abstract methods: see visitMethod(Method).
+            // Code array constraints are checked in Pass3 (3a and 3b).
+
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+
+            String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
+            if (! name.equals("Code")){
+                throw new ClassConstraintException("The Code attribute '"+tostring(obj)+"' is not correctly named 'Code' but '"+name+"'.");
+            }
+
+            Method m = null; // satisfy compiler
+            if (!(carrier.predecessor() instanceof Method)){
+                addMessage("Code attribute '"+tostring(obj)+"' is not declared in a method_info structure but in '"+carrier.predecessor()+"'. Ignored.");
+                return;
+            }
+            else{
+                m = (Method) carrier.predecessor();    // we can assume this method was visited before;
+                                                                                        // i.e. the data consistency was verified.
+            }
+
+            if (obj.getCode().length == 0){
+                throw new ClassConstraintException("Code array of Code attribute '"+tostring(obj)+"' (method '"+m+"') must not be empty.");
+            }
+
+            //In JustIce, the check for correct offsets into the code array is delayed to Pass 3a.
+            CodeException[] exc_table = obj.getExceptionTable();
+            for (CodeException element : exc_table) {
+                int exc_index = element.getCatchType();
+                if (exc_index != 0){ // if 0, it catches all Throwables
+                    checkIndex(obj, exc_index, CONST_Class);
+                    ConstantClass cc = (ConstantClass) (cp.getConstant(exc_index));
+                    checkIndex(cc, cc.getNameIndex(), CONST_Utf8); // cannot be sure this ConstantClass has already been visited (checked)!
+                    String cname = ((ConstantUtf8) cp.getConstant(cc.getNameIndex())).getBytes().replace('/','.');
+
+                    Verifier v = VerifierFactory.getVerifier(cname);
+                    VerificationResult vr = v.doPass1();
+
+                    if (vr != VerificationResult.VR_OK){
+                        throw new ClassConstraintException("Code attribute '"+tostring(obj)+"' (method '"+m+"') has an exception_table entry '"+tostring(element)+"' that references '"+cname+"' as an Exception but it does not pass verification pass 1: "+vr);
+                    }
+                    else{
+                        // We cannot safely trust any other "instanceof" mechanism. We need to transitively verify
+                        // the ancestor hierarchy.
+                        JavaClass e = Repository.lookupClass(cname);
+                        JavaClass t = Repository.lookupClass(Type.THROWABLE.getClassName());
+                        JavaClass o = Repository.lookupClass(Type.OBJECT.getClassName());
+                        while (e != o){
+                            if (e == t) {
                                 break; // It's a subclass of Throwable, OKAY, leave.
                             }
 
-							v = VerifierFactory.getVerifier(e.getSuperclassName());
-							vr = v.doPass1();
-							if (vr != VerificationResult.VR_OK){
-								throw new ClassConstraintException("Code attribute '"+tostring(obj)+"' (method '"+m+"') has an exception_table entry '"+tostring(element)+"' that references '"+cname+"' as an Exception but '"+e.getSuperclassName()+"' in the ancestor hierachy does not pass verification pass 1: "+vr);
-							}
-							else{
-								e = Repository.lookupClass(e.getSuperclassName());
-							}
-						}
-						if (e != t) {
+                            v = VerifierFactory.getVerifier(e.getSuperclassName());
+                            vr = v.doPass1();
+                            if (vr != VerificationResult.VR_OK){
+                                throw new ClassConstraintException("Code attribute '"+tostring(obj)+"' (method '"+m+"') has an exception_table entry '"+tostring(element)+"' that references '"+cname+"' as an Exception but '"+e.getSuperclassName()+"' in the ancestor hierachy does not pass verification pass 1: "+vr);
+                            }
+                            else{
+                                e = Repository.lookupClass(e.getSuperclassName());
+                            }
+                        }
+                        if (e != t) {
                             throw new ClassConstraintException("Code attribute '"+tostring(obj)+"' (method '"+m+"') has an exception_table entry '"+tostring(element)+"' that references '"+cname+"' as an Exception but it is not a subclass of '"+t.getClassName()+"'.");
                         }
-					}
-				}
-			}
-
-			// Create object for local variables information
-			// This is highly unelegant due to usage of the Visitor pattern.
-			// TODO: rework it.
-			int method_number = -1;
-			Method[] ms = Repository.lookupClass(myOwner.getClassName()).getMethods();
-			for (int mn=0; mn<ms.length; mn++){
-				if (m == ms[mn]){
-					method_number = mn;
-					break;
-				}
-			}
-			if (method_number < 0){ // Mmmmh. Can we be sure BCEL does not sometimes instantiate new objects?
-				throw new AssertionViolatedException("Could not find a known BCEL Method object in the corresponding BCEL JavaClass object.");
-			}
-			localVariablesInfos[method_number] = new LocalVariablesInfo(obj.getMaxLocals());
-
-			int num_of_lvt_attribs = 0;
-			// Now iterate through the attributes the Code attribute has.
-			Attribute[] atts = obj.getAttributes();
-			for (int a=0; a<atts.length; a++){
-				if ((! (atts[a] instanceof LineNumberTable)) &&
-				    (! (atts[a] instanceof LocalVariableTable))){
-					addMessage("Attribute '"+tostring(atts[a])+"' as an attribute of Code attribute '"+tostring(obj)+"' (method '"+m+"') is unknown and will therefore be ignored.");
-				}
-				else{// LineNumberTable or LocalVariableTable
-					addMessage("Attribute '"+tostring(atts[a])+"' as an attribute of Code attribute '"+tostring(obj)+"' (method '"+m+"') will effectively be ignored and is only useful for debuggers and such.");
-				}
-
-				//LocalVariableTable check (partially delayed to Pass3a).
-				//Here because its easier to collect the information of the
-				//(possibly more than one) LocalVariableTables belonging to
-				//one certain Code attribute.
-				if (atts[a] instanceof LocalVariableTable){ // checks conforming to vmspec2 4.7.9
-
-					LocalVariableTable lvt = (LocalVariableTable) atts[a];
-
-					checkIndex(lvt, lvt.getNameIndex(), CONST_Utf8);
-
-					String lvtname = ((ConstantUtf8) cp.getConstant(lvt.getNameIndex())).getBytes();
-					if (! lvtname.equals("LocalVariableTable")){
-						throw new ClassConstraintException("The LocalVariableTable attribute '"+tostring(lvt)+"' is not correctly named 'LocalVariableTable' but '"+lvtname+"'.");
-					}
-
-					Code code = obj;
-
-					//In JustIce, the check for correct offsets into the code array is delayed to Pass 3a.
-					LocalVariable[] localvariables = lvt.getLocalVariableTable();
-
-					for (LocalVariable localvariable : localvariables) {
-						checkIndex(lvt, localvariable.getNameIndex(), CONST_Utf8);
-						String localname = ((ConstantUtf8) cp.getConstant(localvariable.getNameIndex())).getBytes();
-						if (!validJavaIdentifier(localname)){
-							throw new ClassConstraintException("LocalVariableTable '"+tostring(lvt)+"' references a local variable by the name '"+localname+"' which is not a legal Java simple name.");
-						}
-
-						checkIndex(lvt, localvariable.getSignatureIndex(), CONST_Utf8);
-						String localsig  = ((ConstantUtf8) (cp.getConstant(localvariable.getSignatureIndex()))).getBytes(); // Local signature(=descriptor)
-						Type t;
-						try{
-							t = Type.getType(localsig);
-						}
-						catch (ClassFormatException cfe){
-							throw new ClassConstraintException("Illegal descriptor (==signature) '"+localsig+"' used by LocalVariable '"+tostring(localvariable)+"' referenced by '"+tostring(lvt)+"'.", cfe);
-						}
-						int localindex = localvariable.getIndex();
-						if ( ( (t==Type.LONG || t==Type.DOUBLE)? localindex+1:localindex) >= code.getMaxLocals()){
-							throw new ClassConstraintException("LocalVariableTable attribute '"+tostring(lvt)+"' references a LocalVariable '"+tostring(localvariable)+"' with an index that exceeds the surrounding Code attribute's max_locals value of '"+code.getMaxLocals()+"'.");
-						}
-
-						try{
-							localVariablesInfos[method_number].add(localindex, localname, localvariable.getStartPC(), localvariable.getLength(), t);
-						}
-						catch(LocalVariableInfoInconsistentException lviie){
-							throw new ClassConstraintException("Conflicting information in LocalVariableTable '"+tostring(lvt)+"' found in Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"'). "+lviie.getMessage(), lviie);
-						}
-					}// for all local variables localvariables[i] in the LocalVariableTable attribute atts[a] END
-
-					num_of_lvt_attribs++;
-					if (!m.isStatic() && num_of_lvt_attribs > obj.getMaxLocals()){
-						throw new ClassConstraintException("Number of LocalVariableTable attributes of Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"') exceeds number of local variable slots '"+obj.getMaxLocals()+"' ('There may be no more than one LocalVariableTable attribute per local variable in the Code attribute.').");
-					}
-				}// if atts[a] instanceof LocalVariableTable END
-			}// for all attributes atts[a] END
-
-		    } catch (ClassNotFoundException e) {
-			// FIXME: this might not be the best way to handle missing classes.
-			throw new AssertionViolatedException("Missing class: " + e, e);
-		    }
+                    }
+                }
+            }
+
+            // Create object for local variables information
+            // This is highly unelegant due to usage of the Visitor pattern.
+            // TODO: rework it.
+            int method_number = -1;
+            Method[] ms = Repository.lookupClass(myOwner.getClassName()).getMethods();
+            for (int mn=0; mn<ms.length; mn++){
+                if (m == ms[mn]){
+                    method_number = mn;
+                    break;
+                }
+            }
+            if (method_number < 0){ // Mmmmh. Can we be sure BCEL does not sometimes instantiate new objects?
+                throw new AssertionViolatedException("Could not find a known BCEL Method object in the corresponding BCEL JavaClass object.");
+            }
+            localVariablesInfos[method_number] = new LocalVariablesInfo(obj.getMaxLocals());
+
+            int num_of_lvt_attribs = 0;
+            // Now iterate through the attributes the Code attribute has.
+            Attribute[] atts = obj.getAttributes();
+            for (int a=0; a<atts.length; a++){
+                if ((! (atts[a] instanceof LineNumberTable)) &&
+                    (! (atts[a] instanceof LocalVariableTable))){
+                    addMessage("Attribute '"+tostring(atts[a])+"' as an attribute of Code attribute '"+tostring(obj)+"' (method '"+m+"') is unknown and will therefore be ignored.");
+                }
+                else{// LineNumberTable or LocalVariableTable
+                    addMessage("Attribute '"+tostring(atts[a])+"' as an attribute of Code attribute '"+tostring(obj)+"' (method '"+m+"') will effectively be ignored and is only useful for debuggers and such.");
+                }
+
+                //LocalVariableTable check (partially delayed to Pass3a).
+                //Here because its easier to collect the information of the
+                //(possibly more than one) LocalVariableTables belonging to
+                //one certain Code attribute.
+                if (atts[a] instanceof LocalVariableTable){ // checks conforming to vmspec2 4.7.9
+
+                    LocalVariableTable lvt = (LocalVariableTable) atts[a];
+
+                    checkIndex(lvt, lvt.getNameIndex(), CONST_Utf8);
+
+                    String lvtname = ((ConstantUtf8) cp.getConstant(lvt.getNameIndex())).getBytes();
+                    if (! lvtname.equals("LocalVariableTable")){
+                        throw new ClassConstraintException("The LocalVariableTable attribute '"+tostring(lvt)+"' is not correctly named 'LocalVariableTable' but '"+lvtname+"'.");
+                    }
 
-		}// visitCode(Code) END
+                    Code code = obj;
 
-		@Override
+                    //In JustIce, the check for correct offsets into the code array is delayed to Pass 3a.
+                    LocalVariable[] localvariables = lvt.getLocalVariableTable();
+
+                    for (LocalVariable localvariable : localvariables) {
+                        checkIndex(lvt, localvariable.getNameIndex(), CONST_Utf8);
+                        String localname = ((ConstantUtf8) cp.getConstant(localvariable.getNameIndex())).getBytes();
+                        if (!validJavaIdentifier(localname)){
+                            throw new ClassConstraintException("LocalVariableTable '"+tostring(lvt)+"' references a local variable by the name '"+localname+"' which is not a legal Java simple name.");
+                        }
+
+                        checkIndex(lvt, localvariable.getSignatureIndex(), CONST_Utf8);
+                        String localsig  = ((ConstantUtf8) (cp.getConstant(localvariable.getSignatureIndex()))).getBytes(); // Local signature(=descriptor)
+                        Type t;
+                        try{
+                            t = Type.getType(localsig);
+                        }
+                        catch (ClassFormatException cfe){
+                            throw new ClassConstraintException("Illegal descriptor (==signature) '"+localsig+"' used by LocalVariable '"+tostring(localvariable)+"' referenced by '"+tostring(lvt)+"'.", cfe);
+                        }
+                        int localindex = localvariable.getIndex();
+                        if ( ( (t==Type.LONG || t==Type.DOUBLE)? localindex+1:localindex) >= code.getMaxLocals()){
+                            throw new ClassConstraintException("LocalVariableTable attribute '"+tostring(lvt)+"' references a LocalVariable '"+tostring(localvariable)+"' with an index that exceeds the surrounding Code attribute's max_locals value of '"+code.getMaxLocals()+"'.");
+                        }
+
+                        try{
+                            localVariablesInfos[method_number].add(localindex, localname, localvariable.getStartPC(), localvariable.getLength(), t);
+                        }
+                        catch(LocalVariableInfoInconsistentException lviie){
+                            throw new ClassConstraintException("Conflicting information in LocalVariableTable '"+tostring(lvt)+"' found in Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"'). "+lviie.getMessage(), lviie);
+                        }
+                    }// for all local variables localvariables[i] in the LocalVariableTable attribute atts[a] END
+
+                    num_of_lvt_attribs++;
+                    if (!m.isStatic() && num_of_lvt_attribs > obj.getMaxLocals()){
+                        throw new ClassConstraintException("Number of LocalVariableTable attributes of Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"') exceeds number of local variable slots '"+obj.getMaxLocals()+"' ('There may be no more than one LocalVariableTable attribute per local variable in the Code attribute.').");
+                    }
+                }// if atts[a] instanceof LocalVariableTable END
+            }// for all attributes atts[a] END
+
+            } catch (ClassNotFoundException e) {
+            // FIXME: this might not be the best way to handle missing classes.
+            throw new AssertionViolatedException("Missing class: " + e, e);
+            }
+
+        }// visitCode(Code) END
+
+        @Override
         public void visitExceptionTable(ExceptionTable obj){//vmspec2 4.7.4
-		    try {
-			// incorrectly named, it's the Exceptions attribute (vmspec2 4.7.4)
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
-
-			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
-			if (! name.equals("Exceptions")){
-				throw new ClassConstraintException("The Exceptions attribute '"+tostring(obj)+"' is not correctly named 'Exceptions' but '"+name+"'.");
-			}
-
-			int[] exc_indices = obj.getExceptionIndexTable();
-
-			for (int exc_indice : exc_indices) {
-				checkIndex(obj, exc_indice, CONST_Class);
-
-				ConstantClass cc = (ConstantClass) (cp.getConstant(exc_indice));
-				checkIndex(cc, cc.getNameIndex(), CONST_Utf8); // cannot be sure this ConstantClass has already been visited (checked)!
-				String cname = ((ConstantUtf8) cp.getConstant(cc.getNameIndex())).getBytes().replace('/','.'); //convert internal notation on-the-fly to external notation
-
-				Verifier v = VerifierFactory.getVerifier(cname);
-				VerificationResult vr = v.doPass1();
-
-				if (vr != VerificationResult.VR_OK){
-					throw new ClassConstraintException("Exceptions attribute '"+tostring(obj)+"' references '"+cname+"' as an Exception but it does not pass verification pass 1: "+vr);
-				}
-				else{
-					// We cannot safely trust any other "instanceof" mechanism. We need to transitively verify
-					// the ancestor hierarchy.
-					JavaClass e = Repository.lookupClass(cname);
-					JavaClass t = Repository.lookupClass(Type.THROWABLE.getClassName());
-					JavaClass o = Repository.lookupClass(Type.OBJECT.getClassName());
-					while (e != o){
-						if (e == t) {
+            try {
+            // incorrectly named, it's the Exceptions attribute (vmspec2 4.7.4)
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+
+            String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
+            if (! name.equals("Exceptions")){
+                throw new ClassConstraintException("The Exceptions attribute '"+tostring(obj)+"' is not correctly named 'Exceptions' but '"+name+"'.");
+            }
+
+            int[] exc_indices = obj.getExceptionIndexTable();
+
+            for (int exc_indice : exc_indices) {
+                checkIndex(obj, exc_indice, CONST_Class);
+
+                ConstantClass cc = (ConstantClass) (cp.getConstant(exc_indice));
+                checkIndex(cc, cc.getNameIndex(), CONST_Utf8); // cannot be sure this ConstantClass has already been visited (checked)!
+                String cname = ((ConstantUtf8) cp.getConstant(cc.getNameIndex())).getBytes().replace('/','.'); //convert internal notation on-the-fly to external notation
+
+                Verifier v = VerifierFactory.getVerifier(cname);
+                VerificationResult vr = v.doPass1();
+
+                if (vr != VerificationResult.VR_OK){
+                    throw new ClassConstraintException("Exceptions attribute '"+tostring(obj)+"' references '"+cname+"' as an Exception but it does not pass verification pass 1: "+vr);
+                }
+                else{
+                    // We cannot safely trust any other "instanceof" mechanism. We need to transitively verify
+                    // the ancestor hierarchy.
+                    JavaClass e = Repository.lookupClass(cname);
+                    JavaClass t = Repository.lookupClass(Type.THROWABLE.getClassName());
+                    JavaClass o = Repository.lookupClass(Type.OBJECT.getClassName());
+                    while (e != o){
+                        if (e == t) {
                             break; // It's a subclass of Throwable, OKAY, leave.
                         }
 
-						v = VerifierFactory.getVerifier(e.getSuperclassName());
-						vr = v.doPass1();
-						if (vr != VerificationResult.VR_OK){
-							throw new ClassConstraintException("Exceptions attribute '"+tostring(obj)+"' references '"+cname+"' as an Exception but '"+e.getSuperclassName()+"' in the ancestor hierachy does not pass verification pass 1: "+vr);
-						}
-						else{
-							e = Repository.lookupClass(e.getSuperclassName());
-						}
-					}
-					if (e != t) {
+                        v = VerifierFactory.getVerifier(e.getSuperclassName());
+                        vr = v.doPass1();
+                        if (vr != VerificationResult.VR_OK){
+                            throw new ClassConstraintException("Exceptions attribute '"+tostring(obj)+"' references '"+cname+"' as an Exception but '"+e.getSuperclassName()+"' in the ancestor hierachy does not pass verification pass 1: "+vr);
+                        }
+                        else{
+                            e = Repository.lookupClass(e.getSuperclassName());
+                        }
+                    }
+                    if (e != t) {
                         throw new ClassConstraintException("Exceptions attribute '"+tostring(obj)+"' references '"+cname+"' as an Exception but it is not a subclass of '"+t.getClassName()+"'.");
                     }
-				}
-			}
+                }
+            }
 
-		    } catch (ClassNotFoundException e) {
-			// FIXME: this might not be the best way to handle missing classes.
-			throw new AssertionViolatedException("Missing class: " + e, e);
-		    }
-		}
-		// SYNTHETIC: see above
-		// DEPRECATED: see above
-		//////////////////////////////////////////////////////////////
-		// code_attribute-structure-ATTRIBUTES (vmspec2 4.7.3, 4.7) //
-		//////////////////////////////////////////////////////////////
-		@Override
+            } catch (ClassNotFoundException e) {
+            // FIXME: this might not be the best way to handle missing classes.
+            throw new AssertionViolatedException("Missing class: " + e, e);
+            }
+        }
+        // SYNTHETIC: see above
+        // DEPRECATED: see above
+        //////////////////////////////////////////////////////////////
+        // code_attribute-structure-ATTRIBUTES (vmspec2 4.7.3, 4.7) //
+        //////////////////////////////////////////////////////////////
+        @Override
         public void visitLineNumberTable(LineNumberTable obj){//vmspec2 4.7.8
-			checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
+            checkIndex(obj, obj.getNameIndex(), CONST_Utf8);
 
-			String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
-			if (! name.equals("LineNumberTable")){
-				throw new ClassConstraintException("The LineNumberTable attribute '"+tostring(obj)+"' is not correctly named 'LineNumberTable' but '"+name+"'.");
-			}
-
-			//In JustIce,this check is delayed to Pass 3a.
-			//LineNumber[] linenumbers = obj.getLineNumberTable();
-			// ...validity check...
+            String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes();
+            if (! name.equals("LineNumberTable")){
+                throw new ClassConstraintException("The LineNumberTable attribute '"+tostring(obj)+"' is not correctly named 'LineNumberTable' but '"+name+"'.");
+            }
+
+            //In JustIce,this check is delayed to Pass 3a.
+            //LineNumber[] linenumbers = obj.getLineNumberTable();

[... 668 lines stripped ...]