You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by sj...@apache.org on 2008/10/08 15:05:44 UTC

svn commit: r702856 [1/3] - in /harmony/enhanced/classlib/trunk: ./ depends/files/ depends/manifests/asm-3.1/ make/ modules/pack200/META-INF/ modules/pack200/src/main/java/org/apache/harmony/pack200/ modules/pack200/src/test/java/org/apache/harmony/pac...

Author: sjanuary
Date: Wed Oct  8 06:05:43 2008
New Revision: 702856

URL: http://svn.apache.org/viewvc?rev=702856&view=rev
Log:
Added ASM dependency for pack200

Added:
    harmony/enhanced/classlib/trunk/depends/manifests/asm-3.1/
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Pack200ClassReader.java   (with props)
    harmony/enhanced/classlib/trunk/modules/pack200/src/test/java/org/apache/harmony/pack200/tests/ArchiveTest.java   (with props)
Modified:
    harmony/enhanced/classlib/trunk/THIRD_PARTY_NOTICES.txt
    harmony/enhanced/classlib/trunk/depends/files/bootclasspath.properties
    harmony/enhanced/classlib/trunk/make/build-java.xml
    harmony/enhanced/classlib/trunk/make/depends.properties
    harmony/enhanced/classlib/trunk/make/depends.xml
    harmony/enhanced/classlib/trunk/modules/pack200/META-INF/MANIFEST.MF
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPMethodOrField.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPNameAndType.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/ClassBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CpBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/FileBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/IcBands.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Segment.java
    harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/SegmentHeader.java

Modified: harmony/enhanced/classlib/trunk/THIRD_PARTY_NOTICES.txt
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/THIRD_PARTY_NOTICES.txt?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/THIRD_PARTY_NOTICES.txt (original)
+++ harmony/enhanced/classlib/trunk/THIRD_PARTY_NOTICES.txt Wed Oct  8 06:05:43 2008
@@ -660,3 +660,38 @@
 dealings in this Font Software without prior written authorization
 from Tavmjong Bah. For further information, contact: tavmjong @ free
 . fr.
+
+
+===============================================================================
+===============================================================================
+
+License notice for ASM
+=======================
+
+ ASM: a very small and fast Java bytecode manipulation framework
+ Copyright (c) 2000-2005 INRIA, France Telecom
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+ 3. Neither the name of the copyright holders nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGE.

Modified: harmony/enhanced/classlib/trunk/depends/files/bootclasspath.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/depends/files/bootclasspath.properties?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/depends/files/bootclasspath.properties (original)
+++ harmony/enhanced/classlib/trunk/depends/files/bootclasspath.properties Wed Oct  8 06:05:43 2008
@@ -202,3 +202,5 @@
 #bootclasspath.47=suncompat.jar
 #bootclasspath.source.47=suncompat-src.jar
 #bootclasspath.source.packageroot.47=/
+
+bootclasspath.48=asm-3.1/asm-3.1.jar

Modified: harmony/enhanced/classlib/trunk/make/build-java.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/make/build-java.xml?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/make/build-java.xml (original)
+++ harmony/enhanced/classlib/trunk/make/build-java.xml Wed Oct  8 06:05:43 2008
@@ -203,6 +203,7 @@
         <copy todir="${hy.jdk}/jre/lib/boot">
             <fileset dir="${depends.jars}">
                 <patternset includes="bcel-5.2/*.jar" />
+                <patternset includes="asm-3.1/*.jar" />
                 <patternset includes="icu4j_3.8/*.jar" />
                 <patternset includes="mx4j_3.0.2/*.jar" />
                 <patternset includes="xalan-j_2.7.0/*.jar" />

Modified: harmony/enhanced/classlib/trunk/make/depends.properties
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/make/depends.properties?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/make/depends.properties (original)
+++ harmony/enhanced/classlib/trunk/make/depends.properties Wed Oct  8 06:05:43 2008
@@ -142,3 +142,9 @@
 bcprov.jar=${bcprov.dir}/bcprov.noidea.jar
 bcprov.url=${depends.url}/jars/bcprov/${bcprov.ver}/bcprov.noidea.jar
 bcprov.md5=30018c46e5c83397ec0b47c6e9c45406
+
+asm.ver=asm-3.1
+asm.dir=${depends.jars}/${asm.ver}
+asm.jar=${asm.dir}/asm-3.1.jar
+asm.url=http://download.forge.objectweb.org/asm/asm-3.1.jar
+asm.md5=4fbe0fd975ecc71480846ce272b483b0

Modified: harmony/enhanced/classlib/trunk/make/depends.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/make/depends.xml?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/make/depends.xml (original)
+++ harmony/enhanced/classlib/trunk/make/depends.xml Wed Oct  8 06:05:43 2008
@@ -47,6 +47,7 @@
         <check-one-file src="${servlet-api.url}" dest="${servlet-api.jar}" />
         <check-one-file src="${dejavu-fonts.url}" dest="${dejavu-fonts.zip}" />
         <check-one-file src="${derby.url}" dest="${derby.jar}" />
+        <check-one-file src="${asm.url}" dest="${asm.jar}" />
     </target>
 
     <target name="-check-win" if="is.windows" depends="-really-check-win" />
@@ -253,6 +254,10 @@
     <download-one-file src="${derby.url}"
                        dest="${derby.jar}"
                        md5="${derby.md5}" />
+
+    <mkdir dir="${asm.dir}" />
+    <download-one-file src="${asm.url}" dest="${asm.jar}"
+                           md5="${asm.md5}" />
     </target>
 
     <target name="-download-win" if="is.windows" depends="-select-win-deps-x86_64,-select-win-deps-x86">

Modified: harmony/enhanced/classlib/trunk/modules/pack200/META-INF/MANIFEST.MF
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/META-INF/MANIFEST.MF?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/META-INF/MANIFEST.MF (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/META-INF/MANIFEST.MF Wed Oct  8 06:05:43 2008
@@ -16,8 +16,7 @@
  java.nio,
  java.util;resolution:=optional,
  java.util.jar;resolution:=optional,
- org.apache.bcel,
- org.apache.bcel.classfile
+ org.objectweb.asm
 Export-Package: org.apache.harmony.pack200,
  org.apache.harmony.unpack200,
  org.apache.harmony.unpack200.bytecode,

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/Archive.java Wed Oct  8 06:05:43 2008
@@ -16,6 +16,7 @@
  */
 package org.apache.harmony.pack200;
 
+import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -27,8 +28,7 @@
 import java.util.jar.JarFile;
 import java.util.jar.JarInputStream;
 
-import org.apache.bcel.classfile.ClassParser;
-import org.apache.bcel.classfile.JavaClass;
+import org.objectweb.asm.ClassReader;
 
 
 /**
@@ -54,29 +54,42 @@
     public void pack() throws Pack200Exception, IOException {
         List classes = new ArrayList();
         List files = new ArrayList();
+        List classNames = new ArrayList();
+        List classModtimes = new ArrayList();
         if(inputStream != null) {
             while(inputStream.available() > 0) {
                 JarEntry jarEntry = inputStream.getNextJarEntry();
                 if(jarEntry != null) {
-                    addJarEntry(jarEntry, inputStream, classes, files);
+                    addJarEntry(jarEntry, new BufferedInputStream(inputStream), classes, classNames, classModtimes, files);
                 }
             }
         } else {
             Enumeration jarEntries = jarFile.entries();
             while(jarEntries.hasMoreElements()) {
                 JarEntry jarEntry = (JarEntry) jarEntries.nextElement();
-                addJarEntry(jarEntry, jarFile.getInputStream(jarEntry), classes, files);
+                addJarEntry(jarEntry, new BufferedInputStream(jarFile.getInputStream(jarEntry)), classes, classNames, classModtimes, files);
             }
         }
-        new Segment().pack(classes, files, outputStream);  // TODO: Multiple segments
+        new Segment().pack(classes, classNames, classModtimes, files, outputStream);  // TODO: Multiple segments
+        outputStream.close();
     }
 
-    private void addJarEntry(JarEntry jarEntry, InputStream stream, List javaClasses, List files) throws IOException, Pack200Exception {
+    private void addJarEntry(JarEntry jarEntry, InputStream stream, List javaClasses, List classNames, List classModtimes, List files) throws IOException, Pack200Exception {
         String name = jarEntry.getName();
         if(name.endsWith(".class")) {
-            ClassParser classParser = new ClassParser(stream, name);
-            JavaClass javaClass = classParser.parse();
-            javaClasses.add(javaClass);
+            long size = jarEntry.getSize();
+            if (size > Integer.MAX_VALUE) {
+                throw new RuntimeException("Large Class!");
+            }
+            byte[] bytes = new byte[(int)size];
+            int read = stream.read(bytes);
+            if(read != size) {
+                throw new RuntimeException("Error reading from stream");
+            }
+            ClassReader classParser = new Pack200ClassReader(bytes);
+            javaClasses.add(classParser);
+            classNames.add(name);
+            classModtimes.add(new Long(jarEntry.getTime()));
         } else {
             // TODO: it's a file...
         }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/AttributeDefinitionBands.java Wed Oct  8 06:05:43 2008
@@ -24,11 +24,6 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.bcel.classfile.Field;
-import org.apache.bcel.classfile.JavaClass;
-import org.apache.bcel.classfile.Method;
-import org.apache.bcel.classfile.Unknown;
-
 /**
  * Attribute Definition bands define how any unknown attributes should be
  * read by the decompressor.
@@ -105,9 +100,9 @@
             attributeDefinitionLayout[i] = cpBands.getCPUtf8(def.layout).getIndex();
         }
 
-        out.write(encodeBandInt(attributeDefinitionHeader, Codec.BYTE1));
-        out.write(encodeBandInt(attributeDefinitionName, Codec.UNSIGNED5));
-        out.write(encodeBandInt(attributeDefinitionLayout, Codec.UNSIGNED5));
+        out.write(encodeBandInt("attributeDefinitionHeader", attributeDefinitionHeader, Codec.BYTE1));
+        out.write(encodeBandInt("attributeDefinitionName", attributeDefinitionName, Codec.UNSIGNED5));
+        out.write(encodeBandInt("attributeDefinitionLayout", attributeDefinitionLayout, Codec.UNSIGNED5));
     }
 
     private int[] addHighIndices(int[] availableIndices) {
@@ -138,26 +133,6 @@
         layouts.put(name, layout);
     }
 
-    public void addUnknownAttribute(Unknown attribute, Object parent) {
-        Map map;
-        if(parent instanceof JavaClass) {
-            map = classAttributes;
-        } else if (parent instanceof Method) {
-            map = methodAttributes;
-        } else if (parent instanceof Field) {
-            map = fieldAttributes;
-        } else {
-            map = codeAttributes;
-        }
-        String name = attribute.getName();
-        List attributes = (List) map.get(name);
-        if(attributes == null) {
-            attributes = new ArrayList();
-            map.put(name, attributes);
-        }
-        attributes.add(attribute);
-    }
-
     private static class AttributeDefinition {
 
         public int index;
@@ -174,10 +149,4 @@
         }
 
     }
-
-    public int getIndex(Unknown attr) {
-        // TODO Auto-generated method stub
-        return 0;
-    }
-
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BandSet.java Wed Oct  8 06:05:43 2008
@@ -33,7 +33,7 @@
         return codec.encode(value);
     }
 
-    public byte[] encodeBandInt(int[] ints, Codec defaultCodec) throws Pack200Exception {
+    public byte[] encodeBandInt(String name, int[] ints, Codec defaultCodec) throws Pack200Exception {
         // TODO non-default codecs
         return defaultCodec.encode(ints);
     }
@@ -49,14 +49,14 @@
         return className.equals(sourceFileName);
     }
 
-    protected byte[] encodeFlags(long[] flags, BHSDCodec loCodec, BHSDCodec hiCodec,
+    protected byte[] encodeFlags(String name, long[] flags, BHSDCodec loCodec, BHSDCodec hiCodec,
             boolean haveHiFlags) throws Pack200Exception {
         if(!haveHiFlags) {
             int[] loBits = new int[flags.length];
             for (int i = 0; i < flags.length; i++) {
                 loBits[i] = (int) flags[i];
             }
-            return encodeBandInt(loBits, loCodec);
+            return encodeBandInt(name, loBits, loCodec);
         } else {
 
             int[] hiBits = new int[flags.length];
@@ -66,8 +66,8 @@
                 hiBits[i] = (int) (l >> 32);
                 loBits[i] = (int) l;
             }
-            byte[] hi = encodeBandInt(hiBits, hiCodec);
-            byte[] lo = encodeBandInt(loBits, loCodec);
+            byte[] hi = encodeBandInt(name, hiBits, hiCodec);
+            byte[] lo = encodeBandInt(name, loBits, loCodec);
             byte[] total = new byte[hi.length + lo.length];
             System.arraycopy(hi, 0, total, 0, hi.length);
             System.arraycopy(lo, 0, total, hi.length + 1, lo.length);
@@ -108,4 +108,25 @@
         return array;
     }
 
+    protected byte[] encodeFlags(String name, long[][] flags, BHSDCodec loCodec, BHSDCodec hiCodec,
+            boolean haveHiFlags) throws Pack200Exception {
+        return encodeFlags(name, flatten(flags), loCodec, hiCodec, haveHiFlags);
+   }
+
+    private long[] flatten(long[][] flags) {
+        int totalSize = 0;
+        for (int i = 0; i < flags.length; i++) {
+            totalSize += flags[i].length;
+        }
+        long[] flatArray = new long[totalSize];
+        int index = 0;
+        for (int i = 0; i < flags.length; i++) {
+            for (int j = 0; j < flags[i].length; j++) {
+                flatArray[index] = flags[i][j];
+                index++;
+            }
+        }
+        return flatArray;
+    }
+
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/BcBands.java Wed Oct  8 06:05:43 2008
@@ -19,437 +19,439 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
-import org.apache.bcel.classfile.Code;
-import org.apache.bcel.classfile.Constant;
-import org.apache.bcel.classfile.ConstantClass;
-import org.apache.bcel.classfile.ConstantDouble;
-import org.apache.bcel.classfile.ConstantFieldref;
-import org.apache.bcel.classfile.ConstantFloat;
-import org.apache.bcel.classfile.ConstantInteger;
-import org.apache.bcel.classfile.ConstantInterfaceMethodref;
-import org.apache.bcel.classfile.ConstantLong;
-import org.apache.bcel.classfile.ConstantMethodref;
-import org.apache.bcel.classfile.ConstantNameAndType;
-import org.apache.bcel.classfile.ConstantPool;
-import org.apache.bcel.classfile.ConstantString;
+import org.objectweb.asm.Label;
 
 /**
  * Bytecode bands
  */
 public class BcBands extends BandSet {
 
-    private CpBands cpBands;
+    private static final Integer MULTIANEWARRAY = new Integer(197);
+    private static final Integer ALOAD_0 = new Integer(42);
+    private final CpBands cpBands;
+    private final Segment segment;
 
-    public BcBands(CpBands cpBands) {
+    public BcBands(CpBands cpBands, Segment segment) {
         this.cpBands = cpBands;
+        this.segment = segment;
     }
 
-    private List bcCodes = new ArrayList();
-    private List bcCaseCount = new ArrayList();
-    private List bcCaseValue = new ArrayList();
-    private List bcByte = new ArrayList();
-    private List bcShort = new ArrayList();
-    private List bcLocal = new ArrayList();
-    private List bcLabel = new ArrayList();
-    private List bcIntref = new ArrayList();
-    private List bcFloatRef = new ArrayList();
-    private List bcLongRef = new ArrayList();
-    private List bcDoubleRef = new ArrayList();
-    private List bcStringRef = new ArrayList();
-    private List bcClassRef = new ArrayList();
-    private List bcFieldRef = new ArrayList();
-    private List bcMethodRef = new ArrayList();
-    private List bcIMethodRef = new ArrayList();
+    private final List bcCodes = new ArrayList();
+    private final List bcCaseCount = new ArrayList();
+    private final List bcCaseValue = new ArrayList();
+    private final List bcByte = new ArrayList();
+    private final List bcShort = new ArrayList();
+    private final List bcLocal = new ArrayList();
+    private final List bcLabel = new ArrayList();
+    private final List bcIntref = new ArrayList();
+    private final List bcFloatRef = new ArrayList();
+    private final List bcLongRef = new ArrayList();
+    private final List bcDoubleRef = new ArrayList();
+    private final List bcStringRef = new ArrayList();
+    private final List bcClassRef = new ArrayList();
+    private final List bcFieldRef = new ArrayList();
+    private final List bcMethodRef = new ArrayList();
+    private final List bcIMethodRef = new ArrayList();
     private List bcThisField = new ArrayList();
-    private List bcSuperField = new ArrayList();
+    private final List bcSuperField = new ArrayList();
     private List bcThisMethod = new ArrayList();
-    private List bcSuperMethod = new ArrayList();
-    private List bcInitRef = new ArrayList();
-//    private List bcEscRef = new ArrayList();
-//    private List bcEscRefSize = new ArrayList();
-//    private List bcEscSize = new ArrayList();
-//    private List bcEscByte = new ArrayList();
-
-    public void addCode(Code obj, String thisClass, String superClass) {
-        ConstantPool cp = obj.getConstantPool();
-        byte[] bytecodes = obj.getCode();
+    private final List bcSuperMethod = new ArrayList();
+    private final List bcInitRef = new ArrayList();
+
+    private String currentClass;
+    private String superClass;
+    private static final Integer WIDE = new Integer(196);
+    private static final Integer INVOKEINTERFACE = new Integer(185);
+    private static final Integer TABLESWITCH = new Integer(170);
+    private static final Integer IINC = new Integer(132);
+    private static final Integer LOOKUPSWITCH = new Integer(171);
+    private static final Integer endMarker = new Integer(255);
+
+    private final List bciRenumbering = new ArrayList();
+    private final Map labelsToOffsets = new HashMap();
+    private int byteCodeOffset;
+    private int renumberedOffset;
+
+    public void setCurrentClass(String name) {
+        currentClass = name;
+    }
+
+    public void setSuperClass(String superName) {
+        superClass = superName;
+    }
+
+    public void finaliseBands() {
+        bcThisField = getIndexInClass(bcThisField);
+        bcThisMethod = getIndexInClass(bcThisMethod);
+    }
+
+    public void pack(OutputStream out) throws IOException, Pack200Exception {
+        out.write(encodeBandInt("bcCodes", listToArray(bcCodes), Codec.BYTE1));
+        out.write(encodeBandInt("bcCaseCount", listToArray(bcCaseCount),
+                Codec.UNSIGNED5));
+        out.write(encodeBandInt("bcCaseValue", listToArray(bcCaseValue),
+                Codec.DELTA5));
+        out.write(encodeBandInt("bcByte", listToArray(bcByte), Codec.BYTE1));
+        out.write(encodeBandInt("bcShort", listToArray(bcShort), Codec.DELTA5));
+        out.write(encodeBandInt("bcLocal", listToArray(bcLocal),
+                Codec.UNSIGNED5));
+        out
+                .write(encodeBandInt("bcLabel", listToArray(bcLabel),
+                        Codec.BRANCH5));
+        out.write(encodeBandInt("bcIntref", cpEntryListToArray(bcIntref),
+                Codec.DELTA5));
+        out.write(encodeBandInt("bcFloatRef", cpEntryListToArray(bcFloatRef),
+                Codec.DELTA5));
+        out.write(encodeBandInt("bcLongRef", cpEntryListToArray(bcLongRef),
+                Codec.DELTA5));
+        out.write(encodeBandInt("bcDoubleRef", cpEntryListToArray(bcDoubleRef),
+                Codec.DELTA5));
+        out.write(encodeBandInt("bcStringRef", cpEntryListToArray(bcStringRef),
+                Codec.DELTA5));
+        out.write(encodeBandInt("bcClassRef",
+                cpEntryOrNullListToArray(bcClassRef), Codec.UNSIGNED5));
+        out.write(encodeBandInt("bcFieldRef", cpEntryListToArray(bcFieldRef),
+                Codec.DELTA5));
+        out.write(encodeBandInt("bcMethodRef", cpEntryListToArray(bcMethodRef),
+                Codec.UNSIGNED5));
+        out.write(encodeBandInt("bcIMethodRef",
+                cpEntryListToArray(bcIMethodRef), Codec.DELTA5));
+        out.write(encodeBandInt("bcThisField", listToArray(bcThisField),
+                Codec.UNSIGNED5));
+        out.write(encodeBandInt("bcSuperField", listToArray(bcSuperField),
+                Codec.UNSIGNED5));
+        out.write(encodeBandInt("bcThisMethod", listToArray(bcThisMethod),
+                Codec.UNSIGNED5));
+        out.write(encodeBandInt("bcSuperMethod",
+                listToArray(bcSuperMethod), Codec.UNSIGNED5));
+        out.write(encodeBandInt("bcInitRef", listToArray(bcInitRef),
+                Codec.UNSIGNED5));
+        // out.write(encodeBandInt(cpEntryListToArray(bcEscRef),
+        // Codec.UNSIGNED5));
+        // out.write(encodeBandInt(listToArray(bcEscRefSize), Codec.UNSIGNED5));
+        // out.write(encodeBandInt(listToArray(bcEscSize), Codec.UNSIGNED5));
+        // out.write(encodeBandInt(listToArray(bcEscByte), Codec.BYTE1));
+    }
+
+    private List getIndexInClass(List cPMethodOrFieldList) {
+        List indices = new ArrayList(cPMethodOrFieldList.size());
+        for (int i = 0; i < cPMethodOrFieldList.size(); i++) {
+            CPMethodOrField cpMF = (CPMethodOrField) cPMethodOrFieldList.get(i);
+            indices.add(new Integer(cpMF.getIndexInClass()));
+        }
+        return indices;
+    }
+
+    public void visitEnd() {
+        for (int i = 0; i < bciRenumbering.size(); i++) {
+            if (bciRenumbering.get(i) == null) {
+                bciRenumbering.remove(i);
+                bciRenumbering.add(i, new Integer(++renumberedOffset));
+            }
+        }
+        if (renumberedOffset + 1 != bciRenumbering.size()) {
+            throw new RuntimeException("Mistake made with renumbering");
+        }
+        for (int i = bcLabel.size() - 1; i >= 0; i--) {
+            Object label = bcLabel.get(i);
+            if (label instanceof Integer) {
+                break;
+            } else if (label instanceof Label) {
+                bcLabel.remove(i);
+                Integer offset = (Integer) labelsToOffsets.get(label);
+                bcLabel.add(i, bciRenumbering.get(offset.intValue()));
+            }
+        }
+        bcCodes.add(endMarker);
+        segment.getClassBands().doBciRenumbering(bciRenumbering,
+                labelsToOffsets);
+        bciRenumbering.clear();
+        labelsToOffsets.clear();
+        byteCodeOffset = 0;
+        renumberedOffset = 0;
+    }
+
+    public void visitLabel(Label label) {
+        labelsToOffsets.put(label, new Integer(byteCodeOffset));
+    }
+
+    public void visitFieldInsn(int opcode, String owner, String name,
+            String desc) {
+        byteCodeOffset += 3;
+        updateRenumbering();
         boolean aload_0 = false;
-        boolean wide = false;
-        for (int i = 0; i < bytecodes.length; i++) {
-            int bytecode = 0xff & bytecodes[i];
-            switch (bytecode) {
-            case 16: // bipush
-            case 17: // sipush
-                bcCodes.add(new Integer(bytecode));
-                byte b1 = bytecodes[++i];
-                byte b2 = bytecodes[++i];
-                short s = (short) (b1 << 8 | b2);
-                bcShort.add(new Integer(s));
-                break;
-            case 18: // ldc
-                Constant constant = cp.getConstant(bytecodes[++i] & 0xFF);
-                if (constant instanceof ConstantInteger) {
-                    bcCodes.add(new Integer(234)); // ildc
-                    bcIntref.add(cpBands.getCPConstant(constant, cp));
-                } else if (constant instanceof ConstantFloat) {
-                    bcCodes.add(new Integer(235)); // fldc
-                    bcFloatRef.add(cpBands.getCPConstant(constant, cp));
-                } else if (constant instanceof ConstantString) {
-                    bcCodes.add(new Integer(18)); // aldc
-                    bcStringRef.add(cpBands.getCPConstant(constant, cp));
-                } else if (constant instanceof ConstantClass) {
-                    bcCodes.add(new Integer(233)); // cldc
-                    bcClassRef.add(cpBands.getCPConstant(constant, cp));
-                }
-                break;
-            case 19: // aldc_w
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                int index = b1 << 8 | b2;
-                constant = cp.getConstant(index);
-                if (constant instanceof ConstantInteger) {
-                    bcCodes.add(new Integer(237)); // ildc_w
-                    bcIntref.add(cpBands.getCPConstant(constant, cp));
-                } else if (constant instanceof ConstantFloat) {
-                    bcCodes.add(new Integer(238)); // fldc_w
-                    bcFloatRef.add(cpBands.getCPConstant(constant, cp));
-                } else if (constant instanceof ConstantString) {
-                    bcCodes.add(new Integer(19)); // aldc_w
-                    bcStringRef.add(cpBands.getCPConstant(constant, cp));
-                } else if (constant instanceof ConstantClass) {
-                    bcCodes.add(new Integer(236)); // cldc_w
-                    bcClassRef.add(cpBands.getCPConstant(constant, cp));
-                }
-                break;
-            case 20: // ldc2_w
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                index = b1 << 8 | b2;
-                constant = cp.getConstant(index);
-                if (constant instanceof ConstantLong) {
-                    bcCodes.add(new Integer(20)); // lldc2_w
-                    bcLongRef.add(cpBands.getCPConstant(constant, cp));
-                } else if (constant instanceof ConstantDouble) {
-                    bcCodes.add(new Integer(239)); // dldc2_w
-                    bcDoubleRef.add(cpBands.getCPConstant(constant, cp));
-                }
-                break;
-            case 21:
-            case 22:
-            case 23:
-            case 24:
-            case 25:
-            case 54:
-            case 55:
-            case 56:
-            case 57:
-            case 58:
-                bcCodes.add(new Integer(bytecode));
-                if(wide) {
-                    b1 = bytecodes[++i];
-                    b2 = bytecodes[++i];
-                    index = b1 << 8 | b2;
-                    bcLocal.add(new Integer(index));
-                    wide = false;
-                } else {
-                    bcLocal.add(new Integer(0xff & bytecodes[++i]));
-                }
-                break;
-            case 42:
-                int next = 0;
-                if(bytecodes.length >= i) {
-                    next = bytecodes[i+1] & 0xFF;
-                }
-                if(next >= 178 && next <= 184) {
-                    aload_0 = true;
-                } else {
-                    bcCodes.add(new Integer(42));
-                }
-                break;
-            case 132: // iinc
-                bcCodes.add(new Integer(132));
-                if(wide) {
-                    b1 = bytecodes[++i];
-                    b2 = bytecodes[++i];
-                    index = b1 << 8 | b2;
-                    b1 = bytecodes[++i];
-                    b2 = bytecodes[++i];
-                    short cnst = (short) (b1 << 8 | b2);
-                    bcLocal.add(new Integer(index));
-                    bcShort.add(new Integer(cnst));
-                    wide = false;
-                } else {
-                    index = bytecodes[++i];
-                    byte cnst = bytecodes[++i];
-                    bcLocal.add(new Integer(index));
-                    bcByte.add(new Integer(cnst));
-                }
-                break;
-            case 153:
-            case 154:
-            case 155:
-            case 156:
-            case 157:
-            case 158:
-            case 159:
-            case 160:
-            case 161:
-            case 162:
-            case 163:
-            case 164:
-            case 165:
-            case 166:
-            case 198:
-            case 199:
-                bcCodes.add(new Integer(bytecode));
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                index = b1 << 8 | b2;
-                bcLabel.add(new Integer(index));
-                break;
-            case 167: // goto
-            case 168: // jsr
-                bcCodes.add(new Integer(bytecode));
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                int offset = b1 << 8 | b2;
-                bcLabel.add(new Integer(offset));
-                break;
-            case 169: // ret
-                bcCodes.add(new Integer(bytecode));
-                if(wide) {
-                    b1 = bytecodes[++i];
-                    b2 = bytecodes[++i];
-                    index = b1 << 8 | b2;
-                    bcLocal.add(new Integer(index));
-                    wide = false;
-                } else {
-                    bcLocal.add(new Integer(0xff & bytecodes[++i]));
-                }
-                break;
-            case 170: // tableswitch
-                bcCodes.add(new Integer(bytecode));
-                int padding = (i + 1) % 4 == 0 ? 0 : 4 - i + 1;
-                i+= padding;
-                b1 = bytecodes[i];
-                b2 = bytecodes[++i];
-                byte b3 = bytecodes[++i];
-                byte b4 = bytecodes[++i];
-                int defaultValue = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                b3 = bytecodes[++i];
-                b4 = bytecodes[++i];
-                int low = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                b3 = bytecodes[++i];
-                b4 = bytecodes[++i];
-                int high = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
-                bcLabel.add(new Integer(defaultValue));
-                bcCaseValue.add(new Integer(low));
-                int count = high - low + 1;
-                bcCaseCount.add(new Integer(count));
-                for (int j = 0; j < count; j++) {
-                    b1 = bytecodes[++i];
-                    b2 = bytecodes[++i];
-                    b3 = bytecodes[++i];
-                    b4 = bytecodes[++i];
-                    int label = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
-                    bcLabel.add(new Integer(label));
-                }
-                break;
-            case 171: // lookupswitch
-                bcCodes.add(new Integer(bytecode));
-                padding = (i + 1) % 4 == 0 ? 0 : 4 - i + 1;
-                i+= padding;
-                b1 = bytecodes[i];
-                b2 = bytecodes[++i];
-                b3 = bytecodes[++i];
-                b4 = bytecodes[++i];
-                defaultValue = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
-                bcLabel.add(new Integer(defaultValue));
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                b3 = bytecodes[++i];
-                b4 = bytecodes[++i];
-                int npairs = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
-                bcCaseCount.add(new Integer(npairs));
-                for (int j = 0; j < npairs; j++) {
-                    b1 = bytecodes[++i];
-                    b2 = bytecodes[++i];
-                    b3 = bytecodes[++i];
-                    b4 = bytecodes[++i];
-                    int caseValue = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
-                    bcCaseValue.add(new Integer(caseValue));
-                    b1 = bytecodes[++i];
-                    b2 = bytecodes[++i];
-                    b3 = bytecodes[++i];
-                    b4 = bytecodes[++i];
-                    int label = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
-                    bcLabel.add(new Integer(label));
-                }
-                break;
-            case 178: // getstatic
-            case 179: // putstatic
-            case 180: // getfield
-            case 181: // putfield
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                index = b1 << 8 | b2;
-                ConstantFieldref cfr = (ConstantFieldref) cp.getConstant(index);
-                String className = cfr.getClass(cp);
-                CPMethodOrField cpField = cpBands.getCPMethodOrField(cfr);
-                if(aload_0) {
-                    bytecode += 7;
-                }
-                if(className.equals(thisClass)) {
-                    bytecode += 24; // change to getstatic_this, putstatic_this etc.
-                    bcThisField.add(cpField);
-                } else if (className.equals(superClass)){
-                    bytecode += 38; // change to getstatic_super etc.
-                    bcSuperField.add(cpField);
-                } else {
-                    if(aload_0) {
-                        bytecode -= 7;
-                        bcCodes.add(new Integer(42)); // add aload_0 back in because there's no special rewrite in this case.
-                    }
-                    bcFieldRef.add(cpField);
-                }
-                aload_0 = false;
-                bcCodes.add(new Integer(bytecode));
-                break;
-            case 182: // invokevirtual
-            case 183: // invokespecial
-            case 184: // invokestatic
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                index = b1 << 8 | b2;
-                ConstantMethodref cmr = (ConstantMethodref) cp.getConstant(index);
-                className = cmr.getClass(cp);
-                CPMethodOrField cpMethod = cpBands.getCPMethodOrField(cmr);
-                if(aload_0) {
-                    bytecode += 7;
-                }
-                if(className.equals(thisClass)) {
-                    if(bytecode == 183) { // invokespecial
-                        ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex());
-                        String name = cnat.getName(cp);
-                        if(name.equals("this")) {
-
-                        }
-                    }
-                    bytecode += 24; // change to invokevirtual_this, invokespecial_this etc.
-                    bcThisMethod.add(cpMethod);
-                } else if(className.equals(superClass)) {
-                    bytecode += 38; // change to invokevirtual_super, invokespecial_super etc.
-                    bcSuperMethod.add(cpMethod);
-                } else {
-                    if(aload_0) {
-                        bytecode -= 7;
-                        bcCodes.add(new Integer(42)); // add aload_0 back in because there's no special rewrite in this case.
-                    }
-                    bcMethodRef.add(cpMethod);
-                }
-                aload_0 = false;
-                bcCodes.add(new Integer(bytecode));
-                break;
-            case 185: // invokeinterface
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                index = b1 << 8 | b2;
-                ConstantInterfaceMethodref cmir = (ConstantInterfaceMethodref) cp.getConstant(index);
-                className = cmir.getClass(cp);
-                CPMethodOrField cpIMethod = cpBands.getCPMethodOrField(cmir);
-                bcIMethodRef.add(cpIMethod);
-                bcCodes.add(new Integer(bytecode));
-                i+= 2; // ignore count and zero fields as this can be recreated by the decompressor
-                break;
-            case 187: // new
-            case 189: // anewarray
-            case 192: // checkcast
-            case 193: // instanceof
-                bcCodes.add(new Integer(bytecode));
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                index = b1 << 8 | b2;
-                ConstantClass constantClass = (ConstantClass) cp.getConstant(index);
-                bcClassRef.add(cpBands.getCPClass(constantClass.getBytes(cp)));
-                break;
-            case 188: // newarray
-                bcCodes.add(new Integer(bytecode));
-                bcByte.add(new Integer(0xff & bytecodes[++i]));
-                break;
-            case 196: // wide
-                bcCodes.add(new Integer(196));
-                wide = true;
-            case 197: // multianewarray
-                bcCodes.add(new Integer(bytecode));
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                index = b1 << 8 | b2;
-                constantClass = (ConstantClass) cp.getConstant(index);
-                bcClassRef.add(cpBands.getCPClass(constantClass.getBytes(cp)));
-                byte dimensions = bytecodes[++i];
-                bcByte.add(new Integer(0xff & dimensions));
-                break;
-            case 200: // goto_w
-            case 201: // jsr_w
-                bcCodes.add(new Integer(bytecode));
-                b1 = bytecodes[++i];
-                b2 = bytecodes[++i];
-                b3 = bytecodes[++i];
-                b4 = bytecodes[++i];
-                offset = b1 << 24 | b2 << 16 | b3 << 8 | b4;
-                bcLabel.add(new Integer(offset));
-                break;
-//   TODO         case 230: // invokespecial_this_init
-//            case 231: // invokespecial_super_init
-//            case 232: // invokespecial_new_init
-//                bcInitRefCount++;
-//                break;
-            default:
-                if(bytecode >= 202) {
-                    throw new RuntimeException("Non-standard bytecode instructions not supported");
-                } else {
-                    bcCodes.add(new Integer(bytecode));
+        if (bcCodes.size() > 0
+                && ((Integer) bcCodes.get(bcCodes.size() - 1)).equals(ALOAD_0)) {
+            bcCodes.remove(bcCodes.size());
+            aload_0 = true;
+        }
+        CPMethodOrField cpField = cpBands.getCPField(owner, name, desc);
+        if (aload_0) {
+            opcode += 7;
+        }
+        if (owner.equals(currentClass)) {
+            opcode += 24; // change to getstatic_this, putstatic_this etc.
+            bcThisField.add(cpField);
+//        } else if (owner.equals(superClass)) {
+//            opcode += 38; // change to getstatic_super etc.
+//            bcSuperField.add(cpField);
+        } else {
+            if (aload_0) {
+                opcode -= 7;
+                bcCodes.add(ALOAD_0); // add aload_0 back in because
+                // there's no special rewrite in
+                // this case.
+            }
+            bcFieldRef.add(cpField);
+        }
+        aload_0 = false;
+        bcCodes.add(new Integer(opcode));
+    }
+
+    private void updateRenumbering() {
+        if(bciRenumbering.isEmpty()) {
+            bciRenumbering.add(new Integer(0));
+        }
+        renumberedOffset ++;
+        for (int i = bciRenumbering.size(); i < byteCodeOffset; i++) {
+            bciRenumbering.add(null);
+        }
+        bciRenumbering.add(new Integer(renumberedOffset));
+    }
+
+    public void visitIincInsn(int var, int increment) {
+        if (increment > Byte.MAX_VALUE) {
+            byteCodeOffset += 6;
+            bcCodes.add(WIDE);
+            bcCodes.add(IINC);
+            bcLocal.add(new Integer(var));
+            bcShort.add(new Integer(increment));
+        } else {
+            byteCodeOffset += 3;
+            bcCodes.add(IINC);
+            bcLocal.add(new Integer(var));
+            bcByte.add(new Integer(increment));
+        }
+        updateRenumbering();
+    }
+
+    public void visitInsn(int opcode) {
+        if (opcode >= 202) {
+            throw new RuntimeException(
+                    "Non-standard bytecode instructions not supported");
+        } else {
+            bcCodes.add(new Integer(opcode));
+            byteCodeOffset++;
+            updateRenumbering();
+        }
+    }
+
+    public void visitIntInsn(int opcode, int operand) {
+        switch (opcode) {
+        case 17: // sipush
+            bcCodes.add(new Integer(opcode));
+            bcShort.add(new Integer(operand));
+            byteCodeOffset += 3;
+            break;
+        case 16: // bipush
+        case 188: // newarray
+            bcCodes.add(new Integer(opcode));
+            bcByte.add(new Integer(operand));
+            byteCodeOffset += 2;
+        }
+        updateRenumbering();
+    }
+
+    public void visitJumpInsn(int opcode, Label label) {
+        byteCodeOffset += 3;
+        updateRenumbering();
+        bcCodes.add(new Integer(opcode));
+        bcLabel.add(label);
+    }
+
+    public void visitLdcInsn(Object cst) {
+        CPConstant constant = cpBands.getConstant(cst);
+        if (segment.lastConstantHadWideIndex() || constant instanceof CPLong
+                || constant instanceof CPDouble) {
+            byteCodeOffset += 3;
+            if (constant instanceof CPInt) {
+                bcCodes.add(new Integer(237)); // ildc_w
+                bcIntref.add(constant);
+            } else if (constant instanceof CPFloat) {
+                bcCodes.add(new Integer(238)); // fldc
+                bcFloatRef.add(constant);
+            } else if (constant instanceof CPLong) {
+                bcCodes.add(new Integer(20)); // lldc2_w
+                bcLongRef.add(constant);
+            } else if (constant instanceof CPDouble) {
+                bcCodes.add(new Integer(239)); // dldc2_w
+                bcDoubleRef.add(constant);
+            } else if (constant instanceof CPString) {
+                bcCodes.add(new Integer(19)); // aldc
+                bcStringRef.add(constant);
+            } else if (constant instanceof CPClass) {
+                bcCodes.add(new Integer(236)); // cldc
+                bcClassRef.add(constant);
+            }
+        } else {
+            byteCodeOffset += 2;
+            if (constant instanceof CPInt) {
+                bcCodes.add(new Integer(234)); // ildc
+                bcIntref.add(constant);
+            } else if (constant instanceof CPFloat) {
+                bcCodes.add(new Integer(235)); // fldc
+                bcFloatRef.add(constant);
+            } else if (constant instanceof CPString) {
+                bcCodes.add(new Integer(18)); // aldc
+                bcStringRef.add(constant);
+            } else if (constant instanceof CPClass) {
+                bcCodes.add(new Integer(233)); // cldc
+                bcClassRef.add(constant);
+            }
+        }
+        updateRenumbering();
+    }
+
+    public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
+        int padding = (byteCodeOffset + 1) % 4 == 0 ? 0 : 4 - byteCodeOffset + 1;
+        byteCodeOffset += padding + 8 + 8 * keys.length;
+        updateRenumbering();
+        bcCodes.add(LOOKUPSWITCH);
+        bcLabel.add(dflt);
+        bcCaseCount.add(new Integer(keys.length));
+        for (int i = 0; i < labels.length; i++) {
+            bcCaseValue.add(new Integer(keys[i]));
+            bcLabel.add(labels[i]);
+        }
+    }
+
+    public void visitMethodInsn(int opcode, String owner, String name,
+            String desc) {
+        byteCodeOffset += 3;
+        updateRenumbering();
+        switch (opcode) {
+        case 182: // invokevirtual
+        case 183: // invokespecial
+        case 184: // invokestatic
+            boolean aload_0 = false;
+            if (bcCodes.size() > 0
+                    && ((Integer) bcCodes.get(bcCodes.size() - 1))
+                            .equals(ALOAD_0)) {
+                bcCodes.remove(bcCodes.size() - 1);
+                aload_0 = true;
+                opcode += 7;
+            }
+
+//            if (opcode == 183 && name.equals("<init>") && !aload_0
+//                    && owner.equals(currentClass)) {
+//                opcode = 230;
+//            } else if (opcode == 183 && name.equals("<init>") && !aload_0
+//                    && owner.equals(superClass)) {
+//                opcode = 231;
+//                // TODO: 232
+//            } else
+            if (owner.equals(currentClass)) {
+                opcode += 24; // change to invokevirtual_this,
+                // invokespecial_this etc.
+                bcThisMethod.add(cpBands.getCPMethod(owner, name, desc));
+//            } else if (owner.equals(superClass)) { // TODO
+//                opcode += 38; // change to invokevirtual_super,
+//                // invokespecial_super etc.
+//                bcSuperMethod.add(cpBands.getCPMethod(owner, name, desc));
+            } else {
+                if (aload_0) {
+                    opcode -= 7;
+                    bcCodes.add(ALOAD_0); // add aload_0 back in
+                    // because there's no
+                    // special rewrite in this
+                    // case.
                 }
+                bcMethodRef.add(cpBands.getCPMethod(owner, name, desc));
             }
+            bcCodes.add(new Integer(opcode));
+            break;
+        case 185: // invokeinterface
+            CPMethodOrField cpIMethod = cpBands.getCPIMethod(owner, name, desc);
+            bcIMethodRef.add(cpIMethod);
+            bcCodes.add(INVOKEINTERFACE);
+            break;
         }
     }
 
-    public void finaliseBands() {
+    public void visitMultiANewArrayInsn(String desc, int dimensions) {
+        byteCodeOffset += 4;
+        updateRenumbering();
+        bcCodes.add(MULTIANEWARRAY);
+        bcClassRef.add(cpBands.getCPClass(desc));
+        bcByte.add(new Integer(dimensions));
+    }
+
+    public void visitTableSwitchInsn(int min, int max, Label dflt,
+            Label[] labels) {
+        int padding = (byteCodeOffset + 1) % 4 == 0 ? 0 : 4 - byteCodeOffset + 1;
+        byteCodeOffset+= (padding + 12 + 4 * labels.length);
+        updateRenumbering();
+        bcCodes.add(TABLESWITCH);
+        bcLabel.add(dflt);
+        bcCaseValue.add(new Integer(min));
+        int count = labels.length;
+        bcCaseCount.add(new Integer(count));
+        for (int i = 0; i < count; i++) {
+            bcLabel.add(labels[i]);
+        }
+    }
 
+    public void visitTypeInsn(int opcode, String type) {
+        // NEW, ANEWARRAY, CHECKCAST or INSTANCEOF
+        byteCodeOffset += 3;
+        updateRenumbering();
+        bcCodes.add(new Integer(opcode));
+        bcClassRef.add(cpBands.getCPClass(type));
     }
 
-    public void pack(OutputStream out) throws IOException, Pack200Exception {
-        out.write(encodeBandInt(listToArray(bcCodes), Codec.BYTE1));
-        out.write(encodeBandInt(listToArray(bcCaseCount), Codec.UNSIGNED5));
-        out.write(encodeBandInt(listToArray(bcCaseValue), Codec.DELTA5));
-        out.write(encodeBandInt(listToArray(bcByte), Codec.BYTE1));
-        out.write(encodeBandInt(listToArray(bcShort), Codec.DELTA5));
-        out.write(encodeBandInt(listToArray(bcLocal), Codec.UNSIGNED5));
-        out.write(encodeBandInt(listToArray(bcLabel), Codec.BRANCH5));
-        out.write(encodeBandInt(cpEntryListToArray(bcIntref), Codec.DELTA5));
-        out.write(encodeBandInt(cpEntryListToArray(bcFloatRef), Codec.DELTA5));
-        out.write(encodeBandInt(cpEntryListToArray(bcLongRef), Codec.DELTA5));
-        out.write(encodeBandInt(cpEntryListToArray(bcDoubleRef), Codec.DELTA5));
-        out.write(encodeBandInt(cpEntryListToArray(bcStringRef), Codec.DELTA5));
-        out.write(encodeBandInt(cpEntryOrNullListToArray(bcClassRef), Codec.UNSIGNED5));
-        out.write(encodeBandInt(cpEntryListToArray(bcFieldRef), Codec.DELTA5));
-        out.write(encodeBandInt(cpEntryListToArray(bcMethodRef), Codec.UNSIGNED5));
-        out.write(encodeBandInt(cpEntryListToArray(bcIMethodRef), Codec.DELTA5));
-        out.write(encodeBandInt(listToArray(bcThisField), Codec.UNSIGNED5));
-        out.write(encodeBandInt(listToArray(bcSuperField), Codec.UNSIGNED5));
-        out.write(encodeBandInt(listToArray(bcThisMethod), Codec.UNSIGNED5));
-        out.write(encodeBandInt(listToArray(bcSuperMethod), Codec.UNSIGNED5));
-        out.write(encodeBandInt(listToArray(bcInitRef), Codec.UNSIGNED5));
-//        out.write(encodeBandInt(cpEntryListToArray(bcEscRef), Codec.UNSIGNED5));
-//        out.write(encodeBandInt(listToArray(bcEscRefSize), Codec.UNSIGNED5));
-//        out.write(encodeBandInt(listToArray(bcEscSize), Codec.UNSIGNED5));
-//        out.write(encodeBandInt(listToArray(bcEscByte), Codec.BYTE1));
+    public void visitVarInsn(int opcode, int var) {
+        // ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET
+        if (var > Byte.MAX_VALUE) {
+            byteCodeOffset += 4;
+            bcCodes.add(WIDE);
+            bcCodes.add(new Integer(opcode));
+            bcLocal.add(new Integer(var));
+        } else {
+            if(var > 3 || opcode == 169 /* RET */) {
+                byteCodeOffset += 2;
+                bcCodes.add(new Integer(opcode));
+                bcLocal.add(new Integer(var));
+            } else {
+                byteCodeOffset +=1;
+                switch(opcode) {
+                case 21: // ILOAD
+                case 54: // ISTORE
+                    bcCodes.add(new Integer(opcode + 5 + var));
+                    break;
+                case 22: // LLOAD
+                case 55: // LSTORE
+                    bcCodes.add(new Integer(opcode + 8 + var));
+                    break;
+                case 23: // FLOAD
+                case 56: // FSTORE
+                    bcCodes.add(new Integer(opcode + 11 + var));
+                    break;
+                case 24: // DLOAD
+                case 57: // DSTORE
+                    bcCodes.add(new Integer(opcode + 14 + var));
+                    break;
+                case 25: // A_LOAD
+                case 58: // A_STORE
+                    bcCodes.add(new Integer(opcode + 17 + var));
+                    break;
+                }
+            }
+        }
+        updateRenumbering();
     }
 
 }

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPMethodOrField.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPMethodOrField.java?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPMethodOrField.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPMethodOrField.java Wed Oct  8 06:05:43 2008
@@ -16,10 +16,11 @@
  */
 package org.apache.harmony.pack200;
 
-public class CPMethodOrField implements Comparable {
+public class CPMethodOrField extends ConstantPoolEntry implements Comparable {
 
     private final CPClass className;
     private final CPNameAndType nameAndType;
+    private int indexInClass;
 
     public CPMethodOrField(CPClass className, CPNameAndType nameAndType) {
         this.className = className;
@@ -59,7 +60,23 @@
         return className.getIndex();
     }
 
+    public CPClass getClassName() {
+        return className;
+    }
+
     public int getDescIndex() {
         return nameAndType.getIndex();
     }
+
+    public CPNameAndType getDesc() {
+        return nameAndType;
+    }
+
+    public int getIndexInClass() {
+        return indexInClass;
+    }
+
+    public void setIndexInClass(int index) {
+        indexInClass = index;
+    }
 }
\ No newline at end of file

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPNameAndType.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPNameAndType.java?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPNameAndType.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPNameAndType.java Wed Oct  8 06:05:43 2008
@@ -45,11 +45,11 @@
     public int compareTo(Object obj) {
         if (obj instanceof CPNameAndType) {
             CPNameAndType nat = (CPNameAndType) obj;
-            int compareName = name.compareTo(nat.name);
-            if (compareName == 0) {
-                return signature.compareTo(nat.signature);
+            int compareSignature = signature.compareTo(nat.signature);;
+            if(compareSignature == 0) {
+                return name.compareTo(nat.name);
             } else {
-                return compareName;
+                return compareSignature;
             }
         }
         return 0;

Modified: harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java?rev=702856&r1=702855&r2=702856&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java (original)
+++ harmony/enhanced/classlib/trunk/modules/pack200/src/main/java/org/apache/harmony/pack200/CPSignature.java Wed Oct  8 06:05:43 2008
@@ -23,15 +23,36 @@
     private final CPUTF8 signatureForm;
     private final List classes;
     private final String signature;
+    private final boolean formStartsWithBracket;
 
     public CPSignature(String signature, CPUTF8 signatureForm, List classes) {
         this.signature = signature;
         this.signatureForm = signatureForm;
         this.classes = classes;
+        formStartsWithBracket = signatureForm.toString().startsWith("(");
     }
 
     public int compareTo(Object arg0) {
-        return signature.compareTo(((CPSignature)arg0).signature);
+        if (formStartsWithBracket
+                && !((CPSignature) arg0).formStartsWithBracket) {
+            return 1;
+        }
+        if (((CPSignature) arg0).formStartsWithBracket
+                && !formStartsWithBracket) {
+            return -1;
+        }
+        if (classes.size() - ((CPSignature) arg0).classes.size() != 0) {
+            return classes.size() - ((CPSignature) arg0).classes.size();
+        }
+        if (classes.size() > 0) {
+            CPClass myFirstClass = (CPClass) classes.get(0);
+            CPClass compareClass = (CPClass) ((CPSignature) arg0).classes
+                    .get(0);
+            return myFirstClass.toString().compareTo(compareClass.toString())
+                    * 1000
+                    + signature.compareTo(((CPSignature) arg0).signature);
+        }
+        return signature.compareTo(((CPSignature) arg0).signature);
     }
 
     public int getIndexInCpUtf8() {