You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2022/09/30 22:12:25 UTC

[commons-compress] branch master updated (cd119181 -> 7005afe4)

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git


    from cd119181 Use generics
     new 8b8c623b Use generics
     new 7005afe4 Use generics

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../commons/compress/harmony/pack200/BandSet.java  |   31 +-
 .../commons/compress/harmony/pack200/BcBands.java  |   66 +-
 .../compress/harmony/pack200/ClassBands.java       | 2862 ++++++++++----------
 .../commons/compress/harmony/pack200/CpBands.java  |   18 +-
 .../compress/harmony/pack200/FileBands.java        |    3 +-
 .../commons/compress/harmony/pack200/IcBands.java  |   14 +-
 .../harmony/pack200/MetadataBandGroup.java         |  278 +-
 .../harmony/pack200/NewAttributeBands.java         |    7 +-
 .../commons/compress/harmony/pack200/Segment.java  |   94 +-
 .../harmony/unpack200/AttributeLayoutMap.java      |   72 +-
 .../compress/harmony/unpack200/BcBands.java        |   30 +-
 .../compress/harmony/unpack200/ClassBands.java     |   49 +-
 .../compress/harmony/unpack200/CpBands.java        |   56 +-
 .../compress/harmony/unpack200/IcBands.java        |   41 +-
 .../compress/harmony/unpack200/IcTuple.java        |    5 +-
 .../harmony/unpack200/MetadataBandGroup.java       |   18 +-
 .../harmony/unpack200/NewAttributeBands.java       |   80 +-
 .../compress/harmony/unpack200/Segment.java        |   27 +-
 .../harmony/unpack200/SegmentConstantPool.java     |    6 +-
 .../unpack200/SegmentConstantPoolArrayCache.java   |   22 +-
 .../bytecode/AnnotationDefaultAttribute.java       |    2 +-
 .../unpack200/bytecode/AnnotationsAttribute.java   |    9 +-
 .../unpack200/bytecode/BCIRenumberedAttribute.java |    4 +-
 .../harmony/unpack200/bytecode/CPField.java        |    2 +-
 .../harmony/unpack200/bytecode/CPMember.java       |   13 +-
 .../harmony/unpack200/bytecode/CPMethod.java       |    2 +-
 .../unpack200/bytecode/ClassConstantPool.java      |   68 +-
 .../harmony/unpack200/bytecode/CodeAttribute.java  |   56 +-
 .../unpack200/bytecode/ExceptionTableEntry.java    |    8 +-
 .../unpack200/bytecode/InnerClassesAttribute.java  |   12 +-
 .../bytecode/LocalVariableTableAttribute.java      |    6 +-
 .../bytecode/LocalVariableTypeTableAttribute.java  |    6 +-
 .../harmony/unpack200/bytecode/NewAttribute.java   |   22 +-
 ...timeVisibleorInvisibleAnnotationsAttribute.java |    2 +-
 ...leorInvisibleParameterAnnotationsAttribute.java |    6 +-
 .../unpack200/bytecode/forms/LabelForm.java        |    4 +-
 .../unpack200/bytecode/forms/SwitchForm.java       |    4 +-
 .../harmony/pack200/tests/ArchiveTest.java         |    8 +-
 .../harmony/pack200/tests/CodecEncodingTest.java   |    2 +-
 .../harmony/pack200/tests/PackingOptionsTest.java  |   32 +-
 .../harmony/pack200/tests/PopulationCodecTest.java |    5 +-
 .../harmony/pack200/tests/RunCodecTest.java        |   11 +-
 .../harmony/unpack200/tests/ArchiveTest.java       |    8 +-
 .../harmony/unpack200/tests/BcBandsTest.java       |    3 +-
 .../harmony/unpack200/tests/CodeAttributeTest.java |   40 +-
 .../unpack200/tests/NewAttributeBandsTest.java     |    4 +-
 46 files changed, 2010 insertions(+), 2108 deletions(-)


[commons-compress] 01/02: Use generics

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git

commit 8b8c623ba3212f6805fb5640b9a4be97b1f81bd5
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Fri Sep 30 16:39:09 2022 -0400

    Use generics
    
    Access statics directly
---
 .../commons/compress/harmony/pack200/BandSet.java  |   31 +-
 .../commons/compress/harmony/pack200/BcBands.java  |   66 +-
 .../compress/harmony/pack200/ClassBands.java       | 2862 ++++++++++----------
 .../commons/compress/harmony/pack200/CpBands.java  |    6 +-
 .../compress/harmony/pack200/FileBands.java        |    3 +-
 .../commons/compress/harmony/pack200/IcBands.java  |   14 +-
 .../harmony/pack200/MetadataBandGroup.java         |  281 +-
 .../commons/compress/harmony/pack200/Segment.java  |   88 +-
 .../harmony/unpack200/AttributeLayoutMap.java      |   69 +-
 .../compress/harmony/unpack200/BcBands.java        |   27 +-
 .../compress/harmony/unpack200/ClassBands.java     |   49 +-
 .../compress/harmony/unpack200/CpBands.java        |   56 +-
 .../compress/harmony/unpack200/IcBands.java        |   41 +-
 .../compress/harmony/unpack200/IcTuple.java        |    5 +-
 .../harmony/unpack200/MetadataBandGroup.java       |   18 +-
 .../harmony/unpack200/NewAttributeBands.java       |   50 +-
 .../compress/harmony/unpack200/Segment.java        |   27 +-
 .../harmony/unpack200/SegmentConstantPool.java     |    2 +-
 .../unpack200/SegmentConstantPoolArrayCache.java   |   22 +-
 .../bytecode/AnnotationDefaultAttribute.java       |    2 +-
 .../unpack200/bytecode/AnnotationsAttribute.java   |    9 +-
 .../unpack200/bytecode/BCIRenumberedAttribute.java |    4 +-
 .../harmony/unpack200/bytecode/CPField.java        |    2 +-
 .../harmony/unpack200/bytecode/CPMember.java       |    8 +-
 .../harmony/unpack200/bytecode/CPMethod.java       |    2 +-
 .../unpack200/bytecode/ClassConstantPool.java      |   55 +-
 .../harmony/unpack200/bytecode/CodeAttribute.java  |   28 +-
 .../unpack200/bytecode/ExceptionTableEntry.java    |    8 +-
 .../unpack200/bytecode/InnerClassesAttribute.java  |   12 +-
 .../bytecode/LocalVariableTableAttribute.java      |    6 +-
 .../bytecode/LocalVariableTypeTableAttribute.java  |    6 +-
 .../harmony/unpack200/bytecode/NewAttribute.java   |   22 +-
 ...timeVisibleorInvisibleAnnotationsAttribute.java |    2 +-
 ...leorInvisibleParameterAnnotationsAttribute.java |    6 +-
 .../unpack200/bytecode/forms/LabelForm.java        |    4 +-
 .../unpack200/bytecode/forms/SwitchForm.java       |    4 +-
 .../harmony/pack200/tests/ArchiveTest.java         |    8 +-
 .../harmony/pack200/tests/CodecEncodingTest.java   |    2 +-
 .../harmony/pack200/tests/PackingOptionsTest.java  |   32 +-
 .../harmony/pack200/tests/PopulationCodecTest.java |    5 +-
 .../harmony/pack200/tests/RunCodecTest.java        |   11 +-
 .../harmony/unpack200/tests/ArchiveTest.java       |    8 +-
 .../harmony/unpack200/tests/BcBandsTest.java       |    3 +-
 .../harmony/unpack200/tests/CodeAttributeTest.java |   40 +-
 .../unpack200/tests/NewAttributeBandsTest.java     |    4 +-
 45 files changed, 1977 insertions(+), 2033 deletions(-)

diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/BandSet.java b/src/main/java/org/apache/commons/compress/harmony/pack200/BandSet.java
index 96aa2415..9c98966d 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/BandSet.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/BandSet.java
@@ -22,6 +22,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.IntStream;
 
 /**
  * Abstract superclass for a set of bands
@@ -124,10 +125,7 @@ public abstract class BandSet {
                     return band;
                 }
                 if (betterCodec instanceof PopulationCodec) {
-                    final int[] extraSpecifierInfo = results.extraMetadata;
-                    for (int element : extraSpecifierInfo) {
-                        segmentHeader.appendBandCodingSpecifier(element);
-                    }
+                    IntStream.of(results.extraMetadata).forEach(segmentHeader::appendBandCodingSpecifier);
                     return encodedBand;
                 }
                 if (betterCodec instanceof RunCodec) {
@@ -465,22 +463,13 @@ public abstract class BandSet {
         int specifier = 141 + (favouredCodec == null ? 1 : 0) + (4 * tdefL) + (unfavouredCodec == null ? 2 : 0);
         final IntList extraBandMetadata = new IntList(3);
         if (favouredCodec != null) {
-            final int[] specifiers = CodecEncoding.getSpecifier(favouredCodec, null);
-            for (int specifier2 : specifiers) {
-                extraBandMetadata.add(specifier2);
-            }
+            IntStream.of(CodecEncoding.getSpecifier(favouredCodec, null)).forEach(extraBandMetadata::add);
         }
         if (tdefL == 0) {
-            final int[] specifiers = CodecEncoding.getSpecifier(tokenCodec, null);
-            for (int specifier2 : specifiers) {
-                extraBandMetadata.add(specifier2);
-            }
+            IntStream.of(CodecEncoding.getSpecifier(tokenCodec, null)).forEach(extraBandMetadata::add);
         }
         if (unfavouredCodec != null) {
-            final int[] specifiers = CodecEncoding.getSpecifier(unfavouredCodec, null);
-            for (int specifier2 : specifiers) {
-                extraBandMetadata.add(specifier2);
-            }
+            IntStream.of(CodecEncoding.getSpecifier(unfavouredCodec, null)).forEach(extraBandMetadata::add);
         }
         final int[] extraMetadata = extraBandMetadata.toArray();
         final byte[] extraMetadataEncoded = Codec.UNSIGNED5.encode(extraMetadata);
@@ -581,7 +570,7 @@ public abstract class BandSet {
      * @param list conversion source.
      * @return conversion result.
      */
-    protected int[] cpEntryListToArray(final List<ConstantPoolEntry> list) {
+    protected int[] cpEntryListToArray(final List<? extends ConstantPoolEntry> list) {
         final int[] array = new int[list.size()];
         for (int i = 0; i < array.length; i++) {
             array[i] = list.get(i).getIndex();
@@ -595,13 +584,13 @@ public abstract class BandSet {
     /**
      * Converts a list of ConstantPoolEntrys or nulls to an int[] array of their indices +1 (or 0 for nulls)
      *
-     * @param theList conversion source.
+     * @param list conversion source.
      * @return conversion result.
      */
-    protected int[] cpEntryOrNullListToArray(final List<ConstantPoolEntry> theList) {
-        final int[] array = new int[theList.size()];
+    protected int[] cpEntryOrNullListToArray(final List<? extends ConstantPoolEntry> list) {
+        final int[] array = new int[list.size()];
         for (int j = 0; j < array.length; j++) {
-            final ConstantPoolEntry cpEntry = theList.get(j);
+            final ConstantPoolEntry cpEntry = list.get(j);
             array[j] = cpEntry == null ? 0 : cpEntry.getIndex() + 1;
             if (cpEntry != null && cpEntry.getIndex() < 0) {
                 throw new IllegalArgumentException("Index should be > 0");
diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/BcBands.java b/src/main/java/org/apache/commons/compress/harmony/pack200/BcBands.java
index c36c5ca2..27594af7 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/BcBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/BcBands.java
@@ -48,20 +48,20 @@ public class BcBands extends BandSet {
     
     // Integers and/or Labels?
     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 final List bcSuperField = new ArrayList();
-    private List bcThisMethod = new ArrayList();
-    private List bcSuperMethod = new ArrayList();
-    private List bcInitRef = new ArrayList();
+    private final List<CPInt> bcIntref = new ArrayList<>();
+    private final List<CPFloat> bcFloatRef = new ArrayList<>();
+    private final List<CPLong> bcLongRef = new ArrayList<>();
+    private final List<CPDouble> bcDoubleRef = new ArrayList<>();
+    private final List<CPString> bcStringRef = new ArrayList<>();
+    private final List<CPClass> bcClassRef = new ArrayList<>();
+    private final List<CPMethodOrField> bcFieldRef = new ArrayList<>();
+    private final List<CPMethodOrField> bcMethodRef = new ArrayList<>();
+    private final List<CPMethodOrField> bcIMethodRef = new ArrayList<>();
+    private List bcThisField = new ArrayList<>();
+    private final List bcSuperField = new ArrayList<>();
+    private List bcThisMethod = new ArrayList<>();
+    private List bcSuperMethod = new ArrayList<>();
+    private List bcInitRef = new ArrayList<>();
 
     private String currentClass;
     private String superClass;
@@ -194,20 +194,18 @@ public class BcBands extends BandSet {
         // out.write(encodeBandInt(integerListToArray(bcEscByte), Codec.BYTE1));
     }
 
-    private List getIndexInClass(final List cPMethodOrFieldList) {
-        final List indices = new ArrayList(cPMethodOrFieldList.size());
+    private List<Integer> getIndexInClass(final List<CPMethodOrField> cPMethodOrFieldList) {
+        final List<Integer> indices = new ArrayList<>(cPMethodOrFieldList.size());
         for (int i = 0; i < cPMethodOrFieldList.size(); i++) {
-            final CPMethodOrField cpMF = (CPMethodOrField) cPMethodOrFieldList.get(i);
-            indices.add(Integer.valueOf(cpMF.getIndexInClass()));
+            indices.add(Integer.valueOf(cPMethodOrFieldList.get(i).getIndexInClass()));
         }
         return indices;
     }
 
-    private List getIndexInClassForConstructor(final List cPMethodList) {
-        final List indices = new ArrayList(cPMethodList.size());
+    private List<Integer> getIndexInClassForConstructor(final List<CPMethodOrField> cPMethodList) {
+        final List<Integer> indices = new ArrayList<>(cPMethodList.size());
         for (int i = 0; i < cPMethodList.size(); i++) {
-            final CPMethodOrField cpMF = (CPMethodOrField) cPMethodList.get(i);
-            indices.add(Integer.valueOf(cpMF.getIndexInClassForConstructor()));
+            indices.add(Integer.valueOf(cPMethodList.get(i).getIndexInClassForConstructor()));
         }
         return indices;
     }
@@ -341,27 +339,27 @@ public class BcBands extends BandSet {
     }
 
     public void visitLdcInsn(final Object cst) {
-        final CPConstant constant = cpBands.getConstant(cst);
+        final CPConstant<?> constant = cpBands.getConstant(cst);
         if (segment.lastConstantHadWideIndex() || constant instanceof CPLong || constant instanceof CPDouble) {
             byteCodeOffset += 3;
             if (constant instanceof CPInt) {
                 bcCodes.add(237); // ildc_w
-                bcIntref.add(constant);
+                bcIntref.add((CPInt) constant);
             } else if (constant instanceof CPFloat) {
                 bcCodes.add(238); // fldc
-                bcFloatRef.add(constant);
+                bcFloatRef.add((CPFloat) constant);
             } else if (constant instanceof CPLong) {
                 bcCodes.add(20); // lldc2_w
-                bcLongRef.add(constant);
+                bcLongRef.add((CPLong) constant);
             } else if (constant instanceof CPDouble) {
                 bcCodes.add(239); // dldc2_w
-                bcDoubleRef.add(constant);
+                bcDoubleRef.add((CPDouble) constant);
             } else if (constant instanceof CPString) {
                 bcCodes.add(19); // aldc
-                bcStringRef.add(constant);
+                bcStringRef.add((CPString) constant);
             } else if (constant instanceof CPClass) {
                 bcCodes.add(236); // cldc
-                bcClassRef.add(constant);
+                bcClassRef.add((CPClass) constant);
             } else {
                 throw new IllegalArgumentException("Constant should not be null");
             }
@@ -369,16 +367,16 @@ public class BcBands extends BandSet {
             byteCodeOffset += 2;
             if (constant instanceof CPInt) {
                 bcCodes.add(234); // ildc
-                bcIntref.add(constant);
+                bcIntref.add((CPInt) constant);
             } else if (constant instanceof CPFloat) {
                 bcCodes.add(235); // fldc
-                bcFloatRef.add(constant);
+                bcFloatRef.add((CPFloat) constant);
             } else if (constant instanceof CPString) {
                 bcCodes.add(18); // aldc
-                bcStringRef.add(constant);
+                bcStringRef.add((CPString) constant);
             } else if (constant instanceof CPClass) {
                 bcCodes.add(233); // cldc
-                bcClassRef.add(constant);
+                bcClassRef.add((CPClass) constant);
             }
         }
         updateRenumbering();
@@ -465,7 +463,7 @@ public class BcBands extends BandSet {
         bcByte.add(dimensions & 0xFF);
     }
 
-    public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) {
+    public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) {
         bcCodes.add(TABLESWITCH);
         bcLabel.add(dflt);
         bcLabelRelativeOffsets.add(byteCodeOffset);
diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/ClassBands.java b/src/main/java/org/apache/commons/compress/harmony/pack200/ClassBands.java
index 0dccf6da..6730445f 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/ClassBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/ClassBands.java
@@ -32,1450 +32,1426 @@ import org.objectweb.asm.Label;
 import org.objectweb.asm.Opcodes;
 
 /**
- * Class bands (corresponds to the {@code class_bands} set of bands in the pack200 specification)
+ * Class bands (corresponds to the {@code class_bands} set of bands in the
+ * pack200 specification)
  */
 public class ClassBands extends BandSet {
 
-    private final CpBands cpBands;
-    private final AttributeDefinitionBands attrBands;
-
-    private final CPClass[] class_this;
-    private final CPClass[] class_super;
-    private final CPClass[][] class_interface;
-    private final int[] class_interface_count;
-
-    private final int[] major_versions;
-
-    private final long[] class_flags;
-    private int[] class_attr_calls;
-    private final List classSourceFile = new ArrayList();
-    private final List classEnclosingMethodClass = new ArrayList();
-    private final List classEnclosingMethodDesc = new ArrayList();
-    private final List classSignature = new ArrayList();
-
-    private final IntList classFileVersionMinor = new IntList();
-    private final IntList classFileVersionMajor = new IntList();
-
-    private final int[] class_field_count;
-    private final CPNameAndType[][] field_descr;
-    private final long[][] field_flags;
-    private int[] field_attr_calls;
-    private final List fieldConstantValueKQ = new ArrayList();
-    private final List fieldSignature = new ArrayList();
-
-    private final int[] class_method_count;
-    private final CPNameAndType[][] method_descr;
-    private final long[][] method_flags;
-    private int[] method_attr_calls;
-    private final List methodSignature = new ArrayList();
-    private final IntList methodExceptionNumber = new IntList();
-    private final List methodExceptionClasses = new ArrayList();
-
-    private int[] codeHeaders;
-    private final IntList codeMaxStack = new IntList();
-    private final IntList codeMaxLocals = new IntList();
-    private final IntList codeHandlerCount = new IntList();
-    private final List codeHandlerStartP = new ArrayList();
-    private final List codeHandlerEndPO = new ArrayList();
-    private final List codeHandlerCatchPO = new ArrayList();
-    private final List codeHandlerClass = new ArrayList();
-    private final List codeFlags = new ArrayList();
-    private int[] code_attr_calls;
-    private final IntList codeLineNumberTableN = new IntList();
-    private final List codeLineNumberTableBciP = new ArrayList();
-    private final IntList codeLineNumberTableLine = new IntList();
-    private final IntList codeLocalVariableTableN = new IntList();
-    private final List codeLocalVariableTableBciP = new ArrayList();
-    private final List codeLocalVariableTableSpanO = new ArrayList();
-    private final List codeLocalVariableTableNameRU = new ArrayList();
-    private final List codeLocalVariableTableTypeRS = new ArrayList();
-    private final IntList codeLocalVariableTableSlot = new IntList();
-    private final IntList codeLocalVariableTypeTableN = new IntList();
-    private final List codeLocalVariableTypeTableBciP = new ArrayList();
-    private final List codeLocalVariableTypeTableSpanO = new ArrayList();
-    private final List codeLocalVariableTypeTableNameRU = new ArrayList();
-    private final List codeLocalVariableTypeTableTypeRS = new ArrayList();
-    private final IntList codeLocalVariableTypeTableSlot = new IntList();
-
-    private final MetadataBandGroup class_RVA_bands;
-    private final MetadataBandGroup class_RIA_bands;
-    private final MetadataBandGroup field_RVA_bands;
-    private final MetadataBandGroup field_RIA_bands;
-    private final MetadataBandGroup method_RVA_bands;
-    private final MetadataBandGroup method_RIA_bands;
-    private final MetadataBandGroup method_RVPA_bands;
-    private final MetadataBandGroup method_RIPA_bands;
-    private final MetadataBandGroup method_AD_bands;
-
-    private final List classAttributeBands = new ArrayList();
-    private final List methodAttributeBands = new ArrayList();
-    private final List fieldAttributeBands = new ArrayList();
-    private final List codeAttributeBands = new ArrayList();
-
-    private final List tempFieldFlags = new ArrayList();
-    private final List tempFieldDesc = new ArrayList();
-    private final List tempMethodFlags = new ArrayList();
-    private final List tempMethodDesc = new ArrayList();
-    private TempParamAnnotation tempMethodRVPA;
-    private TempParamAnnotation tempMethodRIPA;
-
-    private boolean anySyntheticClasses = false;
-    private boolean anySyntheticFields = false;
-    private boolean anySyntheticMethods = false;
-    private final Segment segment;
-
-    private final Map classReferencesInnerClass = new HashMap();
-    private final boolean stripDebug;
-
-    private int index = 0;
-
-    private int numMethodArgs = 0;
-    private int[] class_InnerClasses_N;
-    private CPClass[] class_InnerClasses_RC;
-    private int[] class_InnerClasses_F;
-    private List classInnerClassesOuterRCN;
-    private List classInnerClassesNameRUN;
-
-    public ClassBands(final Segment segment, final int numClasses, final int effort, final boolean stripDebug)
-        throws IOException {
-        super(effort, segment.getSegmentHeader());
-        this.stripDebug = stripDebug;
-        this.segment = segment;
-        this.cpBands = segment.getCpBands();
-        this.attrBands = segment.getAttrBands();
-        class_this = new CPClass[numClasses];
-        class_super = new CPClass[numClasses];
-        class_interface_count = new int[numClasses];
-        class_interface = new CPClass[numClasses][];
-        class_field_count = new int[numClasses];
-        class_method_count = new int[numClasses];
-        field_descr = new CPNameAndType[numClasses][];
-        field_flags = new long[numClasses][];
-        method_descr = new CPNameAndType[numClasses][];
-        method_flags = new long[numClasses][];
-        for (int i = 0; i < numClasses; i++) {
-            field_flags[i] = new long[0];
-            method_flags[i] = new long[0];
-        }
-        // minor_versions = new int[numClasses];
-        major_versions = new int[numClasses];
-        class_flags = new long[numClasses];
-
-        class_RVA_bands = new MetadataBandGroup("RVA", MetadataBandGroup.CONTEXT_CLASS, cpBands, segmentHeader, effort);
-        class_RIA_bands = new MetadataBandGroup("RIA", MetadataBandGroup.CONTEXT_CLASS, cpBands, segmentHeader, effort);
-        field_RVA_bands = new MetadataBandGroup("RVA", MetadataBandGroup.CONTEXT_FIELD, cpBands, segmentHeader, effort);
-        field_RIA_bands = new MetadataBandGroup("RIA", MetadataBandGroup.CONTEXT_FIELD, cpBands, segmentHeader, effort);
-        method_RVA_bands = new MetadataBandGroup("RVA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader,
-            effort);
-        method_RIA_bands = new MetadataBandGroup("RIA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader,
-            effort);
-        method_RVPA_bands = new MetadataBandGroup("RVPA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader,
-            effort);
-        method_RIPA_bands = new MetadataBandGroup("RIPA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader,
-            effort);
-        method_AD_bands = new MetadataBandGroup("AD", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader, effort);
-
-        createNewAttributeBands();
-    }
-
-    private void createNewAttributeBands() throws IOException {
-        final List classAttributeLayouts = attrBands.getClassAttributeLayouts();
-        for (Object classAttributeLayout : classAttributeLayouts) {
-            final AttributeDefinition def = (AttributeDefinition) classAttributeLayout;
-            classAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
-        }
-        final List methodAttributeLayouts = attrBands.getMethodAttributeLayouts();
-        for (Object methodAttributeLayout : methodAttributeLayouts) {
-            final AttributeDefinition def = (AttributeDefinition) methodAttributeLayout;
-            methodAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
-        }
-        final List fieldAttributeLayouts = attrBands.getFieldAttributeLayouts();
-        for (Object fieldAttributeLayout : fieldAttributeLayouts) {
-            final AttributeDefinition def = (AttributeDefinition) fieldAttributeLayout;
-            fieldAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
-        }
-        final List codeAttributeLayouts = attrBands.getCodeAttributeLayouts();
-        for (Object codeAttributeLayout : codeAttributeLayouts) {
-            final AttributeDefinition def = (AttributeDefinition) codeAttributeLayout;
-            codeAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
-        }
-    }
-
-    public void addClass(final int major, int flags, final String className, final String signature,
-        final String superName, final String[] interfaces) {
-        class_this[index] = cpBands.getCPClass(className);
-        class_super[index] = cpBands.getCPClass(superName);
-        class_interface_count[index] = interfaces.length;
-        class_interface[index] = new CPClass[interfaces.length];
-        for (int i = 0; i < interfaces.length; i++) {
-            class_interface[index][i] = cpBands.getCPClass(interfaces[i]);
-        }
-        major_versions[index] = major;
-        class_flags[index] = flags;
-        if (!anySyntheticClasses && ((flags & (1 << 12)) != 0)
-            && segment.getCurrentClassReader().hasSyntheticAttributes()) {
-            cpBands.addCPUtf8("Synthetic");
-            anySyntheticClasses = true;
-        }
-        if ((flags & Opcodes.ACC_DEPRECATED) != 0) { // ASM uses (1<<17) flag for deprecated
-            flags = flags & ~Opcodes.ACC_DEPRECATED;
-            flags = flags | (1 << 20);
-        }
-        if (signature != null) {
-            class_flags[index] |= (1 << 19);
-            classSignature.add(cpBands.getCPSignature(signature));
-        }
-    }
-
-    public void currentClassReferencesInnerClass(final CPClass inner) {
-        if (!(index >= class_this.length)) {
-            final CPClass currentClass = class_this[index];
-            if (currentClass != null && !currentClass.equals(inner)
-                && !isInnerClassOf(currentClass.toString(), inner)) {
-                Set referencedInnerClasses = (Set) classReferencesInnerClass.get(currentClass);
-                if (referencedInnerClasses == null) {
-                    referencedInnerClasses = new HashSet();
-                    classReferencesInnerClass.put(currentClass, referencedInnerClasses);
-                }
-                referencedInnerClasses.add(inner);
-            }
-        }
-    }
-
-    private boolean isInnerClassOf(final String possibleInner, final CPClass possibleOuter) {
-        if (isInnerClass(possibleInner)) {
-            final String superClassName = possibleInner.substring(0, possibleInner.lastIndexOf('$'));
-            if (superClassName.equals(possibleOuter.toString())) {
-                return true;
-            }
-            return isInnerClassOf(superClassName, possibleOuter);
-        }
-        return false;
-    }
-
-    private boolean isInnerClass(final String possibleInner) {
-        return possibleInner.indexOf('$') != -1;
-    }
-
-    public void addField(int flags, final String name, final String desc, final String signature, final Object value) {
-        flags = flags & 0xFFFF;
-        tempFieldDesc.add(cpBands.getCPNameAndType(name, desc));
-        if (signature != null) {
-            fieldSignature.add(cpBands.getCPSignature(signature));
-            flags |= (1 << 19);
-        }
-        if ((flags & Opcodes.ACC_DEPRECATED) != 0) { // ASM uses (1<<17) flag for deprecated
-            flags = flags & ~Opcodes.ACC_DEPRECATED;
-            flags = flags | (1 << 20);
-        }
-        if (value != null) {
-            fieldConstantValueKQ.add(cpBands.getConstant(value));
-            flags |= (1 << 17);
-        }
-        if (!anySyntheticFields && ((flags & (1 << 12)) != 0)
-            && segment.getCurrentClassReader().hasSyntheticAttributes()) {
-            cpBands.addCPUtf8("Synthetic");
-            anySyntheticFields = true;
-        }
-        tempFieldFlags.add(Long.valueOf(flags));
-    }
-
-    /**
-     * All input classes for the segment have now been read in, so this method is called so that this class can
-     * calculate/complete anything it could not do while classes were being read.
-     */
-    public void finaliseBands() {
-        final int defaultMajorVersion = segmentHeader.getDefaultMajorVersion();
-        for (int i = 0; i < class_flags.length; i++) {
-            final int major = major_versions[i];
-            if (major != defaultMajorVersion) {
-                class_flags[i] |= 1 << 24;
-                classFileVersionMajor.add(major);
-                classFileVersionMinor.add(0);
-            }
-        }
-        // Calculate code headers
-        codeHeaders = new int[codeHandlerCount.size()];
-        int removed = 0;
-        for (int i = 0; i < codeHeaders.length; i++) {
-            final int numHandlers = codeHandlerCount.get(i - removed);
-            final int maxLocals = codeMaxLocals.get(i - removed);
-            final int maxStack = codeMaxStack.get(i - removed);
-            if (numHandlers == 0) {
-                final int header = maxLocals * 12 + maxStack + 1;
-                if (header < 145 && maxStack < 12) {
-                    codeHeaders[i] = header;
-                }
-            } else if (numHandlers == 1) {
-                final int header = maxLocals * 8 + maxStack + 145;
-                if (header < 209 && maxStack < 8) {
-                    codeHeaders[i] = header;
-                }
-            } else if (numHandlers == 2) {
-                final int header = maxLocals * 7 + maxStack + 209;
-                if (header < 256 && maxStack < 7) {
-                    codeHeaders[i] = header;
-                }
-            }
-            if (codeHeaders[i] != 0) { // Remove the redundant values from
-                                       // codeHandlerCount, codeMaxLocals and
-                                       // codeMaxStack
-                codeHandlerCount.remove(i - removed);
-                codeMaxLocals.remove(i - removed);
-                codeMaxStack.remove(i - removed);
-                removed++;
-            } else if (!segment.getSegmentHeader().have_all_code_flags()) {
-                codeFlags.add(Long.valueOf(0));
-            }
-        }
-
-        // Compute any required IcLocals
-        final IntList innerClassesN = new IntList();
-        final List icLocal = new ArrayList();
-        for (int i = 0; i < class_this.length; i++) {
-            final CPClass cpClass = class_this[i];
-            final Set referencedInnerClasses = (Set) classReferencesInnerClass.get(cpClass);
-            if (referencedInnerClasses != null) {
-                int innerN = 0;
-                final List innerClasses = segment.getIcBands().getInnerClassesForOuter(cpClass.toString());
-                if (innerClasses != null) {
-                    for (Object element : innerClasses) {
-                        referencedInnerClasses.remove(((IcTuple) element).C);
-                    }
-                }
-                for (Object element : referencedInnerClasses) {
-                    final CPClass inner = (CPClass) element;
-                    final IcTuple icTuple = segment.getIcBands().getIcTuple(inner);
-                    if (icTuple != null && !icTuple.isAnonymous()) {
-                        // should transmit an icLocal entry
-                        icLocal.add(icTuple);
-                        innerN++;
-                    }
-                }
-                if (innerN != 0) {
-                    innerClassesN.add(innerN);
-                    class_flags[i] |= (1 << 23);
-                }
-            }
-        }
-        class_InnerClasses_N = innerClassesN.toArray();
-        class_InnerClasses_RC = new CPClass[icLocal.size()];
-        class_InnerClasses_F = new int[icLocal.size()];
-        classInnerClassesOuterRCN = new ArrayList();
-        classInnerClassesNameRUN = new ArrayList();
-        for (int i = 0; i < class_InnerClasses_RC.length; i++) {
-            final IcTuple icTuple = (IcTuple) icLocal.get(i);
-            class_InnerClasses_RC[i] = (icTuple.C);
-            if (icTuple.C2 == null && icTuple.N == null) {
-                class_InnerClasses_F[i] = 0;
-            } else {
-                if (icTuple.F == 0) {
-                    class_InnerClasses_F[i] = 0x00010000;
-                } else {
-                    class_InnerClasses_F[i] = icTuple.F;
-                }
-                classInnerClassesOuterRCN.add(icTuple.C2);
-                classInnerClassesNameRUN.add(icTuple.N);
-            }
-        }
-        // Calculate any backwards calls from metadata bands
-        final IntList classAttrCalls = new IntList();
-        final IntList fieldAttrCalls = new IntList();
-        final IntList methodAttrCalls = new IntList();
-        final IntList codeAttrCalls = new IntList();
-
-        if (class_RVA_bands.hasContent()) {
-            classAttrCalls.add(class_RVA_bands.numBackwardsCalls());
-        }
-        if (class_RIA_bands.hasContent()) {
-            classAttrCalls.add(class_RIA_bands.numBackwardsCalls());
-        }
-        if (field_RVA_bands.hasContent()) {
-            fieldAttrCalls.add(field_RVA_bands.numBackwardsCalls());
-        }
-        if (field_RIA_bands.hasContent()) {
-            fieldAttrCalls.add(field_RIA_bands.numBackwardsCalls());
-        }
-        if (method_RVA_bands.hasContent()) {
-            methodAttrCalls.add(method_RVA_bands.numBackwardsCalls());
-        }
-        if (method_RIA_bands.hasContent()) {
-            methodAttrCalls.add(method_RIA_bands.numBackwardsCalls());
-        }
-        if (method_RVPA_bands.hasContent()) {
-            methodAttrCalls.add(method_RVPA_bands.numBackwardsCalls());
-        }
-        if (method_RIPA_bands.hasContent()) {
-            methodAttrCalls.add(method_RIPA_bands.numBackwardsCalls());
-        }
-        if (method_AD_bands.hasContent()) {
-            methodAttrCalls.add(method_AD_bands.numBackwardsCalls());
-        }
-
-        // Sort non-predefined attribute bands
-        final Comparator comparator = (arg0, arg1) -> {
-            final NewAttributeBands bands0 = (NewAttributeBands) arg0;
-            final NewAttributeBands bands1 = (NewAttributeBands) arg1;
-            return bands0.getFlagIndex() - bands1.getFlagIndex();
-        };
-        classAttributeBands.sort(comparator);
-        methodAttributeBands.sort(comparator);
-        fieldAttributeBands.sort(comparator);
-        codeAttributeBands.sort(comparator);
-
-        for (Object classAttributeBand : classAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) classAttributeBand;
-            if (bands.isUsedAtLeastOnce()) {
-                final int[] backwardsCallCounts = bands.numBackwardsCalls();
-                for (int backwardsCallCount : backwardsCallCounts) {
-                    classAttrCalls.add(backwardsCallCount);
-                }
-            }
-        }
-        for (Object methodAttributeBand : methodAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) methodAttributeBand;
-            if (bands.isUsedAtLeastOnce()) {
-                final int[] backwardsCallCounts = bands.numBackwardsCalls();
-                for (int backwardsCallCount : backwardsCallCounts) {
-                    methodAttrCalls.add(backwardsCallCount);
-                }
-            }
-        }
-        for (Object fieldAttributeBand : fieldAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) fieldAttributeBand;
-            if (bands.isUsedAtLeastOnce()) {
-                final int[] backwardsCallCounts = bands.numBackwardsCalls();
-                for (int backwardsCallCount : backwardsCallCounts) {
-                    fieldAttrCalls.add(backwardsCallCount);
-                }
-            }
-        }
-        for (Object codeAttributeBand : codeAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) codeAttributeBand;
-            if (bands.isUsedAtLeastOnce()) {
-                final int[] backwardsCallCounts = bands.numBackwardsCalls();
-                for (int backwardsCallCount : backwardsCallCounts) {
-                    codeAttrCalls.add(backwardsCallCount);
-                }
-            }
-        }
-
-        class_attr_calls = classAttrCalls.toArray();
-        field_attr_calls = fieldAttrCalls.toArray();
-        method_attr_calls = methodAttrCalls.toArray();
-        code_attr_calls = codeAttrCalls.toArray();
-    }
-
-    @Override
-    public void pack(final OutputStream out) throws IOException, Pack200Exception {
-        PackingUtils.log("Writing class bands...");
-
-        byte[] encodedBand = encodeBandInt("class_this", getInts(class_this), Codec.DELTA5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_this[" + class_this.length + "]");
-
-        encodedBand = encodeBandInt("class_super", getInts(class_super), Codec.DELTA5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_super[" + class_super.length + "]");
-
-        encodedBand = encodeBandInt("class_interface_count", class_interface_count, Codec.DELTA5);
-        out.write(encodedBand);
-        PackingUtils.log(
-            "Wrote " + encodedBand.length + " bytes from class_interface_count[" + class_interface_count.length + "]");
-
-        final int totalInterfaces = sum(class_interface_count);
-        final int[] classInterface = new int[totalInterfaces];
-        int k = 0;
-        for (CPClass[] element : class_interface) {
-            if (element != null) {
-                for (final CPClass cpClass : element) {
-                    classInterface[k] = cpClass.getIndex();
-                    k++;
-                }
-            }
-        }
-
-        encodedBand = encodeBandInt("class_interface", classInterface, Codec.DELTA5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_interface[" + classInterface.length + "]");
-
-        encodedBand = encodeBandInt("class_field_count", class_field_count, Codec.DELTA5);
-        out.write(encodedBand);
-        PackingUtils
-            .log("Wrote " + encodedBand.length + " bytes from class_field_count[" + class_field_count.length + "]");
-
-        encodedBand = encodeBandInt("class_method_count", class_method_count, Codec.DELTA5);
-        out.write(encodedBand);
-        PackingUtils
-            .log("Wrote " + encodedBand.length + " bytes from class_method_count[" + class_method_count.length + "]");
-
-        final int totalFields = sum(class_field_count);
-        final int[] fieldDescr = new int[totalFields];
-        k = 0;
-        for (int i = 0; i < index; i++) {
-            for (int j = 0; j < field_descr[i].length; j++) {
-                final CPNameAndType descr = field_descr[i][j];
-                fieldDescr[k] = descr.getIndex();
-                k++;
-            }
-        }
-
-        encodedBand = encodeBandInt("field_descr", fieldDescr, Codec.DELTA5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from field_descr[" + fieldDescr.length + "]");
-
-        writeFieldAttributeBands(out);
-
-        final int totalMethods = sum(class_method_count);
-        final int[] methodDescr = new int[totalMethods];
-        k = 0;
-        for (int i = 0; i < index; i++) {
-            for (int j = 0; j < method_descr[i].length; j++) {
-                final CPNameAndType descr = method_descr[i][j];
-                methodDescr[k] = descr.getIndex();
-                k++;
-            }
-        }
-
-        encodedBand = encodeBandInt("method_descr", methodDescr, Codec.MDELTA5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from method_descr[" + methodDescr.length + "]");
-
-        writeMethodAttributeBands(out);
-        writeClassAttributeBands(out);
-        writeCodeBands(out);
-    }
-
-    private int sum(final int[] ints) {
-        int sum = 0;
-        for (int j : ints) {
-            sum += j;
-        }
-        return sum;
-    }
-
-    private void writeFieldAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
-        byte[] encodedBand = encodeFlags("field_flags", field_flags, Codec.UNSIGNED5, Codec.UNSIGNED5,
-            segmentHeader.have_field_flags_hi());
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from field_flags[" + field_flags.length + "]");
-
-        // *field_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
-        // *field_attr_indexes :UNSIGNED5 [SUM(*field_attr_count)]
-        encodedBand = encodeBandInt("field_attr_calls", field_attr_calls, Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils
-            .log("Wrote " + encodedBand.length + " bytes from field_attr_calls[" + field_attr_calls.length + "]");
-
-        encodedBand = encodeBandInt("fieldConstantValueKQ", cpEntryListToArray(fieldConstantValueKQ), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log(
-            "Wrote " + encodedBand.length + " bytes from fieldConstantValueKQ[" + fieldConstantValueKQ.size() + "]");
-
-        encodedBand = encodeBandInt("fieldSignature", cpEntryListToArray(fieldSignature), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from fieldSignature[" + fieldSignature.size() + "]");
-
-        field_RVA_bands.pack(out);
-        field_RIA_bands.pack(out);
-        for (Object fieldAttributeBand : fieldAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) fieldAttributeBand;
-            bands.pack(out);
-        }
-    }
-
-    private void writeMethodAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
-        byte[] encodedBand = encodeFlags("method_flags", method_flags, Codec.UNSIGNED5, Codec.UNSIGNED5,
-            segmentHeader.have_method_flags_hi());
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from method_flags[" + method_flags.length + "]");
-
-        // *method_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
-        // *method_attr_indexes :UNSIGNED5 [SUM(*method_attr_count)]
-        encodedBand = encodeBandInt("method_attr_calls", method_attr_calls, Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils
-            .log("Wrote " + encodedBand.length + " bytes from method_attr_calls[" + method_attr_calls.length + "]");
-
-        encodedBand = encodeBandInt("methodExceptionNumber", methodExceptionNumber.toArray(), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log(
-            "Wrote " + encodedBand.length + " bytes from methodExceptionNumber[" + methodExceptionNumber.size() + "]");
-
-        encodedBand = encodeBandInt("methodExceptionClasses", cpEntryListToArray(methodExceptionClasses),
-            Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from methodExceptionClasses["
-            + methodExceptionClasses.size() + "]");
-
-        encodedBand = encodeBandInt("methodSignature", cpEntryListToArray(methodSignature), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from methodSignature[" + methodSignature.size() + "]");
-
-        method_RVA_bands.pack(out);
-        method_RIA_bands.pack(out);
-        method_RVPA_bands.pack(out);
-        method_RIPA_bands.pack(out);
-        method_AD_bands.pack(out);
-        for (Object methodAttributeBand : methodAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) methodAttributeBand;
-            bands.pack(out);
-        }
-    }
-
-    private void writeClassAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
-        byte[] encodedBand = encodeFlags("class_flags", class_flags, Codec.UNSIGNED5, Codec.UNSIGNED5,
-            segmentHeader.have_class_flags_hi());
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_flags[" + class_flags.length + "]");
-
-        // These bands are not needed, but could be used to reduce the size of
-        // the archive if there are enough different non-standard attributes
-        // defined that segmentHeader.have_class_flags_hi() is true. The same
-        // applies to method_attr_count, field_attr_count, code_attr_count etc.
-
-        // *class_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
-        // *class_attr_indexes :UNSIGNED5 [SUM(*class_attr_count)]
-
-        encodedBand = encodeBandInt("class_attr_calls", class_attr_calls, Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils
-            .log("Wrote " + encodedBand.length + " bytes from class_attr_calls[" + class_attr_calls.length + "]");
-
-        encodedBand = encodeBandInt("classSourceFile", cpEntryOrNullListToArray(classSourceFile), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from classSourceFile[" + classSourceFile.size() + "]");
-
-        encodedBand = encodeBandInt("class_enclosing_method_RC", cpEntryListToArray(classEnclosingMethodClass),
-            Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_enclosing_method_RC["
-            + classEnclosingMethodClass.size() + "]");
-
-        encodedBand = encodeBandInt("class_EnclosingMethod_RDN", cpEntryOrNullListToArray(classEnclosingMethodDesc),
-            Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_EnclosingMethod_RDN["
-            + classEnclosingMethodDesc.size() + "]");
-
-        encodedBand = encodeBandInt("class_Signature_RS", cpEntryListToArray(classSignature), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils
-            .log("Wrote " + encodedBand.length + " bytes from class_Signature_RS[" + classSignature.size() + "]");
-
-        class_RVA_bands.pack(out);
-        class_RIA_bands.pack(out);
-
-        encodedBand = encodeBandInt("class_InnerClasses_N", class_InnerClasses_N, Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log(
-            "Wrote " + encodedBand.length + " bytes from class_InnerClasses_N[" + class_InnerClasses_N.length + "]");
-
-        encodedBand = encodeBandInt("class_InnerClasses_RC", getInts(class_InnerClasses_RC), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log(
-            "Wrote " + encodedBand.length + " bytes from class_InnerClasses_RC[" + class_InnerClasses_RC.length + "]");
-
-        encodedBand = encodeBandInt("class_InnerClasses_F", class_InnerClasses_F, Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log(
-            "Wrote " + encodedBand.length + " bytes from class_InnerClasses_F[" + class_InnerClasses_F.length + "]");
-
-        encodedBand = encodeBandInt("class_InnerClasses_outer_RCN", cpEntryOrNullListToArray(classInnerClassesOuterRCN),
-            Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_outer_RCN["
-            + classInnerClassesOuterRCN.size() + "]");
-
-        encodedBand = encodeBandInt("class_InnerClasses_name_RUN", cpEntryOrNullListToArray(classInnerClassesNameRUN),
-            Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_name_RUN["
-            + classInnerClassesNameRUN.size() + "]");
-
-        encodedBand = encodeBandInt("classFileVersionMinor", classFileVersionMinor.toArray(), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log(
-            "Wrote " + encodedBand.length + " bytes from classFileVersionMinor[" + classFileVersionMinor.size() + "]");
-
-        encodedBand = encodeBandInt("classFileVersionMajor", classFileVersionMajor.toArray(), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log(
-            "Wrote " + encodedBand.length + " bytes from classFileVersionMajor[" + classFileVersionMajor.size() + "]");
-
-        for (Object classAttributeBand : classAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) classAttributeBand;
-            bands.pack(out);
-        }
-    }
-
-    private int[] getInts(final CPClass[] cpClasses) {
-        final int[] ints = new int[cpClasses.length];
-        for (int i = 0; i < ints.length; i++) {
-            if (cpClasses[i] != null) {
-                ints[i] = cpClasses[i].getIndex();
-            }
-        }
-        return ints;
-    }
-
-    private void writeCodeBands(final OutputStream out) throws IOException, Pack200Exception {
-        byte[] encodedBand = encodeBandInt("codeHeaders", codeHeaders, Codec.BYTE1);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeHeaders[" + codeHeaders.length + "]");
-
-        encodedBand = encodeBandInt("codeMaxStack", codeMaxStack.toArray(), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeMaxStack[" + codeMaxStack.size() + "]");
-
-        encodedBand = encodeBandInt("codeMaxLocals", codeMaxLocals.toArray(), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeMaxLocals[" + codeMaxLocals.size() + "]");
-
-        encodedBand = encodeBandInt("codeHandlerCount", codeHandlerCount.toArray(), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils
-            .log("Wrote " + encodedBand.length + " bytes from codeHandlerCount[" + codeHandlerCount.size() + "]");
-
-        encodedBand = encodeBandInt("codeHandlerStartP", integerListToArray(codeHandlerStartP), Codec.BCI5);
-        out.write(encodedBand);
-        PackingUtils
-            .log("Wrote " + encodedBand.length + " bytes from codeHandlerStartP[" + codeHandlerStartP.size() + "]");
-
-        encodedBand = encodeBandInt("codeHandlerEndPO", integerListToArray(codeHandlerEndPO), Codec.BRANCH5);
-        out.write(encodedBand);
-        PackingUtils
-            .log("Wrote " + encodedBand.length + " bytes from codeHandlerEndPO[" + codeHandlerEndPO.size() + "]");
-
-        encodedBand = encodeBandInt("codeHandlerCatchPO", integerListToArray(codeHandlerCatchPO), Codec.BRANCH5);
-        out.write(encodedBand);
-        PackingUtils
-            .log("Wrote " + encodedBand.length + " bytes from codeHandlerCatchPO[" + codeHandlerCatchPO.size() + "]");
-
-        encodedBand = encodeBandInt("codeHandlerClass", cpEntryOrNullListToArray(codeHandlerClass), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils
-            .log("Wrote " + encodedBand.length + " bytes from codeHandlerClass[" + codeHandlerClass.size() + "]");
-
-        writeCodeAttributeBands(out);
-    }
-
-    private void writeCodeAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
-        byte[] encodedBand = encodeFlags("codeFlags", longListToArray(codeFlags), Codec.UNSIGNED5, Codec.UNSIGNED5,
-            segmentHeader.have_code_flags_hi());
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeFlags[" + codeFlags.size() + "]");
-
-        // *code_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
-        // *code_attr_indexes :UNSIGNED5 [SUM(*code_attr_count)]
-        encodedBand = encodeBandInt("code_attr_calls", code_attr_calls, Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_attr_calls[" + code_attr_calls.length + "]");
-
-        encodedBand = encodeBandInt("code_LineNumberTable_N", codeLineNumberTableN.toArray(), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log(
-            "Wrote " + encodedBand.length + " bytes from code_LineNumberTable_N[" + codeLineNumberTableN.size() + "]");
-
-        encodedBand = encodeBandInt("code_LineNumberTable_bci_P", integerListToArray(codeLineNumberTableBciP),
-            Codec.BCI5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LineNumberTable_bci_P["
-            + codeLineNumberTableBciP.size() + "]");
-
-        encodedBand = encodeBandInt("code_LineNumberTable_line", codeLineNumberTableLine.toArray(), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LineNumberTable_line["
-            + codeLineNumberTableLine.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTable_N", codeLocalVariableTableN.toArray(), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_N["
-            + codeLocalVariableTableN.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTable_bci_P", integerListToArray(codeLocalVariableTableBciP),
-            Codec.BCI5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_bci_P["
-            + codeLocalVariableTableBciP.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTable_span_O", integerListToArray(codeLocalVariableTableSpanO),
-            Codec.BRANCH5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_span_O["
-            + codeLocalVariableTableSpanO.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTable_name_RU", cpEntryListToArray(codeLocalVariableTableNameRU),
-            Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_name_RU["
-            + codeLocalVariableTableNameRU.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTable_type_RS", cpEntryListToArray(codeLocalVariableTableTypeRS),
-            Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_type_RS["
-            + codeLocalVariableTableTypeRS.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTable_slot", codeLocalVariableTableSlot.toArray(),
-            Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_slot["
-            + codeLocalVariableTableSlot.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTypeTable_N", codeLocalVariableTypeTableN.toArray(),
-            Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_N["
-            + codeLocalVariableTypeTableN.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTypeTable_bci_P",
-            integerListToArray(codeLocalVariableTypeTableBciP), Codec.BCI5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_bci_P["
-            + codeLocalVariableTypeTableBciP.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTypeTable_span_O",
-            integerListToArray(codeLocalVariableTypeTableSpanO), Codec.BRANCH5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_span_O["
-            + codeLocalVariableTypeTableSpanO.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTypeTable_name_RU",
-            cpEntryListToArray(codeLocalVariableTypeTableNameRU), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_name_RU["
-            + codeLocalVariableTypeTableNameRU.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTypeTable_type_RS",
-            cpEntryListToArray(codeLocalVariableTypeTableTypeRS), Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_type_RS["
-            + codeLocalVariableTypeTableTypeRS.size() + "]");
-
-        encodedBand = encodeBandInt("code_LocalVariableTypeTable_slot", codeLocalVariableTypeTableSlot.toArray(),
-            Codec.UNSIGNED5);
-        out.write(encodedBand);
-        PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_slot["
-            + codeLocalVariableTypeTableSlot.size() + "]");
-
-        for (Object codeAttributeBand : codeAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) codeAttributeBand;
-            bands.pack(out);
-        }
-    }
-
-    public void addMethod(int flags, final String name, final String desc, final String signature,
-        final String[] exceptions) {
-        final CPNameAndType nt = cpBands.getCPNameAndType(name, desc);
-        tempMethodDesc.add(nt);
-        if (signature != null) {
-            methodSignature.add(cpBands.getCPSignature(signature));
-            flags |= (1 << 19);
-        }
-        if (exceptions != null) {
-            methodExceptionNumber.add(exceptions.length);
-            for (String exception : exceptions) {
-                methodExceptionClasses.add(cpBands.getCPClass(exception));
-            }
-            flags |= (1 << 18);
-        }
-        if ((flags & Opcodes.ACC_DEPRECATED) != 0) { // ASM uses (1<<17) flag for deprecated
-            flags = flags & ~Opcodes.ACC_DEPRECATED;
-            flags = flags | (1 << 20);
-        }
-        tempMethodFlags.add(Long.valueOf(flags));
-        numMethodArgs = countArgs(desc);
-        if (!anySyntheticMethods && ((flags & (1 << 12)) != 0)
-            && segment.getCurrentClassReader().hasSyntheticAttributes()) {
-            cpBands.addCPUtf8("Synthetic");
-            anySyntheticMethods = true;
-        }
-    }
-
-    public void endOfMethod() {
-        if (tempMethodRVPA != null) {
-            method_RVPA_bands.addParameterAnnotation(tempMethodRVPA.numParams, tempMethodRVPA.annoN,
-                tempMethodRVPA.pairN, tempMethodRVPA.typeRS, tempMethodRVPA.nameRU, tempMethodRVPA.t,
-                tempMethodRVPA.values, tempMethodRVPA.caseArrayN, tempMethodRVPA.nestTypeRS, tempMethodRVPA.nestNameRU,
-                tempMethodRVPA.nestPairN);
-            tempMethodRVPA = null;
-        }
-        if (tempMethodRIPA != null) {
-            method_RIPA_bands.addParameterAnnotation(tempMethodRIPA.numParams, tempMethodRIPA.annoN,
-                tempMethodRIPA.pairN, tempMethodRIPA.typeRS, tempMethodRIPA.nameRU, tempMethodRIPA.t,
-                tempMethodRIPA.values, tempMethodRIPA.caseArrayN, tempMethodRIPA.nestTypeRS, tempMethodRIPA.nestNameRU,
-                tempMethodRIPA.nestPairN);
-            tempMethodRIPA = null;
-        }
-        if (codeFlags.size() > 0) {
-            final long latestCodeFlag = ((Long) codeFlags.get(codeFlags.size() - 1)).longValue();
-            final int latestLocalVariableTableN = codeLocalVariableTableN.get(codeLocalVariableTableN.size() - 1);
-            if (latestCodeFlag == (1 << 2) && latestLocalVariableTableN == 0) {
-                codeLocalVariableTableN.remove(codeLocalVariableTableN.size() - 1);
-                codeFlags.remove(codeFlags.size() - 1);
-                codeFlags.add(Integer.valueOf(0));
-            }
-        }
-    }
-
-    protected static int countArgs(final String descriptor) {
-        final int bra = descriptor.indexOf('(');
-        final int ket = descriptor.indexOf(')');
-        if (bra == -1 || ket == -1 || ket < bra) {
-            throw new IllegalArgumentException("No arguments");
-        }
-
-        boolean inType = false;
-        boolean consumingNextType = false;
-        int count = 0;
-        for (int i = bra + 1; i < ket; i++) {
-            final char charAt = descriptor.charAt(i);
-            if (inType && charAt == ';') {
-                inType = false;
-                consumingNextType = false;
-            } else if (!inType && charAt == 'L') {
-                inType = true;
-                count++;
-            } else if (charAt == '[') {
-                consumingNextType = true;
-            } else if (inType) {
-                // NOP
-            } else if (consumingNextType) {
-                count++;
-                consumingNextType = false;
-            } else if (charAt == 'D' || charAt == 'J') {
-                count += 2;
-            } else {
-                count++;
-            }
-        }
-        return count;
-    }
-
-    public void endOfClass() { // All the data for the current class has been
-                               // read
-        final int numFields = tempFieldDesc.size();
-        class_field_count[index] = numFields;
-        field_descr[index] = new CPNameAndType[numFields];
-        field_flags[index] = new long[numFields];
-        for (int i = 0; i < numFields; i++) {
-            field_descr[index][i] = (CPNameAndType) tempFieldDesc.get(i);
-            field_flags[index][i] = ((Long) tempFieldFlags.get(i)).longValue();
-        }
-        final int numMethods = tempMethodDesc.size();
-        class_method_count[index] = numMethods;
-        method_descr[index] = new CPNameAndType[numMethods];
-        method_flags[index] = new long[numMethods];
-        for (int i = 0; i < numMethods; i++) {
-            method_descr[index][i] = (CPNameAndType) tempMethodDesc.get(i);
-            method_flags[index][i] = ((Long) tempMethodFlags.get(i)).longValue();
-        }
-        tempFieldDesc.clear();
-        tempFieldFlags.clear();
-        tempMethodDesc.clear();
-        tempMethodFlags.clear();
-        index++;
-    }
-
-    public void addSourceFile(final String source) {
-        String implicitSourceFileName = class_this[index].toString();
-        if (implicitSourceFileName.indexOf('$') != -1) {
-            implicitSourceFileName = implicitSourceFileName.substring(0, implicitSourceFileName.indexOf('$'));
-        }
-        implicitSourceFileName = implicitSourceFileName.substring(implicitSourceFileName.lastIndexOf('/') + 1)
-            + ".java";
-        if (source.equals(implicitSourceFileName)) {
-            classSourceFile.add(null);
-        } else {
-            classSourceFile.add(cpBands.getCPUtf8(source));
-        }
-        class_flags[index] |= (1 << 17);
-    }
-
-    public void addEnclosingMethod(final String owner, final String name, final String desc) {
-        class_flags[index] |= (1 << 18);
-        classEnclosingMethodClass.add(cpBands.getCPClass(owner));
-        classEnclosingMethodDesc.add(name == null ? null : cpBands.getCPNameAndType(name, desc));
-    }
-
-    public void addClassAttribute(final NewAttribute attribute) {
-        // TODO: backwards calls
-        final String attributeName = attribute.type;
-        for (Object classAttributeBand : classAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) classAttributeBand;
-            if (bands.getAttributeName().equals(attributeName)) {
-                bands.addAttribute(attribute);
-                final int flagIndex = bands.getFlagIndex();
-                class_flags[index] |= (1 << flagIndex);
-                return;
-            }
-        }
-        throw new IllegalArgumentException("No suitable definition for " + attributeName);
-    }
-
-    public void addFieldAttribute(final NewAttribute attribute) {
-        final String attributeName = attribute.type;
-        for (Object fieldAttributeBand : fieldAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) fieldAttributeBand;
-            if (bands.getAttributeName().equals(attributeName)) {
-                bands.addAttribute(attribute);
-                final int flagIndex = bands.getFlagIndex();
-                final Long flags = (Long) tempFieldFlags.remove(tempFieldFlags.size() - 1);
-                tempFieldFlags.add(Long.valueOf(flags.longValue() | (1 << flagIndex)));
-                return;
-            }
-        }
-        throw new IllegalArgumentException("No suitable definition for " + attributeName);
-    }
-
-    public void addMethodAttribute(final NewAttribute attribute) {
-        final String attributeName = attribute.type;
-        for (Object methodAttributeBand : methodAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) methodAttributeBand;
-            if (bands.getAttributeName().equals(attributeName)) {
-                bands.addAttribute(attribute);
-                final int flagIndex = bands.getFlagIndex();
-                final Long flags = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1);
-                tempMethodFlags.add(Long.valueOf(flags.longValue() | (1 << flagIndex)));
-                return;
-            }
-        }
-        throw new IllegalArgumentException("No suitable definition for " + attributeName);
-    }
-
-    public void addCodeAttribute(final NewAttribute attribute) {
-        final String attributeName = attribute.type;
-        for (Object codeAttributeBand : codeAttributeBands) {
-            final NewAttributeBands bands = (NewAttributeBands) codeAttributeBand;
-            if (bands.getAttributeName().equals(attributeName)) {
-                bands.addAttribute(attribute);
-                final int flagIndex = bands.getFlagIndex();
-                final Long flags = (Long) codeFlags.remove(codeFlags.size() - 1);
-                codeFlags.add(Long.valueOf(flags.longValue() | (1 << flagIndex)));
-                return;
-            }
-        }
-        throw new IllegalArgumentException("No suitable definition for " + attributeName);
-    }
-
-    public void addMaxStack(final int maxStack, int maxLocals) {
-        final Long latestFlag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1);
-        final Long newFlag = Long.valueOf(latestFlag.intValue() | (1 << 17));
-        tempMethodFlags.add(newFlag);
-        codeMaxStack.add(maxStack);
-        if ((newFlag.longValue() & (1 << 3)) == 0) { // not static
-            maxLocals--; // minus 'this' local
-        }
-        maxLocals -= numMethodArgs;
-        codeMaxLocals.add(maxLocals);
-    }
-
-    public void addCode() {
-        codeHandlerCount.add(0);
-        if (!stripDebug) {
-            codeFlags.add(Long.valueOf(1 << 2));
-            codeLocalVariableTableN.add(0);
-        }
-    }
-
-    public void addHandler(final Label start, final Label end, final Label handler, final String type) {
-        final int handlers = codeHandlerCount.remove(codeHandlerCount.size() - 1);
-        codeHandlerCount.add(handlers + 1);
-        codeHandlerStartP.add(start);
-        codeHandlerEndPO.add(end);
-        codeHandlerCatchPO.add(handler);
-        codeHandlerClass.add(type == null ? null : cpBands.getCPClass(type));
-    }
-
-    public void addLineNumber(final int line, final Label start) {
-        final Long latestCodeFlag = (Long) codeFlags.get(codeFlags.size() - 1);
-        if ((latestCodeFlag.intValue() & (1 << 1)) == 0) {
-            codeFlags.remove(codeFlags.size() - 1);
-            codeFlags.add(Long.valueOf(latestCodeFlag.intValue() | (1 << 1)));
-            codeLineNumberTableN.add(1);
-        } else {
-            codeLineNumberTableN.increment(codeLineNumberTableN.size() - 1);
-        }
-        codeLineNumberTableLine.add(line);
-        codeLineNumberTableBciP.add(start);
-    }
-
-    public void addLocalVariable(final String name, final String desc, final String signature, final Label start,
-        final Label end, final int indx) {
-        if (signature != null) { // LocalVariableTypeTable attribute
-            final Long latestCodeFlag = (Long) codeFlags.get(codeFlags.size() - 1);
-            if ((latestCodeFlag.intValue() & (1 << 3)) == 0) {
-                codeFlags.remove(codeFlags.size() - 1);
-                codeFlags.add(Long.valueOf(latestCodeFlag.intValue() | (1 << 3)));
-                codeLocalVariableTypeTableN.add(1);
-            } else {
-                codeLocalVariableTypeTableN.increment(codeLocalVariableTypeTableN.size() - 1);
-            }
-            codeLocalVariableTypeTableBciP.add(start);
-            codeLocalVariableTypeTableSpanO.add(end);
-            codeLocalVariableTypeTableNameRU.add(cpBands.getCPUtf8(name));
-            codeLocalVariableTypeTableTypeRS.add(cpBands.getCPSignature(signature));
-            codeLocalVariableTypeTableSlot.add(indx);
-        }
-        // LocalVariableTable attribute
-        codeLocalVariableTableN.increment(codeLocalVariableTableN.size() - 1);
-        codeLocalVariableTableBciP.add(start);
-        codeLocalVariableTableSpanO.add(end);
-        codeLocalVariableTableNameRU.add(cpBands.getCPUtf8(name));
-        codeLocalVariableTableTypeRS.add(cpBands.getCPSignature(desc));
-        codeLocalVariableTableSlot.add(indx);
-    }
-
-    public void doBciRenumbering(final IntList bciRenumbering, final Map<Label, Integer> labelsToOffsets) {
-        renumberBci(codeLineNumberTableBciP, bciRenumbering, labelsToOffsets);
-        renumberBci(codeLocalVariableTableBciP, bciRenumbering, labelsToOffsets);
-        renumberOffsetBci(codeLocalVariableTableBciP, codeLocalVariableTableSpanO, bciRenumbering, labelsToOffsets);
-        renumberBci(codeLocalVariableTypeTableBciP, bciRenumbering, labelsToOffsets);
-        renumberOffsetBci(codeLocalVariableTypeTableBciP, codeLocalVariableTypeTableSpanO, bciRenumbering,
-            labelsToOffsets);
-        renumberBci(codeHandlerStartP, bciRenumbering, labelsToOffsets);
-        renumberOffsetBci(codeHandlerStartP, codeHandlerEndPO, bciRenumbering, labelsToOffsets);
-        renumberDoubleOffsetBci(codeHandlerStartP, codeHandlerEndPO, codeHandlerCatchPO, bciRenumbering,
-            labelsToOffsets);
-
-        for (Object classAttributeBand : classAttributeBands) {
-            final NewAttributeBands newAttributeBandSet = (NewAttributeBands) classAttributeBand;
-            newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
-        }
-        for (Object methodAttributeBand : methodAttributeBands) {
-            final NewAttributeBands newAttributeBandSet = (NewAttributeBands) methodAttributeBand;
-            newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
-        }
-        for (Object fieldAttributeBand : fieldAttributeBands) {
-            final NewAttributeBands newAttributeBandSet = (NewAttributeBands) fieldAttributeBand;
-            newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
-        }
-        for (Object codeAttributeBand : codeAttributeBands) {
-            final NewAttributeBands newAttributeBandSet = (NewAttributeBands) codeAttributeBand;
-            newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
-        }
-    }
-
-    private void renumberBci(final List list, final IntList bciRenumbering, final Map<Label, Integer> labelsToOffsets) {
-        for (int i = list.size() - 1; i >= 0; i--) {
-            final Object label = list.get(i);
-            if (label instanceof Integer) {
-                break;
-            }
-            if (label instanceof Label) {
-                list.remove(i);
-                final Integer bytecodeIndex = labelsToOffsets.get(label);
-                list.add(i, Integer.valueOf(bciRenumbering.get(bytecodeIndex.intValue())));
-            }
-        }
-    }
-
-    private void renumberOffsetBci(final List relative, final List list, final IntList bciRenumbering,
-        final Map<Label, Integer> labelsToOffsets) {
-        for (int i = list.size() - 1; i >= 0; i--) {
-            final Object label = list.get(i);
-            if (label instanceof Integer) {
-                break;
-            }
-            if (label instanceof Label) {
-                list.remove(i);
-                final Integer bytecodeIndex = labelsToOffsets.get(label);
-                final Integer renumberedOffset = Integer
-                    .valueOf(bciRenumbering.get(bytecodeIndex.intValue()) - ((Integer) relative.get(i)).intValue());
-                list.add(i, renumberedOffset);
-            }
-        }
-    }
-
-    private void renumberDoubleOffsetBci(final List relative, final List firstOffset, final List list,
-        final IntList bciRenumbering, final Map<Label, Integer> labelsToOffsets) {
-        // TODO: There's probably a nicer way of doing this...
-        for (int i = list.size() - 1; i >= 0; i--) {
-            final Object label = list.get(i);
-            if (label instanceof Integer) {
-                break;
-            }
-            if (label instanceof Label) {
-                list.remove(i);
-                final Integer bytecodeIndex = labelsToOffsets.get(label);
-                final Integer renumberedOffset = Integer.valueOf(bciRenumbering.get(bytecodeIndex.intValue())
-                    - ((Integer) relative.get(i)).intValue() - ((Integer) firstOffset.get(i)).intValue());
-                list.add(i, renumberedOffset);
-            }
-        }
-    }
-
-    public boolean isAnySyntheticClasses() {
-        return anySyntheticClasses;
-    }
-
-    public boolean isAnySyntheticFields() {
-        return anySyntheticFields;
-    }
-
-    public boolean isAnySyntheticMethods() {
-        return anySyntheticMethods;
-    }
-
-    public void addParameterAnnotation(final int parameter, final String desc, final boolean visible, final List nameRU,
-        final List t, final List values, final List caseArrayN, final List nestTypeRS, final List nestNameRU,
-        final List nestPairN) {
-        if (visible) {
-            if (tempMethodRVPA == null) {
-                tempMethodRVPA = new TempParamAnnotation(numMethodArgs);
-                tempMethodRVPA.addParameterAnnotation(parameter, desc, nameRU, t, values, caseArrayN, nestTypeRS,
-                    nestNameRU, nestPairN);
-            }
-            final Long flag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1);
-            tempMethodFlags.add(Long.valueOf(flag.longValue() | (1 << 23)));
-        } else {
-            if (tempMethodRIPA == null) {
-                tempMethodRIPA = new TempParamAnnotation(numMethodArgs);
-                tempMethodRIPA.addParameterAnnotation(parameter, desc, nameRU, t, values, caseArrayN, nestTypeRS,
-                    nestNameRU, nestPairN);
-            }
-            final Long flag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1);
-            tempMethodFlags.add(Long.valueOf(flag.longValue() | (1 << 24)));
-        }
-    }
-
-    private static class TempParamAnnotation {
-
-        int numParams;
-        int[] annoN;
-        IntList pairN = new IntList();
-        List typeRS = new ArrayList();
-        List nameRU = new ArrayList();
-        List t = new ArrayList();
-        List values = new ArrayList();
-        List caseArrayN = new ArrayList();
-        List nestTypeRS = new ArrayList();
-        List nestNameRU = new ArrayList();
-        List nestPairN = new ArrayList();
-
-        public TempParamAnnotation(final int numParams) {
-            this.numParams = numParams;
-            annoN = new int[numParams];
-        }
-
-        public void addParameterAnnotation(final int parameter, final String desc, final List nameRU, final List t,
-            final List values, final List caseArrayN, final List nestTypeRS, final List nestNameRU,
-            final List nestPairN) {
-            annoN[parameter]++;
-            typeRS.add(desc);
-            pairN.add(nameRU.size());
-            this.nameRU.addAll(nameRU);
-            this.t.addAll(t);
-            this.values.addAll(values);
-            this.caseArrayN.addAll(caseArrayN);
-            this.nestTypeRS.addAll(nestTypeRS);
-            this.nestNameRU.addAll(nestNameRU);
-            this.nestPairN.addAll(nestPairN);
-        }
-    }
-
-    public void addAnnotation(final int context, final String desc, final boolean visible, final List nameRU,
-        final List t, final List values, final List caseArrayN, final List nestTypeRS, final List nestNameRU,
-        final List nestPairN) {
-        switch (context) {
-        case MetadataBandGroup.CONTEXT_CLASS:
-            if (visible) {
-                class_RVA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
-                if ((class_flags[index] & (1 << 21)) != 0) {
-                    class_RVA_bands.incrementAnnoN();
-                } else {
-                    class_RVA_bands.newEntryInAnnoN();
-                    class_flags[index] = class_flags[index] | (1 << 21);
-                }
-            } else {
-                class_RIA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
-                if ((class_flags[index] & (1 << 22)) != 0) {
-                    class_RIA_bands.incrementAnnoN();
-                } else {
-                    class_RIA_bands.newEntryInAnnoN();
-                    class_flags[index] = class_flags[index] | (1 << 22);
-                }
-            }
-            break;
-        case MetadataBandGroup.CONTEXT_FIELD:
-            if (visible) {
-                field_RVA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
-                final Long flag = (Long) tempFieldFlags.remove(tempFieldFlags.size() - 1);
-                if ((flag.intValue() & (1 << 21)) != 0) {
-                    field_RVA_bands.incrementAnnoN();
-                } else {
-                    field_RVA_bands.newEntryInAnnoN();
-                }
-                tempFieldFlags.add(Long.valueOf(flag.intValue() | (1 << 21)));
-            } else {
-                field_RIA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
-                final Long flag = (Long) tempFieldFlags.remove(tempFieldFlags.size() - 1);
-                if ((flag.intValue() & (1 << 22)) != 0) {
-                    field_RIA_bands.incrementAnnoN();
-                } else {
-                    field_RIA_bands.newEntryInAnnoN();
-                }
-                tempFieldFlags.add(Long.valueOf(flag.intValue() | (1 << 22)));
-            }
-            break;
-        case MetadataBandGroup.CONTEXT_METHOD:
-            if (visible) {
-                method_RVA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
-                final Long flag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1);
-                if ((flag.intValue() & (1 << 21)) != 0) {
-                    method_RVA_bands.incrementAnnoN();
-                } else {
-                    method_RVA_bands.newEntryInAnnoN();
-                }
-                tempMethodFlags.add(Long.valueOf(flag.intValue() | (1 << 21)));
-            } else {
-                method_RIA_bands.addAnnotation(desc, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
-                final Long flag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1);
-                if ((flag.intValue() & (1 << 22)) != 0) {
-                    method_RIA_bands.incrementAnnoN();
-                } else {
-                    method_RIA_bands.newEntryInAnnoN();
-                }
-                tempMethodFlags.add(Long.valueOf(flag.intValue() | (1 << 22)));
-            }
-            break;
-        }
-    }
-
-    public void addAnnotationDefault(final List nameRU, final List t, final List values, final List caseArrayN,
-        final List nestTypeRS, final List nestNameRU, final List nestPairN) {
-        method_AD_bands.addAnnotation(null, nameRU, t, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
-        final Long flag = (Long) tempMethodFlags.remove(tempMethodFlags.size() - 1);
-        tempMethodFlags.add(Long.valueOf(flag.longValue() | (1 << 25)));
-    }
-
-    /**
-     * Remove all entries for the current class
-     */
-    public void removeCurrentClass() {
-        // Note - this doesn't remove any entries added to the constant pool but
-        // that shouldn't be a problem
-        if ((class_flags[index] & (1 << 17)) != 0) {
-            classSourceFile.remove(classSourceFile.size() - 1);
-        }
-        if ((class_flags[index] & (1 << 18)) != 0) {
-            classEnclosingMethodClass.remove(classEnclosingMethodClass.size() - 1);
-            classEnclosingMethodDesc.remove(classEnclosingMethodDesc.size() - 1);
-        }
-        if ((class_flags[index] & (1 << 19)) != 0) {
-            classSignature.remove(classSignature.size() - 1);
-        }
-        if ((class_flags[index] & (1 << 21)) != 0) {
-            class_RVA_bands.removeLatest();
-        }
-        if ((class_flags[index] & (1 << 22)) != 0) {
-            class_RIA_bands.removeLatest();
-        }
-        for (Object tempFieldFlag : tempFieldFlags) {
-            final Long flagsL = (Long) tempFieldFlag;
-            final long flags = flagsL.longValue();
-            if ((flags & (1 << 19)) != 0) {
-                fieldSignature.remove(fieldSignature.size() - 1);
-            }
-            if ((flags & (1 << 17)) != 0) {
-                fieldConstantValueKQ.remove(fieldConstantValueKQ.size() - 1);
-            }
-            if ((flags & (1 << 21)) != 0) {
-                field_RVA_bands.removeLatest();
-            }
-            if ((flags & (1 << 22)) != 0) {
-                field_RIA_bands.removeLatest();
-            }
-        }
-        for (Object tempMethodFlag : tempMethodFlags) {
-            final Long flagsL = (Long) tempMethodFlag;
-            final long flags = flagsL.longValue();
-            if ((flags & (1 << 19)) != 0) {
-                methodSignature.remove(methodSignature.size() - 1);
-            }
-            if ((flags & (1 << 18)) != 0) {
-                final int exceptions = methodExceptionNumber.remove(methodExceptionNumber.size() - 1);
-                for (int i = 0; i < exceptions; i++) {
-                    methodExceptionClasses.remove(methodExceptionClasses.size() - 1);
-                }
-            }
-            if ((flags & (1 << 17)) != 0) { // has code attribute
-                codeMaxLocals.remove(codeMaxLocals.size() - 1);
-                codeMaxStack.remove(codeMaxStack.size() - 1);
-                final int handlers = codeHandlerCount.remove(codeHandlerCount.size() - 1);
-                for (int i = 0; i < handlers; i++) {
-                    final int index = codeHandlerStartP.size() - 1;
-                    codeHandlerStartP.remove(index);
-                    codeHandlerEndPO.remove(index);
-                    codeHandlerCatchPO.remove(index);
-                    codeHandlerClass.remove(index);
-                }
-                if (!stripDebug) {
-                    final long cdeFlags = ((Long) codeFlags.remove(codeFlags.size() - 1)).longValue();
-                    final int numLocalVariables = codeLocalVariableTableN.remove(codeLocalVariableTableN.size() - 1);
-                    for (int i = 0; i < numLocalVariables; i++) {
-                        final int location = codeLocalVariableTableBciP.size() - 1;
-                        codeLocalVariableTableBciP.remove(location);
-                        codeLocalVariableTableSpanO.remove(location);
-                        codeLocalVariableTableNameRU.remove(location);
-                        codeLocalVariableTableTypeRS.remove(location);
-                        codeLocalVariableTableSlot.remove(location);
-                    }
-                    if ((cdeFlags & (1 << 3)) != 0) {
-                        final int numLocalVariablesInTypeTable = codeLocalVariableTypeTableN
-                            .remove(codeLocalVariableTypeTableN.size() - 1);
-                        for (int i = 0; i < numLocalVariablesInTypeTable; i++) {
-                            final int location = codeLocalVariableTypeTableBciP.size() - 1;
-                            codeLocalVariableTypeTableBciP.remove(location);
-                            codeLocalVariableTypeTableSpanO.remove(location);
-                            codeLocalVariableTypeTableNameRU.remove(location);
-                            codeLocalVariableTypeTableTypeRS.remove(location);
-                            codeLocalVariableTypeTableSlot.remove(location);
-                        }
-                    }
-                    if ((cdeFlags & (1 << 1)) != 0) {
-                        final int numLineNumbers = codeLineNumberTableN.remove(codeLineNumberTableN.size() - 1);
-                        for (int i = 0; i < numLineNumbers; i++) {
-                            final int location = codeLineNumberTableBciP.size() - 1;
-                            codeLineNumberTableBciP.remove(location);
-                            codeLineNumberTableLine.remove(location);
-                        }
-                    }
-                }
-            }
-            if ((flags & (1 << 21)) != 0) {
-                method_RVA_bands.removeLatest();
-            }
-            if ((flags & (1 << 22)) != 0) {
-                method_RIA_bands.removeLatest();
-            }
-            if ((flags & (1 << 23)) != 0) {
-                method_RVPA_bands.removeLatest();
-            }
-            if ((flags & (1 << 24)) != 0) {
-                method_RIPA_bands.removeLatest();
-            }
-            if ((flags & (1 << 25)) != 0) {
-                method_AD_bands.removeLatest();
-            }
-        }
-        class_this[index] = null;
-        class_super[index] = null;
-        class_interface_count[index] = 0;
-        class_interface[index] = null;
-        major_versions[index] = 0;
-        class_flags[index] = 0;
-        tempFieldDesc.clear();
-        tempFieldFlags.clear();
-        tempMethodDesc.clear();
-        tempMethodFlags.clear();
-        if (index > 0) {
-            index--;
-        }
-    }
-
-    public int numClassesProcessed() {
-        return index;
-    }
+	private final CpBands cpBands;
+	private final AttributeDefinitionBands attrBands;
+
+	private final CPClass[] class_this;
+	private final CPClass[] class_super;
+	private final CPClass[][] class_interface;
+	private final int[] class_interface_count;
+
+	private final int[] major_versions;
+
+	private final long[] class_flags;
+	private int[] class_attr_calls;
+	private final List<CPUTF8> classSourceFile = new ArrayList<>();
+	private final List<ConstantPoolEntry> classEnclosingMethodClass = new ArrayList<>();
+	private final List<ConstantPoolEntry> classEnclosingMethodDesc = new ArrayList<>();
+	private final List<CPSignature> classSignature = new ArrayList<>();
+
+	private final IntList classFileVersionMinor = new IntList();
+	private final IntList classFileVersionMajor = new IntList();
+
+	private final int[] class_field_count;
+	private final CPNameAndType[][] field_descr;
+	private final long[][] field_flags;
+	private int[] field_attr_calls;
+	private final List<CPConstant<?>> fieldConstantValueKQ = new ArrayList<>();
+	private final List<CPSignature> fieldSignature = new ArrayList<>();
+
+	private final int[] class_method_count;
+	private final CPNameAndType[][] method_descr;
+	private final long[][] method_flags;
+	private int[] method_attr_calls;
+	private final List<CPSignature> methodSignature = new ArrayList<>();
+	private final IntList methodExceptionNumber = new IntList();
+	private final List<CPClass> methodExceptionClasses = new ArrayList<>();
+
+	private int[] codeHeaders;
+	private final IntList codeMaxStack = new IntList();
+	private final IntList codeMaxLocals = new IntList();
+	private final IntList codeHandlerCount = new IntList();
+	private final List codeHandlerStartP = new ArrayList();
+	private final List codeHandlerEndPO = new ArrayList();
+	private final List codeHandlerCatchPO = new ArrayList();
+	private final List<CPClass> codeHandlerClass = new ArrayList<>();
+	private final List<Long> codeFlags = new ArrayList<>();
+	private int[] code_attr_calls;
+	private final IntList codeLineNumberTableN = new IntList();
+	private final List codeLineNumberTableBciP = new ArrayList();
+	private final IntList codeLineNumberTableLine = new IntList();
+	private final IntList codeLocalVariableTableN = new IntList();
+	private final List codeLocalVariableTableBciP = new ArrayList();
+	private final List codeLocalVariableTableSpanO = new ArrayList();
+	private final List<ConstantPoolEntry> codeLocalVariableTableNameRU = new ArrayList<>();
+	private final List<ConstantPoolEntry> codeLocalVariableTableTypeRS = new ArrayList<>();
+	private final IntList codeLocalVariableTableSlot = new IntList();
+	private final IntList codeLocalVariableTypeTableN = new IntList();
+	private final List codeLocalVariableTypeTableBciP = new ArrayList();
+	private final List codeLocalVariableTypeTableSpanO = new ArrayList();
+	private final List<ConstantPoolEntry> codeLocalVariableTypeTableNameRU = new ArrayList<>();
+	private final List<ConstantPoolEntry> codeLocalVariableTypeTableTypeRS = new ArrayList<>();
+	private final IntList codeLocalVariableTypeTableSlot = new IntList();
+
+	private final MetadataBandGroup class_RVA_bands;
+	private final MetadataBandGroup class_RIA_bands;
+	private final MetadataBandGroup field_RVA_bands;
+	private final MetadataBandGroup field_RIA_bands;
+	private final MetadataBandGroup method_RVA_bands;
+	private final MetadataBandGroup method_RIA_bands;
+	private final MetadataBandGroup method_RVPA_bands;
+	private final MetadataBandGroup method_RIPA_bands;
+	private final MetadataBandGroup method_AD_bands;
+
+	private final List<NewAttributeBands> classAttributeBands = new ArrayList<>();
+	private final List<NewAttributeBands> methodAttributeBands = new ArrayList<>();
+	private final List<NewAttributeBands> fieldAttributeBands = new ArrayList<>();
+	private final List<NewAttributeBands> codeAttributeBands = new ArrayList<>();
+
+	private final List<Long> tempFieldFlags = new ArrayList<>();
+	private final List<CPNameAndType> tempFieldDesc = new ArrayList<>();
+	private final List<Long> tempMethodFlags = new ArrayList<>();
+	private final List<CPNameAndType> tempMethodDesc = new ArrayList<>();
+	private TempParamAnnotation tempMethodRVPA;
+	private TempParamAnnotation tempMethodRIPA;
+
+	private boolean anySyntheticClasses = false;
+	private boolean anySyntheticFields = false;
+	private boolean anySyntheticMethods = false;
+	private final Segment segment;
+
+	private final Map<CPClass, Set<CPClass>> classReferencesInnerClass = new HashMap<>();
+	private final boolean stripDebug;
+
+	private int index = 0;
+
+	private int numMethodArgs = 0;
+	private int[] class_InnerClasses_N;
+	private CPClass[] class_InnerClasses_RC;
+	private int[] class_InnerClasses_F;
+	private List<CPClass> classInnerClassesOuterRCN;
+	private List<CPUTF8> classInnerClassesNameRUN;
+
+	public ClassBands(final Segment segment, final int numClasses, final int effort, final boolean stripDebug)
+			throws IOException {
+		super(effort, segment.getSegmentHeader());
+		this.stripDebug = stripDebug;
+		this.segment = segment;
+		this.cpBands = segment.getCpBands();
+		this.attrBands = segment.getAttrBands();
+		class_this = new CPClass[numClasses];
+		class_super = new CPClass[numClasses];
+		class_interface_count = new int[numClasses];
+		class_interface = new CPClass[numClasses][];
+		class_field_count = new int[numClasses];
+		class_method_count = new int[numClasses];
+		field_descr = new CPNameAndType[numClasses][];
+		field_flags = new long[numClasses][];
+		method_descr = new CPNameAndType[numClasses][];
+		method_flags = new long[numClasses][];
+		for (int i = 0; i < numClasses; i++) {
+			field_flags[i] = new long[0];
+			method_flags[i] = new long[0];
+		}
+		// minor_versions = new int[numClasses];
+		major_versions = new int[numClasses];
+		class_flags = new long[numClasses];
+
+		class_RVA_bands = new MetadataBandGroup("RVA", MetadataBandGroup.CONTEXT_CLASS, cpBands, segmentHeader, effort);
+		class_RIA_bands = new MetadataBandGroup("RIA", MetadataBandGroup.CONTEXT_CLASS, cpBands, segmentHeader, effort);
+		field_RVA_bands = new MetadataBandGroup("RVA", MetadataBandGroup.CONTEXT_FIELD, cpBands, segmentHeader, effort);
+		field_RIA_bands = new MetadataBandGroup("RIA", MetadataBandGroup.CONTEXT_FIELD, cpBands, segmentHeader, effort);
+		method_RVA_bands = new MetadataBandGroup("RVA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader,
+				effort);
+		method_RIA_bands = new MetadataBandGroup("RIA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader,
+				effort);
+		method_RVPA_bands = new MetadataBandGroup("RVPA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader,
+				effort);
+		method_RIPA_bands = new MetadataBandGroup("RIPA", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader,
+				effort);
+		method_AD_bands = new MetadataBandGroup("AD", MetadataBandGroup.CONTEXT_METHOD, cpBands, segmentHeader, effort);
+
+		createNewAttributeBands();
+	}
+
+	private void createNewAttributeBands() throws IOException {
+		for (AttributeDefinition def : attrBands.getClassAttributeLayouts()) {
+			classAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
+		}
+		for (AttributeDefinition def : attrBands.getMethodAttributeLayouts()) {
+			methodAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
+		}
+		for (AttributeDefinition def : attrBands.getFieldAttributeLayouts()) {
+			fieldAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
+		}
+		for (AttributeDefinition def : attrBands.getCodeAttributeLayouts()) {
+			codeAttributeBands.add(new NewAttributeBands(effort, cpBands, segment.getSegmentHeader(), def));
+		}
+	}
+
+	public void addClass(final int major, int flags, final String className, final String signature,
+			final String superName, final String[] interfaces) {
+		class_this[index] = cpBands.getCPClass(className);
+		class_super[index] = cpBands.getCPClass(superName);
+		class_interface_count[index] = interfaces.length;
+		class_interface[index] = new CPClass[interfaces.length];
+		for (int i = 0; i < interfaces.length; i++) {
+			class_interface[index][i] = cpBands.getCPClass(interfaces[i]);
+		}
+		major_versions[index] = major;
+		class_flags[index] = flags;
+		if (!anySyntheticClasses && ((flags & (1 << 12)) != 0)
+				&& segment.getCurrentClassReader().hasSyntheticAttributes()) {
+			cpBands.addCPUtf8("Synthetic");
+			anySyntheticClasses = true;
+		}
+		if ((flags & Opcodes.ACC_DEPRECATED) != 0) { // ASM uses (1<<17) flag for deprecated
+			flags = flags & ~Opcodes.ACC_DEPRECATED;
+			flags = flags | (1 << 20);
+		}
+		if (signature != null) {
+			class_flags[index] |= (1 << 19);
+			classSignature.add(cpBands.getCPSignature(signature));
+		}
+	}
+
+	public void currentClassReferencesInnerClass(final CPClass inner) {
+		if (!(index >= class_this.length)) {
+			final CPClass currentClass = class_this[index];
+			if (currentClass != null && !currentClass.equals(inner)
+					&& !isInnerClassOf(currentClass.toString(), inner)) {
+				Set<CPClass> referencedInnerClasses = classReferencesInnerClass.get(currentClass);
+				if (referencedInnerClasses == null) {
+					referencedInnerClasses = new HashSet<>();
+					classReferencesInnerClass.put(currentClass, referencedInnerClasses);
+				}
+				referencedInnerClasses.add(inner);
+			}
+		}
+	}
+
+	private boolean isInnerClassOf(final String possibleInner, final CPClass possibleOuter) {
+		if (isInnerClass(possibleInner)) {
+			final String superClassName = possibleInner.substring(0, possibleInner.lastIndexOf('$'));
+			if (superClassName.equals(possibleOuter.toString())) {
+				return true;
+			}
+			return isInnerClassOf(superClassName, possibleOuter);
+		}
+		return false;
+	}
+
+	private boolean isInnerClass(final String possibleInner) {
+		return possibleInner.indexOf('$') != -1;
+	}
+
+	public void addField(int flags, final String name, final String desc, final String signature, final Object value) {
+		flags = flags & 0xFFFF;
+		tempFieldDesc.add(cpBands.getCPNameAndType(name, desc));
+		if (signature != null) {
+			fieldSignature.add(cpBands.getCPSignature(signature));
+			flags |= (1 << 19);
+		}
+		if ((flags & Opcodes.ACC_DEPRECATED) != 0) { // ASM uses (1<<17) flag for deprecated
+			flags = flags & ~Opcodes.ACC_DEPRECATED;
+			flags = flags | (1 << 20);
+		}
+		if (value != null) {
+			fieldConstantValueKQ.add(cpBands.getConstant(value));
+			flags |= (1 << 17);
+		}
+		if (!anySyntheticFields && ((flags & (1 << 12)) != 0)
+				&& segment.getCurrentClassReader().hasSyntheticAttributes()) {
+			cpBands.addCPUtf8("Synthetic");
+			anySyntheticFields = true;
+		}
+		tempFieldFlags.add(Long.valueOf(flags));
+	}
+
+	/**
+	 * All input classes for the segment have now been read in, so this method is
+	 * called so that this class can calculate/complete anything it could not do
+	 * while classes were being read.
+	 */
+	public void finaliseBands() {
+		final int defaultMajorVersion = segmentHeader.getDefaultMajorVersion();
+		for (int i = 0; i < class_flags.length; i++) {
+			final int major = major_versions[i];
+			if (major != defaultMajorVersion) {
+				class_flags[i] |= 1 << 24;
+				classFileVersionMajor.add(major);
+				classFileVersionMinor.add(0);
+			}
+		}
+		// Calculate code headers
+		codeHeaders = new int[codeHandlerCount.size()];
+		int removed = 0;
+		for (int i = 0; i < codeHeaders.length; i++) {
+			final int numHandlers = codeHandlerCount.get(i - removed);
+			final int maxLocals = codeMaxLocals.get(i - removed);
+			final int maxStack = codeMaxStack.get(i - removed);
+			if (numHandlers == 0) {
+				final int header = maxLocals * 12 + maxStack + 1;
+				if (header < 145 && maxStack < 12) {
+					codeHeaders[i] = header;
+				}
+			} else if (numHandlers == 1) {
+				final int header = maxLocals * 8 + maxStack + 145;
+				if (header < 209 && maxStack < 8) {
+					codeHeaders[i] = header;
+				}
+			} else if (numHandlers == 2) {
+				final int header = maxLocals * 7 + maxStack + 209;
+				if (header < 256 && maxStack < 7) {
+					codeHeaders[i] = header;
+				}
+			}
+			if (codeHeaders[i] != 0) { // Remove the redundant values from
+										// codeHandlerCount, codeMaxLocals and
+										// codeMaxStack
+				codeHandlerCount.remove(i - removed);
+				codeMaxLocals.remove(i - removed);
+				codeMaxStack.remove(i - removed);
+				removed++;
+			} else if (!segment.getSegmentHeader().have_all_code_flags()) {
+				codeFlags.add(Long.valueOf(0));
+			}
+		}
+
+		// Compute any required IcLocals
+		final IntList innerClassesN = new IntList();
+		final List<IcTuple> icLocal = new ArrayList<>();
+		for (int i = 0; i < class_this.length; i++) {
+			final CPClass cpClass = class_this[i];
+			final Set<CPClass> referencedInnerClasses = classReferencesInnerClass.get(cpClass);
+			if (referencedInnerClasses != null) {
+				int innerN = 0;
+				final List<IcTuple> innerClasses = segment.getIcBands().getInnerClassesForOuter(cpClass.toString());
+				if (innerClasses != null) {
+					for (IcTuple element : innerClasses) {
+						referencedInnerClasses.remove(element.C);
+					}
+				}
+				for (CPClass inner : referencedInnerClasses) {
+					final IcTuple icTuple = segment.getIcBands().getIcTuple(inner);
+					if (icTuple != null && !icTuple.isAnonymous()) {
+						// should transmit an icLocal entry
+						icLocal.add(icTuple);
+						innerN++;
+					}
+				}
+				if (innerN != 0) {
+					innerClassesN.add(innerN);
+					class_flags[i] |= (1 << 23);
+				}
+			}
+		}
+		class_InnerClasses_N = innerClassesN.toArray();
+		class_InnerClasses_RC = new CPClass[icLocal.size()];
+		class_InnerClasses_F = new int[icLocal.size()];
+		classInnerClassesOuterRCN = new ArrayList<>();
+		classInnerClassesNameRUN = new ArrayList<>();
+		for (int i = 0; i < class_InnerClasses_RC.length; i++) {
+			final IcTuple icTuple = icLocal.get(i);
+			class_InnerClasses_RC[i] = (icTuple.C);
+			if (icTuple.C2 == null && icTuple.N == null) {
+				class_InnerClasses_F[i] = 0;
+			} else {
+				if (icTuple.F == 0) {
+					class_InnerClasses_F[i] = 0x00010000;
+				} else {
+					class_InnerClasses_F[i] = icTuple.F;
+				}
+				classInnerClassesOuterRCN.add(icTuple.C2);
+				classInnerClassesNameRUN.add(icTuple.N);
+			}
+		}
+		// Calculate any backwards calls from metadata bands
+		final IntList classAttrCalls = new IntList();
+		final IntList fieldAttrCalls = new IntList();
+		final IntList methodAttrCalls = new IntList();
+		final IntList codeAttrCalls = new IntList();
+
+		if (class_RVA_bands.hasContent()) {
+			classAttrCalls.add(class_RVA_bands.numBackwardsCalls());
+		}
+		if (class_RIA_bands.hasContent()) {
+			classAttrCalls.add(class_RIA_bands.numBackwardsCalls());
+		}
+		if (field_RVA_bands.hasContent()) {
+			fieldAttrCalls.add(field_RVA_bands.numBackwardsCalls());
+		}
+		if (field_RIA_bands.hasContent()) {
+			fieldAttrCalls.add(field_RIA_bands.numBackwardsCalls());
+		}
+		if (method_RVA_bands.hasContent()) {
+			methodAttrCalls.add(method_RVA_bands.numBackwardsCalls());
+		}
+		if (method_RIA_bands.hasContent()) {
+			methodAttrCalls.add(method_RIA_bands.numBackwardsCalls());
+		}
+		if (method_RVPA_bands.hasContent()) {
+			methodAttrCalls.add(method_RVPA_bands.numBackwardsCalls());
+		}
+		if (method_RIPA_bands.hasContent()) {
+			methodAttrCalls.add(method_RIPA_bands.numBackwardsCalls());
+		}
+		if (method_AD_bands.hasContent()) {
+			methodAttrCalls.add(method_AD_bands.numBackwardsCalls());
+		}
+
+		// Sort non-predefined attribute bands
+		final Comparator<NewAttributeBands> comparator = (arg0, arg1) -> arg0.getFlagIndex() - arg1.getFlagIndex();
+		classAttributeBands.sort(comparator);
+		methodAttributeBands.sort(comparator);
+		fieldAttributeBands.sort(comparator);
+		codeAttributeBands.sort(comparator);
+
+		for (NewAttributeBands bands : classAttributeBands) {
+			if (bands.isUsedAtLeastOnce()) {
+				for (int backwardsCallCount : bands.numBackwardsCalls()) {
+					classAttrCalls.add(backwardsCallCount);
+				}
+			}
+		}
+		for (NewAttributeBands bands : methodAttributeBands) {
+			if (bands.isUsedAtLeastOnce()) {
+				for (int backwardsCallCount : bands.numBackwardsCalls()) {
+					methodAttrCalls.add(backwardsCallCount);
+				}
+			}
+		}
+		for (NewAttributeBands bands : fieldAttributeBands) {
+			if (bands.isUsedAtLeastOnce()) {
+				for (int backwardsCallCount : bands.numBackwardsCalls()) {
+					fieldAttrCalls.add(backwardsCallCount);
+				}
+			}
+		}
+		for (NewAttributeBands bands : codeAttributeBands) {
+			if (bands.isUsedAtLeastOnce()) {
+				for (int backwardsCallCount : bands.numBackwardsCalls()) {
+					codeAttrCalls.add(backwardsCallCount);
+				}
+			}
+		}
+
+		class_attr_calls = classAttrCalls.toArray();
+		field_attr_calls = fieldAttrCalls.toArray();
+		method_attr_calls = methodAttrCalls.toArray();
+		code_attr_calls = codeAttrCalls.toArray();
+	}
+
+	@Override
+	public void pack(final OutputStream out) throws IOException, Pack200Exception {
+		PackingUtils.log("Writing class bands...");
+
+		byte[] encodedBand = encodeBandInt("class_this", getInts(class_this), Codec.DELTA5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_this[" + class_this.length + "]");
+
+		encodedBand = encodeBandInt("class_super", getInts(class_super), Codec.DELTA5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_super[" + class_super.length + "]");
+
+		encodedBand = encodeBandInt("class_interface_count", class_interface_count, Codec.DELTA5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_interface_count["
+				+ class_interface_count.length + "]");
+
+		final int totalInterfaces = sum(class_interface_count);
+		final int[] classInterface = new int[totalInterfaces];
+		int k = 0;
+		for (CPClass[] element : class_interface) {
+			if (element != null) {
+				for (final CPClass cpClass : element) {
+					classInterface[k] = cpClass.getIndex();
+					k++;
+				}
+			}
+		}
+
+		encodedBand = encodeBandInt("class_interface", classInterface, Codec.DELTA5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_interface[" + classInterface.length + "]");
+
+		encodedBand = encodeBandInt("class_field_count", class_field_count, Codec.DELTA5);
+		out.write(encodedBand);
+		PackingUtils
+				.log("Wrote " + encodedBand.length + " bytes from class_field_count[" + class_field_count.length + "]");
+
+		encodedBand = encodeBandInt("class_method_count", class_method_count, Codec.DELTA5);
+		out.write(encodedBand);
+		PackingUtils.log(
+				"Wrote " + encodedBand.length + " bytes from class_method_count[" + class_method_count.length + "]");
+
+		final int totalFields = sum(class_field_count);
+		final int[] fieldDescr = new int[totalFields];
+		k = 0;
+		for (int i = 0; i < index; i++) {
+			for (int j = 0; j < field_descr[i].length; j++) {
+				final CPNameAndType descr = field_descr[i][j];
+				fieldDescr[k] = descr.getIndex();
+				k++;
+			}
+		}
+
+		encodedBand = encodeBandInt("field_descr", fieldDescr, Codec.DELTA5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from field_descr[" + fieldDescr.length + "]");
+
+		writeFieldAttributeBands(out);
+
+		final int totalMethods = sum(class_method_count);
+		final int[] methodDescr = new int[totalMethods];
+		k = 0;
+		for (int i = 0; i < index; i++) {
+			for (int j = 0; j < method_descr[i].length; j++) {
+				final CPNameAndType descr = method_descr[i][j];
+				methodDescr[k] = descr.getIndex();
+				k++;
+			}
+		}
+
+		encodedBand = encodeBandInt("method_descr", methodDescr, Codec.MDELTA5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from method_descr[" + methodDescr.length + "]");
+
+		writeMethodAttributeBands(out);
+		writeClassAttributeBands(out);
+		writeCodeBands(out);
+	}
+
+	private int sum(final int[] ints) {
+		int sum = 0;
+		for (int j : ints) {
+			sum += j;
+		}
+		return sum;
+	}
+
+	private void writeFieldAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
+		byte[] encodedBand = encodeFlags("field_flags", field_flags, Codec.UNSIGNED5, Codec.UNSIGNED5,
+				segmentHeader.have_field_flags_hi());
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from field_flags[" + field_flags.length + "]");
+
+		// *field_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
+		// *field_attr_indexes :UNSIGNED5 [SUM(*field_attr_count)]
+		encodedBand = encodeBandInt("field_attr_calls", field_attr_calls, Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils
+				.log("Wrote " + encodedBand.length + " bytes from field_attr_calls[" + field_attr_calls.length + "]");
+
+		encodedBand = encodeBandInt("fieldConstantValueKQ", cpEntryListToArray(fieldConstantValueKQ), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from fieldConstantValueKQ["
+				+ fieldConstantValueKQ.size() + "]");
+
+		encodedBand = encodeBandInt("fieldSignature", cpEntryListToArray(fieldSignature), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from fieldSignature[" + fieldSignature.size() + "]");
+
+		field_RVA_bands.pack(out);
+		field_RIA_bands.pack(out);
+		for (NewAttributeBands bands : fieldAttributeBands) {
+			bands.pack(out);
+		}
+	}
+
+	private void writeMethodAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
+		byte[] encodedBand = encodeFlags("method_flags", method_flags, Codec.UNSIGNED5, Codec.UNSIGNED5,
+				segmentHeader.have_method_flags_hi());
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from method_flags[" + method_flags.length + "]");
+
+		// *method_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
+		// *method_attr_indexes :UNSIGNED5 [SUM(*method_attr_count)]
+		encodedBand = encodeBandInt("method_attr_calls", method_attr_calls, Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils
+				.log("Wrote " + encodedBand.length + " bytes from method_attr_calls[" + method_attr_calls.length + "]");
+
+		encodedBand = encodeBandInt("methodExceptionNumber", methodExceptionNumber.toArray(), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from methodExceptionNumber["
+				+ methodExceptionNumber.size() + "]");
+
+		encodedBand = encodeBandInt("methodExceptionClasses", cpEntryListToArray(methodExceptionClasses),
+				Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from methodExceptionClasses["
+				+ methodExceptionClasses.size() + "]");
+
+		encodedBand = encodeBandInt("methodSignature", cpEntryListToArray(methodSignature), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from methodSignature[" + methodSignature.size() + "]");
+
+		method_RVA_bands.pack(out);
+		method_RIA_bands.pack(out);
+		method_RVPA_bands.pack(out);
+		method_RIPA_bands.pack(out);
+		method_AD_bands.pack(out);
+		for (NewAttributeBands bands : methodAttributeBands) {
+			bands.pack(out);
+		}
+	}
+
+	private void writeClassAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
+		byte[] encodedBand = encodeFlags("class_flags", class_flags, Codec.UNSIGNED5, Codec.UNSIGNED5,
+				segmentHeader.have_class_flags_hi());
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_flags[" + class_flags.length + "]");
+
+		// These bands are not needed, but could be used to reduce the size of
+		// the archive if there are enough different non-standard attributes
+		// defined that segmentHeader.have_class_flags_hi() is true. The same
+		// applies to method_attr_count, field_attr_count, code_attr_count etc.
+
+		// *class_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
+		// *class_attr_indexes :UNSIGNED5 [SUM(*class_attr_count)]
+
+		encodedBand = encodeBandInt("class_attr_calls", class_attr_calls, Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils
+				.log("Wrote " + encodedBand.length + " bytes from class_attr_calls[" + class_attr_calls.length + "]");
+
+		encodedBand = encodeBandInt("classSourceFile", cpEntryOrNullListToArray(classSourceFile), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from classSourceFile[" + classSourceFile.size() + "]");
+
+		encodedBand = encodeBandInt("class_enclosing_method_RC", cpEntryListToArray(classEnclosingMethodClass),
+				Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_enclosing_method_RC["
+				+ classEnclosingMethodClass.size() + "]");
+
+		encodedBand = encodeBandInt("class_EnclosingMethod_RDN", cpEntryOrNullListToArray(classEnclosingMethodDesc),
+				Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_EnclosingMethod_RDN["
+				+ classEnclosingMethodDesc.size() + "]");
+
+		encodedBand = encodeBandInt("class_Signature_RS", cpEntryListToArray(classSignature), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils
+				.log("Wrote " + encodedBand.length + " bytes from class_Signature_RS[" + classSignature.size() + "]");
+
+		class_RVA_bands.pack(out);
+		class_RIA_bands.pack(out);
+
+		encodedBand = encodeBandInt("class_InnerClasses_N", class_InnerClasses_N, Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_N["
+				+ class_InnerClasses_N.length + "]");
+
+		encodedBand = encodeBandInt("class_InnerClasses_RC", getInts(class_InnerClasses_RC), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_RC["
+				+ class_InnerClasses_RC.length + "]");
+
+		encodedBand = encodeBandInt("class_InnerClasses_F", class_InnerClasses_F, Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_F["
+				+ class_InnerClasses_F.length + "]");
+
+		encodedBand = encodeBandInt("class_InnerClasses_outer_RCN", cpEntryOrNullListToArray(classInnerClassesOuterRCN),
+				Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_outer_RCN["
+				+ classInnerClassesOuterRCN.size() + "]");
+
+		encodedBand = encodeBandInt("class_InnerClasses_name_RUN", cpEntryOrNullListToArray(classInnerClassesNameRUN),
+				Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from class_InnerClasses_name_RUN["
+				+ classInnerClassesNameRUN.size() + "]");
+
+		encodedBand = encodeBandInt("classFileVersionMinor", classFileVersionMinor.toArray(), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from classFileVersionMinor["
+				+ classFileVersionMinor.size() + "]");
+
+		encodedBand = encodeBandInt("classFileVersionMajor", classFileVersionMajor.toArray(), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from classFileVersionMajor["
+				+ classFileVersionMajor.size() + "]");
+
+		for (NewAttributeBands classAttributeBand : classAttributeBands) {
+			classAttributeBand.pack(out);
+		}
+	}
+
+	private int[] getInts(final CPClass[] cpClasses) {
+		final int[] ints = new int[cpClasses.length];
+		for (int i = 0; i < ints.length; i++) {
+			if (cpClasses[i] != null) {
+				ints[i] = cpClasses[i].getIndex();
+			}
+		}
+		return ints;
+	}
+
+	private void writeCodeBands(final OutputStream out) throws IOException, Pack200Exception {
+		byte[] encodedBand = encodeBandInt("codeHeaders", codeHeaders, Codec.BYTE1);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeHeaders[" + codeHeaders.length + "]");
+
+		encodedBand = encodeBandInt("codeMaxStack", codeMaxStack.toArray(), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeMaxStack[" + codeMaxStack.size() + "]");
+
+		encodedBand = encodeBandInt("codeMaxLocals", codeMaxLocals.toArray(), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeMaxLocals[" + codeMaxLocals.size() + "]");
+
+		encodedBand = encodeBandInt("codeHandlerCount", codeHandlerCount.toArray(), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils
+				.log("Wrote " + encodedBand.length + " bytes from codeHandlerCount[" + codeHandlerCount.size() + "]");
+
+		encodedBand = encodeBandInt("codeHandlerStartP", integerListToArray(codeHandlerStartP), Codec.BCI5);
+		out.write(encodedBand);
+		PackingUtils
+				.log("Wrote " + encodedBand.length + " bytes from codeHandlerStartP[" + codeHandlerStartP.size() + "]");
+
+		encodedBand = encodeBandInt("codeHandlerEndPO", integerListToArray(codeHandlerEndPO), Codec.BRANCH5);
+		out.write(encodedBand);
+		PackingUtils
+				.log("Wrote " + encodedBand.length + " bytes from codeHandlerEndPO[" + codeHandlerEndPO.size() + "]");
+
+		encodedBand = encodeBandInt("codeHandlerCatchPO", integerListToArray(codeHandlerCatchPO), Codec.BRANCH5);
+		out.write(encodedBand);
+		PackingUtils.log(
+				"Wrote " + encodedBand.length + " bytes from codeHandlerCatchPO[" + codeHandlerCatchPO.size() + "]");
+
+		encodedBand = encodeBandInt("codeHandlerClass", cpEntryOrNullListToArray(codeHandlerClass), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils
+				.log("Wrote " + encodedBand.length + " bytes from codeHandlerClass[" + codeHandlerClass.size() + "]");
+
+		writeCodeAttributeBands(out);
+	}
+
+	private void writeCodeAttributeBands(final OutputStream out) throws IOException, Pack200Exception {
+		byte[] encodedBand = encodeFlags("codeFlags", longListToArray(codeFlags), Codec.UNSIGNED5, Codec.UNSIGNED5,
+				segmentHeader.have_code_flags_hi());
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from codeFlags[" + codeFlags.size() + "]");
+
+		// *code_attr_count :UNSIGNED5 [COUNT(1<<16,...)]
+		// *code_attr_indexes :UNSIGNED5 [SUM(*code_attr_count)]
+		encodedBand = encodeBandInt("code_attr_calls", code_attr_calls, Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_attr_calls[" + code_attr_calls.length + "]");
+
+		encodedBand = encodeBandInt("code_LineNumberTable_N", codeLineNumberTableN.toArray(), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LineNumberTable_N["
+				+ codeLineNumberTableN.size() + "]");
+
+		encodedBand = encodeBandInt("code_LineNumberTable_bci_P", integerListToArray(codeLineNumberTableBciP),
+				Codec.BCI5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LineNumberTable_bci_P["
+				+ codeLineNumberTableBciP.size() + "]");
+
+		encodedBand = encodeBandInt("code_LineNumberTable_line", codeLineNumberTableLine.toArray(), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LineNumberTable_line["
+				+ codeLineNumberTableLine.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTable_N", codeLocalVariableTableN.toArray(), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_N["
+				+ codeLocalVariableTableN.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTable_bci_P", integerListToArray(codeLocalVariableTableBciP),
+				Codec.BCI5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_bci_P["
+				+ codeLocalVariableTableBciP.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTable_span_O", integerListToArray(codeLocalVariableTableSpanO),
+				Codec.BRANCH5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_span_O["
+				+ codeLocalVariableTableSpanO.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTable_name_RU", cpEntryListToArray(codeLocalVariableTableNameRU),
+				Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_name_RU["
+				+ codeLocalVariableTableNameRU.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTable_type_RS", cpEntryListToArray(codeLocalVariableTableTypeRS),
+				Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_type_RS["
+				+ codeLocalVariableTableTypeRS.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTable_slot", codeLocalVariableTableSlot.toArray(),
+				Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTable_slot["
+				+ codeLocalVariableTableSlot.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTypeTable_N", codeLocalVariableTypeTableN.toArray(),
+				Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_N["
+				+ codeLocalVariableTypeTableN.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTypeTable_bci_P",
+				integerListToArray(codeLocalVariableTypeTableBciP), Codec.BCI5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_bci_P["
+				+ codeLocalVariableTypeTableBciP.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTypeTable_span_O",
+				integerListToArray(codeLocalVariableTypeTableSpanO), Codec.BRANCH5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_span_O["
+				+ codeLocalVariableTypeTableSpanO.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTypeTable_name_RU",
+				cpEntryListToArray(codeLocalVariableTypeTableNameRU), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_name_RU["
+				+ codeLocalVariableTypeTableNameRU.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTypeTable_type_RS",
+				cpEntryListToArray(codeLocalVariableTypeTableTypeRS), Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_type_RS["
+				+ codeLocalVariableTypeTableTypeRS.size() + "]");
+
+		encodedBand = encodeBandInt("code_LocalVariableTypeTable_slot", codeLocalVariableTypeTableSlot.toArray(),
+				Codec.UNSIGNED5);
+		out.write(encodedBand);
+		PackingUtils.log("Wrote " + encodedBand.length + " bytes from code_LocalVariableTypeTable_slot["
+				+ codeLocalVariableTypeTableSlot.size() + "]");
+
+		for (NewAttributeBands bands : codeAttributeBands) {
+			bands.pack(out);
+		}
+	}
+
+	public void addMethod(int flags, final String name, final String desc, final String signature,
+			final String[] exceptions) {
+		final CPNameAndType nt = cpBands.getCPNameAndType(name, desc);
+		tempMethodDesc.add(nt);
+		if (signature != null) {
+			methodSignature.add(cpBands.getCPSignature(signature));
+			flags |= (1 << 19);
+		}
+		if (exceptions != null) {
+			methodExceptionNumber.add(exceptions.length);
+			for (String exception : exceptions) {
+				methodExceptionClasses.add(cpBands.getCPClass(exception));
+			}
+			flags |= (1 << 18);
+		}
+		if ((flags & Opcodes.ACC_DEPRECATED) != 0) { // ASM uses (1<<17) flag for deprecated
+			flags = flags & ~Opcodes.ACC_DEPRECATED;
+			flags = flags | (1 << 20);
+		}
+		tempMethodFlags.add(Long.valueOf(flags));
+		numMethodArgs = countArgs(desc);
+		if (!anySyntheticMethods && ((flags & (1 << 12)) != 0)
+				&& segment.getCurrentClassReader().hasSyntheticAttributes()) {
+			cpBands.addCPUtf8("Synthetic");
+			anySyntheticMethods = true;
+		}
+	}
+
+	public void endOfMethod() {
+		if (tempMethodRVPA != null) {
+			method_RVPA_bands.addParameterAnnotation(tempMethodRVPA.numParams, tempMethodRVPA.annoN,
+					tempMethodRVPA.pairN, tempMethodRVPA.typeRS, tempMethodRVPA.nameRU, tempMethodRVPA.tags,
+					tempMethodRVPA.values, tempMethodRVPA.caseArrayN, tempMethodRVPA.nestTypeRS,
+					tempMethodRVPA.nestNameRU, tempMethodRVPA.nestPairN);
+			tempMethodRVPA = null;
+		}
+		if (tempMethodRIPA != null) {
+			method_RIPA_bands.addParameterAnnotation(tempMethodRIPA.numParams, tempMethodRIPA.annoN,
+					tempMethodRIPA.pairN, tempMethodRIPA.typeRS, tempMethodRIPA.nameRU, tempMethodRIPA.tags,
+					tempMethodRIPA.values, tempMethodRIPA.caseArrayN, tempMethodRIPA.nestTypeRS,
+					tempMethodRIPA.nestNameRU, tempMethodRIPA.nestPairN);
+			tempMethodRIPA = null;
+		}
+		if (codeFlags.size() > 0) {
+			final long latestCodeFlag = codeFlags.get(codeFlags.size() - 1).longValue();
+			final int latestLocalVariableTableN = codeLocalVariableTableN.get(codeLocalVariableTableN.size() - 1);
+			if (latestCodeFlag == (1 << 2) && latestLocalVariableTableN == 0) {
+				codeLocalVariableTableN.remove(codeLocalVariableTableN.size() - 1);
+				codeFlags.remove(codeFlags.size() - 1);
+				codeFlags.add(Long.valueOf(0));
+			}
+		}
+	}
+
+	protected static int countArgs(final String descriptor) {
+		final int bra = descriptor.indexOf('(');
+		final int ket = descriptor.indexOf(')');
+		if (bra == -1 || ket == -1 || ket < bra) {
+			throw new IllegalArgumentException("No arguments");
+		}
+
+		boolean inType = false;
+		boolean consumingNextType = false;
+		int count = 0;
+		for (int i = bra + 1; i < ket; i++) {
+			final char charAt = descriptor.charAt(i);
+			if (inType && charAt == ';') {
+				inType = false;
+				consumingNextType = false;
+			} else if (!inType && charAt == 'L') {
+				inType = true;
+				count++;
+			} else if (charAt == '[') {
+				consumingNextType = true;
+			} else if (inType) {
+				// NOP
+			} else if (consumingNextType) {
+				count++;
+				consumingNextType = false;
+			} else if (charAt == 'D' || charAt == 'J') {
+				count += 2;
+			} else {
+				count++;
+			}
+		}
+		return count;
+	}
+
+	public void endOfClass() { // All the data for the current class has been
+								// read
+		final int numFields = tempFieldDesc.size();
+		class_field_count[index] = numFields;
+		field_descr[index] = new CPNameAndType[numFields];
+		field_flags[index] = new long[numFields];
+		for (int i = 0; i < numFields; i++) {
+			field_descr[index][i] = tempFieldDesc.get(i);
+			field_flags[index][i] = tempFieldFlags.get(i).longValue();
+		}
+		final int numMethods = tempMethodDesc.size();
+		class_method_count[index] = numMethods;
+		method_descr[index] = new CPNameAndType[numMethods];
+		method_flags[index] = new long[numMethods];
+		for (int i = 0; i < numMethods; i++) {
+			method_descr[index][i] = tempMethodDesc.get(i);
+			method_flags[index][i] = tempMethodFlags.get(i).longValue();
+		}
+		tempFieldDesc.clear();
+		tempFieldFlags.clear();
+		tempMethodDesc.clear();
+		tempMethodFlags.clear();
+		index++;
+	}
+
+	public void addSourceFile(final String source) {
+		String implicitSourceFileName = class_this[index].toString();
+		if (implicitSourceFileName.indexOf('$') != -1) {
+			implicitSourceFileName = implicitSourceFileName.substring(0, implicitSourceFileName.indexOf('$'));
+		}
+		implicitSourceFileName = implicitSourceFileName.substring(implicitSourceFileName.lastIndexOf('/') + 1)
+				+ ".java";
+		if (source.equals(implicitSourceFileName)) {
+			classSourceFile.add(null);
+		} else {
+			classSourceFile.add(cpBands.getCPUtf8(source));
+		}
+		class_flags[index] |= (1 << 17);
+	}
+
+	public void addEnclosingMethod(final String owner, final String name, final String desc) {
+		class_flags[index] |= (1 << 18);
+		classEnclosingMethodClass.add(cpBands.getCPClass(owner));
+		classEnclosingMethodDesc.add(name == null ? null : cpBands.getCPNameAndType(name, desc));
+	}
+
+	public void addClassAttribute(final NewAttribute attribute) {
+		// TODO: backwards calls
+		final String attributeName = attribute.type;
+		for (NewAttributeBands bands : classAttributeBands) {
+			if (bands.getAttributeName().equals(attributeName)) {
+				bands.addAttribute(attribute);
+				final int flagIndex = bands.getFlagIndex();
+				class_flags[index] |= (1 << flagIndex);
+				return;
+			}
+		}
+		throw new IllegalArgumentException("No suitable definition for " + attributeName);
+	}
+
+	public void addFieldAttribute(final NewAttribute attribute) {
+		final String attributeName = attribute.type;
+		for (NewAttributeBands bands : fieldAttributeBands) {
+			if (bands.getAttributeName().equals(attributeName)) {
+				bands.addAttribute(attribute);
+				final int flagIndex = bands.getFlagIndex();
+				final Long flags = tempFieldFlags.remove(tempFieldFlags.size() - 1);
+				tempFieldFlags.add(Long.valueOf(flags.longValue() | (1 << flagIndex)));
+				return;
+			}
+		}
+		throw new IllegalArgumentException("No suitable definition for " + attributeName);
+	}
+
+	public void addMethodAttribute(final NewAttribute attribute) {
+		final String attributeName = attribute.type;
+		for (NewAttributeBands bands : methodAttributeBands) {
+			if (bands.getAttributeName().equals(attributeName)) {
+				bands.addAttribute(attribute);
+				final int flagIndex = bands.getFlagIndex();
+				final Long flags = tempMethodFlags.remove(tempMethodFlags.size() - 1);
+				tempMethodFlags.add(Long.valueOf(flags.longValue() | (1 << flagIndex)));
+				return;
+			}
+		}
+		throw new IllegalArgumentException("No suitable definition for " + attributeName);
+	}
+
+	public void addCodeAttribute(final NewAttribute attribute) {
+		final String attributeName = attribute.type;
+		for (NewAttributeBands bands : codeAttributeBands) {
+			if (bands.getAttributeName().equals(attributeName)) {
+				bands.addAttribute(attribute);
+				final int flagIndex = bands.getFlagIndex();
+				final Long flags = codeFlags.remove(codeFlags.size() - 1);
+				codeFlags.add(Long.valueOf(flags.longValue() | (1 << flagIndex)));
+				return;
+			}
+		}
+		throw new IllegalArgumentException("No suitable definition for " + attributeName);
+	}
+
+	public void addMaxStack(final int maxStack, int maxLocals) {
+		final Long latestFlag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
+		final Long newFlag = Long.valueOf(latestFlag.intValue() | (1 << 17));
+		tempMethodFlags.add(newFlag);
+		codeMaxStack.add(maxStack);
+		if ((newFlag.longValue() & (1 << 3)) == 0) { // not static
+			maxLocals--; // minus 'this' local
+		}
+		maxLocals -= numMethodArgs;
+		codeMaxLocals.add(maxLocals);
+	}
+
+	public void addCode() {
+		codeHandlerCount.add(0);
+		if (!stripDebug) {
+			codeFlags.add(Long.valueOf(1 << 2));
+			codeLocalVariableTableN.add(0);
+		}
+	}
+
+	public void addHandler(final Label start, final Label end, final Label handler, final String type) {
+		final int handlers = codeHandlerCount.remove(codeHandlerCount.size() - 1);
+		codeHandlerCount.add(handlers + 1);
+		codeHandlerStartP.add(start);
+		codeHandlerEndPO.add(end);
+		codeHandlerCatchPO.add(handler);
+		codeHandlerClass.add(type == null ? null : cpBands.getCPClass(type));
+	}
+
+	public void addLineNumber(final int line, final Label start) {
+		final Long latestCodeFlag = codeFlags.get(codeFlags.size() - 1);
+		if ((latestCodeFlag.intValue() & (1 << 1)) == 0) {
+			codeFlags.remove(codeFlags.size() - 1);
+			codeFlags.add(Long.valueOf(latestCodeFlag.intValue() | (1 << 1)));
+			codeLineNumberTableN.add(1);
+		} else {
+			codeLineNumberTableN.increment(codeLineNumberTableN.size() - 1);
+		}
+		codeLineNumberTableLine.add(line);
+		codeLineNumberTableBciP.add(start);
+	}
+
+	public void addLocalVariable(final String name, final String desc, final String signature, final Label start,
+			final Label end, final int indx) {
+		if (signature != null) { // LocalVariableTypeTable attribute
+			final Long latestCodeFlag = codeFlags.get(codeFlags.size() - 1);
+			if ((latestCodeFlag.intValue() & (1 << 3)) == 0) {
+				codeFlags.remove(codeFlags.size() - 1);
+				codeFlags.add(Long.valueOf(latestCodeFlag.intValue() | (1 << 3)));
+				codeLocalVariableTypeTableN.add(1);
+			} else {
+				codeLocalVariableTypeTableN.increment(codeLocalVariableTypeTableN.size() - 1);
+			}
+			codeLocalVariableTypeTableBciP.add(start);
+			codeLocalVariableTypeTableSpanO.add(end);
+			codeLocalVariableTypeTableNameRU.add(cpBands.getCPUtf8(name));
+			codeLocalVariableTypeTableTypeRS.add(cpBands.getCPSignature(signature));
+			codeLocalVariableTypeTableSlot.add(indx);
+		}
+		// LocalVariableTable attribute
+		codeLocalVariableTableN.increment(codeLocalVariableTableN.size() - 1);
+		codeLocalVariableTableBciP.add(start);
+		codeLocalVariableTableSpanO.add(end);
+		codeLocalVariableTableNameRU.add(cpBands.getCPUtf8(name));
+		codeLocalVariableTableTypeRS.add(cpBands.getCPSignature(desc));
+		codeLocalVariableTableSlot.add(indx);
+	}
+
+	public void doBciRenumbering(final IntList bciRenumbering, final Map<Label, Integer> labelsToOffsets) {
+		renumberBci(codeLineNumberTableBciP, bciRenumbering, labelsToOffsets);
+		renumberBci(codeLocalVariableTableBciP, bciRenumbering, labelsToOffsets);
+		renumberOffsetBci(codeLocalVariableTableBciP, codeLocalVariableTableSpanO, bciRenumbering, labelsToOffsets);
+		renumberBci(codeLocalVariableTypeTableBciP, bciRenumbering, labelsToOffsets);
+		renumberOffsetBci(codeLocalVariableTypeTableBciP, codeLocalVariableTypeTableSpanO, bciRenumbering,
+				labelsToOffsets);
+		renumberBci(codeHandlerStartP, bciRenumbering, labelsToOffsets);
+		renumberOffsetBci(codeHandlerStartP, codeHandlerEndPO, bciRenumbering, labelsToOffsets);
+		renumberDoubleOffsetBci(codeHandlerStartP, codeHandlerEndPO, codeHandlerCatchPO, bciRenumbering,
+				labelsToOffsets);
+
+		for (NewAttributeBands newAttributeBandSet : classAttributeBands) {
+			newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
+		}
+		for (NewAttributeBands newAttributeBandSet : methodAttributeBands) {
+			newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
+		}
+		for (NewAttributeBands newAttributeBandSet : fieldAttributeBands) {
+			newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
+		}
+		for (NewAttributeBands newAttributeBandSet : codeAttributeBands) {
+			newAttributeBandSet.renumberBci(bciRenumbering, labelsToOffsets);
+		}
+	}
+
+	private void renumberBci(final List<Integer> list, final IntList bciRenumbering,
+			final Map<Label, Integer> labelsToOffsets) {
+		for (int i = list.size() - 1; i >= 0; i--) {
+			final Object label = list.get(i);
+			if (label instanceof Integer) {
+				break;
+			}
+			if (label instanceof Label) {
+				list.remove(i);
+				final Integer bytecodeIndex = labelsToOffsets.get(label);
+				list.add(i, Integer.valueOf(bciRenumbering.get(bytecodeIndex.intValue())));
+			}
+		}
+	}
+
+	private void renumberOffsetBci(final List<Integer> relative, final List<Integer> list, final IntList bciRenumbering,
+			final Map<Label, Integer> labelsToOffsets) {
+		for (int i = list.size() - 1; i >= 0; i--) {
+			final Object label = list.get(i);
+			if (label instanceof Integer) {
+				break;
+			}
+			if (label instanceof Label) {
+				list.remove(i);
+				final Integer bytecodeIndex = labelsToOffsets.get(label);
+				final Integer renumberedOffset = Integer
+						.valueOf(bciRenumbering.get(bytecodeIndex.intValue()) - relative.get(i).intValue());
+				list.add(i, renumberedOffset);
+			}
+		}
+	}
+
+	private void renumberDoubleOffsetBci(final List<Integer> relative, final List<Integer> firstOffset, final List<Object> list,
+			final IntList bciRenumbering, final Map<Label, Integer> labelsToOffsets) {
+		// TODO: There's probably a nicer way of doing this...
+		for (int i = list.size() - 1; i >= 0; i--) {
+			final Object label = list.get(i);
+			if (label instanceof Integer) {
+				break;
+			}
+			if (label instanceof Label) {
+				list.remove(i);
+				final Integer bytecodeIndex = labelsToOffsets.get(label);
+				final Integer renumberedOffset = Integer.valueOf(bciRenumbering.get(bytecodeIndex.intValue())
+						- relative.get(i).intValue() - firstOffset.get(i).intValue());
+				list.add(i, renumberedOffset);
+			}
+		}
+	}
+
+	public boolean isAnySyntheticClasses() {
+		return anySyntheticClasses;
+	}
+
+	public boolean isAnySyntheticFields() {
+		return anySyntheticFields;
+	}
+
+	public boolean isAnySyntheticMethods() {
+		return anySyntheticMethods;
+	}
+
+	public void addParameterAnnotation(final int parameter, final String desc, final boolean visible,
+			final List<String> nameRU, final List<String> tags, final List<Object> values,
+			final List<Integer> caseArrayN, final List<String> nestTypeRS, final List<String> nestNameRU,
+			final List<Integer> nestPairN) {
+		if (visible) {
+			if (tempMethodRVPA == null) {
+				tempMethodRVPA = new TempParamAnnotation(numMethodArgs);
+				tempMethodRVPA.addParameterAnnotation(parameter, desc, nameRU, tags, values, caseArrayN, nestTypeRS,
+						nestNameRU, nestPairN);
+			}
+			final Long flag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
+			tempMethodFlags.add(Long.valueOf(flag.longValue() | (1 << 23)));
+		} else {
+			if (tempMethodRIPA == null) {
+				tempMethodRIPA = new TempParamAnnotation(numMethodArgs);
+				tempMethodRIPA.addParameterAnnotation(parameter, desc, nameRU, tags, values, caseArrayN, nestTypeRS,
+						nestNameRU, nestPairN);
+			}
+			final Long flag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
+			tempMethodFlags.add(Long.valueOf(flag.longValue() | (1 << 24)));
+		}
+	}
+
+	private static class TempParamAnnotation {
+
+		int numParams;
+		int[] annoN;
+		IntList pairN = new IntList();
+		List<String> typeRS = new ArrayList<>();
+		List<String> nameRU = new ArrayList<>();
+		List<String> tags = new ArrayList<>();
+		List<Object> values = new ArrayList<>();
+		List<Integer> caseArrayN = new ArrayList<>();
+		List<String> nestTypeRS = new ArrayList<>();
+		List<String> nestNameRU = new ArrayList<>();
+		List<Integer> nestPairN = new ArrayList<>();
+
+		public TempParamAnnotation(final int numParams) {
+			this.numParams = numParams;
+			annoN = new int[numParams];
+		}
+
+		public void addParameterAnnotation(final int parameter, final String desc, final List<String> nameRU,
+				final List<String> tags, final List<Object> values, final List<Integer> caseArrayN,
+				final List<String> nestTypeRS, final List<String> nestNameRU, final List<Integer> nestPairN) {
+			annoN[parameter]++;
+			typeRS.add(desc);
+			pairN.add(nameRU.size());
+			this.nameRU.addAll(nameRU);
+			this.tags.addAll(tags);
+			this.values.addAll(values);
+			this.caseArrayN.addAll(caseArrayN);
+			this.nestTypeRS.addAll(nestTypeRS);
+			this.nestNameRU.addAll(nestNameRU);
+			this.nestPairN.addAll(nestPairN);
+		}
+	}
+
+	public void addAnnotation(final int context, final String desc, final boolean visible, final List<String> nameRU,
+			final List<String> tags, final List<Object> values, final List<Integer> caseArrayN, final List<String> nestTypeRS,
+			final List<String> nestNameRU, final List<Integer> nestPairN) {
+		switch (context) {
+		case MetadataBandGroup.CONTEXT_CLASS:
+			if (visible) {
+				class_RVA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU,
+						nestPairN);
+				if ((class_flags[index] & (1 << 21)) != 0) {
+					class_RVA_bands.incrementAnnoN();
+				} else {
+					class_RVA_bands.newEntryInAnnoN();
+					class_flags[index] = class_flags[index] | (1 << 21);
+				}
+			} else {
+				class_RIA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU,
+						nestPairN);
+				if ((class_flags[index] & (1 << 22)) != 0) {
+					class_RIA_bands.incrementAnnoN();
+				} else {
+					class_RIA_bands.newEntryInAnnoN();
+					class_flags[index] = class_flags[index] | (1 << 22);
+				}
+			}
+			break;
+		case MetadataBandGroup.CONTEXT_FIELD:
+			if (visible) {
+				field_RVA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU,
+						nestPairN);
+				final Long flag = tempFieldFlags.remove(tempFieldFlags.size() - 1);
+				if ((flag.intValue() & (1 << 21)) != 0) {
+					field_RVA_bands.incrementAnnoN();
+				} else {
+					field_RVA_bands.newEntryInAnnoN();
+				}
+				tempFieldFlags.add(Long.valueOf(flag.intValue() | (1 << 21)));
+			} else {
+				field_RIA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU,
+						nestPairN);
+				final Long flag = tempFieldFlags.remove(tempFieldFlags.size() - 1);
+				if ((flag.intValue() & (1 << 22)) != 0) {
+					field_RIA_bands.incrementAnnoN();
+				} else {
+					field_RIA_bands.newEntryInAnnoN();
+				}
+				tempFieldFlags.add(Long.valueOf(flag.intValue() | (1 << 22)));
+			}
+			break;
+		case MetadataBandGroup.CONTEXT_METHOD:
+			if (visible) {
+				method_RVA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU,
+						nestPairN);
+				final Long flag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
+				if ((flag.intValue() & (1 << 21)) != 0) {
+					method_RVA_bands.incrementAnnoN();
+				} else {
+					method_RVA_bands.newEntryInAnnoN();
+				}
+				tempMethodFlags.add(Long.valueOf(flag.intValue() | (1 << 21)));
+			} else {
+				method_RIA_bands.addAnnotation(desc, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU,
+						nestPairN);
+				final Long flag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
+				if ((flag.intValue() & (1 << 22)) != 0) {
+					method_RIA_bands.incrementAnnoN();
+				} else {
+					method_RIA_bands.newEntryInAnnoN();
+				}
+				tempMethodFlags.add(Long.valueOf(flag.intValue() | (1 << 22)));
+			}
+			break;
+		}
+	}
+
+	public void addAnnotationDefault(final List<String> nameRU, final List<String> tags, final List<Object> values,
+			final List<Integer> caseArrayN, final List<String> nestTypeRS, final List<String> nestNameRU,
+			final List<Integer> nestPairN) {
+		method_AD_bands.addAnnotation(null, nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU, nestPairN);
+		final Long flag = tempMethodFlags.remove(tempMethodFlags.size() - 1);
+		tempMethodFlags.add(Long.valueOf(flag.longValue() | (1 << 25)));
+	}
+
+	/**
+	 * Remove all entries for the current class
+	 */
+	public void removeCurrentClass() {
+		// Note - this doesn't remove any entries added to the constant pool but
+		// that shouldn't be a problem
+		if ((class_flags[index] & (1 << 17)) != 0) {
+			classSourceFile.remove(classSourceFile.size() - 1);
+		}
+		if ((class_flags[index] & (1 << 18)) != 0) {
+			classEnclosingMethodClass.remove(classEnclosingMethodClass.size() - 1);
+			classEnclosingMethodDesc.remove(classEnclosingMethodDesc.size() - 1);
+		}
+		if ((class_flags[index] & (1 << 19)) != 0) {
+			classSignature.remove(classSignature.size() - 1);
+		}
+		if ((class_flags[index] & (1 << 21)) != 0) {
+			class_RVA_bands.removeLatest();
+		}
+		if ((class_flags[index] & (1 << 22)) != 0) {
+			class_RIA_bands.removeLatest();
+		}
+		for (Long flagsL : tempFieldFlags) {
+			final long flags = flagsL.longValue();
+			if ((flags & (1 << 19)) != 0) {
+				fieldSignature.remove(fieldSignature.size() - 1);
+			}
+			if ((flags & (1 << 17)) != 0) {
+				fieldConstantValueKQ.remove(fieldConstantValueKQ.size() - 1);
+			}
+			if ((flags & (1 << 21)) != 0) {
+				field_RVA_bands.removeLatest();
+			}
+			if ((flags & (1 << 22)) != 0) {
+				field_RIA_bands.removeLatest();
+			}
+		}
+		for (Long flagsL : tempMethodFlags) {
+			final long flags = flagsL.longValue();
+			if ((flags & (1 << 19)) != 0) {
+				methodSignature.remove(methodSignature.size() - 1);
+			}
+			if ((flags & (1 << 18)) != 0) {
+				final int exceptions = methodExceptionNumber.remove(methodExceptionNumber.size() - 1);
+				for (int i = 0; i < exceptions; i++) {
+					methodExceptionClasses.remove(methodExceptionClasses.size() - 1);
+				}
+			}
+			if ((flags & (1 << 17)) != 0) { // has code attribute
+				codeMaxLocals.remove(codeMaxLocals.size() - 1);
+				codeMaxStack.remove(codeMaxStack.size() - 1);
+				final int handlers = codeHandlerCount.remove(codeHandlerCount.size() - 1);
+				for (int i = 0; i < handlers; i++) {
+					final int index = codeHandlerStartP.size() - 1;
+					codeHandlerStartP.remove(index);
+					codeHandlerEndPO.remove(index);
+					codeHandlerCatchPO.remove(index);
+					codeHandlerClass.remove(index);
+				}
+				if (!stripDebug) {
+					final long cdeFlags = codeFlags.remove(codeFlags.size() - 1).longValue();
+					final int numLocalVariables = codeLocalVariableTableN.remove(codeLocalVariableTableN.size() - 1);
+					for (int i = 0; i < numLocalVariables; i++) {
+						final int location = codeLocalVariableTableBciP.size() - 1;
+						codeLocalVariableTableBciP.remove(location);
+						codeLocalVariableTableSpanO.remove(location);
+						codeLocalVariableTableNameRU.remove(location);
+						codeLocalVariableTableTypeRS.remove(location);
+						codeLocalVariableTableSlot.remove(location);
+					}
+					if ((cdeFlags & (1 << 3)) != 0) {
+						final int numLocalVariablesInTypeTable = codeLocalVariableTypeTableN
+								.remove(codeLocalVariableTypeTableN.size() - 1);
+						for (int i = 0; i < numLocalVariablesInTypeTable; i++) {
+							final int location = codeLocalVariableTypeTableBciP.size() - 1;
+							codeLocalVariableTypeTableBciP.remove(location);
+							codeLocalVariableTypeTableSpanO.remove(location);
+							codeLocalVariableTypeTableNameRU.remove(location);
+							codeLocalVariableTypeTableTypeRS.remove(location);
+							codeLocalVariableTypeTableSlot.remove(location);
+						}
+					}
+					if ((cdeFlags & (1 << 1)) != 0) {
+						final int numLineNumbers = codeLineNumberTableN.remove(codeLineNumberTableN.size() - 1);
+						for (int i = 0; i < numLineNumbers; i++) {
+							final int location = codeLineNumberTableBciP.size() - 1;
+							codeLineNumberTableBciP.remove(location);
+							codeLineNumberTableLine.remove(location);
+						}
+					}
+				}
+			}
+			if ((flags & (1 << 21)) != 0) {
+				method_RVA_bands.removeLatest();
+			}
+			if ((flags & (1 << 22)) != 0) {
+				method_RIA_bands.removeLatest();
+			}
+			if ((flags & (1 << 23)) != 0) {
+				method_RVPA_bands.removeLatest();
+			}
+			if ((flags & (1 << 24)) != 0) {
+				method_RIPA_bands.removeLatest();
+			}
+			if ((flags & (1 << 25)) != 0) {
+				method_AD_bands.removeLatest();
+			}
+		}
+		class_this[index] = null;
+		class_super[index] = null;
+		class_interface_count[index] = 0;
+		class_interface[index] = null;
+		major_versions[index] = 0;
+		class_flags[index] = 0;
+		tempFieldDesc.clear();
+		tempFieldFlags.clear();
+		tempMethodDesc.clear();
+		tempMethodFlags.clear();
+		if (index > 0) {
+			index--;
+		}
+	}
+
+	public int numClassesProcessed() {
+		return index;
+	}
 }
diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/CpBands.java b/src/main/java/org/apache/commons/compress/harmony/pack200/CpBands.java
index d75a7db3..7804b297 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/CpBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/CpBands.java
@@ -58,7 +58,7 @@ public class CpBands extends BandSet {
     private final Map<String, CPMethodOrField> stringsToCpField = new HashMap<>();
     private final Map<String, CPMethodOrField> stringsToCpIMethod = new HashMap<>();
 
-    private final Map<Object, CPConstant> objectsToCPConstant = new HashMap<>();
+    private final Map<Object, CPConstant<?>> objectsToCPConstant = new HashMap<>();
 
     private final Segment segment;
 
@@ -546,8 +546,8 @@ public class CpBands extends BandSet {
         return cpF;
     }
 
-    public CPConstant getConstant(final Object value) {
-        CPConstant constant = objectsToCPConstant.get(value);
+    public CPConstant<?> getConstant(final Object value) {
+        CPConstant<?> constant = objectsToCPConstant.get(value);
         if (constant == null) {
             if (value instanceof Integer) {
                 constant = new CPInt(((Integer) value).intValue());
diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/FileBands.java b/src/main/java/org/apache/commons/compress/harmony/pack200/FileBands.java
index 28cd6a30..1ff665a5 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/FileBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/FileBands.java
@@ -60,8 +60,7 @@ public class FileBands extends BandSet {
         final int archiveModtime = segmentHeader.getArchive_modtime();
 
         final Set<String> classNames = new HashSet<>();
-        for (Object element : segmentUnit.getClassList()) {
-            final ClassReader reader = (ClassReader) element;
+        for (ClassReader reader : segmentUnit.getClassList()) {
             classNames.add(reader.getClassName());
         }
         final CPUTF8 emptyString = cpBands.getCPUtf8("");
diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/IcBands.java b/src/main/java/org/apache/commons/compress/harmony/pack200/IcBands.java
index a29bd800..20f35266 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/IcBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/IcBands.java
@@ -124,9 +124,8 @@ public class IcBands extends BandSet {
             outerToInner.put(outerName, tuples);
             tuples.add(icTuple);
         } else {
-            for (Object tuple : tuples) {
-                final IcTuple icT = (IcTuple) tuple;
-                if (icTuple.equals(icT)) {
+            for (IcTuple tuple : tuples) {
+                if (icTuple.equals(tuple)) {
                     return;
                 }
             }
@@ -139,7 +138,7 @@ public class IcBands extends BandSet {
         return name.equals(outerName + '$' + innerName) && innerName.indexOf('$') == -1;
     }
 
-    class IcTuple implements Comparable {
+    class IcTuple implements Comparable<IcTuple> {
 
         protected CPClass C; // this class
         protected int F; // flags
@@ -169,8 +168,8 @@ public class IcBands extends BandSet {
         }
 
         @Override
-        public int compareTo(final Object arg0) {
-            return C.compareTo(((IcTuple) arg0).C);
+        public int compareTo(final IcTuple arg0) {
+            return C.compareTo(arg0.C);
         }
 
         public boolean isAnonymous() {
@@ -182,8 +181,7 @@ public class IcBands extends BandSet {
     }
 
     public IcTuple getIcTuple(final CPClass inner) {
-        for (Object element : innerClasses) {
-            final IcTuple icTuple = (IcTuple) element;
+        for (IcTuple icTuple : innerClasses) {
             if (icTuple.C.equals(inner)) {
                 return icTuple;
             }
diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/MetadataBandGroup.java b/src/main/java/org/apache/commons/compress/harmony/pack200/MetadataBandGroup.java
index a28c3c59..38e7056d 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/MetadataBandGroup.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/MetadataBandGroup.java
@@ -36,22 +36,22 @@ public class MetadataBandGroup extends BandSet {
 
     public IntList param_NB = new IntList(); // TODO: Lazy instantiation?
     public IntList anno_N = new IntList();
-    public List type_RS = new ArrayList();
+    public List<CPSignature> type_RS = new ArrayList<>();
     public IntList pair_N = new IntList();
-    public List name_RU = new ArrayList();
-    public List T = new ArrayList();
-    public List caseI_KI = new ArrayList();
-    public List caseD_KD = new ArrayList();
-    public List caseF_KF = new ArrayList();
-    public List caseJ_KJ = new ArrayList();
-    public List casec_RS = new ArrayList();
-    public List caseet_RS = new ArrayList();
-    public List caseec_RU = new ArrayList();
-    public List cases_RU = new ArrayList();
+    public List<CPUTF8> name_RU = new ArrayList<>();
+    public List<String> T = new ArrayList<>();
+    public List<CPConstant<?>> caseI_KI = new ArrayList<>();
+    public List<CPConstant<?>> caseD_KD = new ArrayList<>();
+    public List<CPConstant<?>> caseF_KF = new ArrayList<>();
+    public List<CPConstant<?>> caseJ_KJ = new ArrayList<>();
+    public List<CPSignature> casec_RS = new ArrayList<>();
+    public List<CPSignature> caseet_RS = new ArrayList<>();
+    public List<CPUTF8> caseec_RU = new ArrayList<>();
+    public List<CPUTF8> cases_RU = new ArrayList<>();
     public IntList casearray_N = new IntList();
-    public List nesttype_RS = new ArrayList();
+    public List<CPSignature> nesttype_RS = new ArrayList<>();
     public IntList nestpair_N = new IntList();
-    public List nestname_RU = new ArrayList();
+    public List<CPUTF8> nestname_RU = new ArrayList<>();
 
     private final CpBands cpBands;
     private final int context;
@@ -199,10 +199,10 @@ public class MetadataBandGroup extends BandSet {
         }
     }
 
-    private int[] tagListToArray(final List t2) {
-        final int[] ints = new int[t2.size()];
+    private int[] tagListToArray(final List<String> list) {
+        final int[] ints = new int[list.size()];
         for (int i = 0; i < ints.length; i++) {
-            ints[i] = ((String) t2.get(i)).charAt(0);
+            ints[i] = list.get(i).charAt(0);
         }
         return ints;
     }
@@ -222,143 +222,140 @@ public class MetadataBandGroup extends BandSet {
      * @param nestNameRU TODO
      * @param nestPairN TODO
      */
-    public void addParameterAnnotation(final int numParams, final int[] annoN, final IntList pairN, final List typeRS,
-        final List nameRU, final List t, final List values, final List caseArrayN, final List nestTypeRS,
-        final List nestNameRU, final List nestPairN) {
-        param_NB.add(numParams);
-        for (int element : annoN) {
-            anno_N.add(element);
-        }
-        pair_N.addAll(pairN);
-        for (Object element : typeRS) {
-            final String desc = (String) element;
-            type_RS.add(cpBands.getCPSignature(desc));
-        }
-        for (Object element : nameRU) {
-            final String name = (String) element;
-            name_RU.add(cpBands.getCPUtf8(name));
-        }
-        final Iterator valuesIterator = values.iterator();
-        for (Object element : t) {
-            final String tag = (String) element;
-            T.add(tag);
-            if (tag.equals("B") || tag.equals("C") || tag.equals("I") || tag.equals("S") || tag.equals("Z")) {
-                final Integer value = (Integer) valuesIterator.next();
-                caseI_KI.add(cpBands.getConstant(value));
-            } else if (tag.equals("D")) {
-                final Double value = (Double) valuesIterator.next();
-                caseD_KD.add(cpBands.getConstant(value));
-            } else if (tag.equals("F")) {
-                final Float value = (Float) valuesIterator.next();
-                caseF_KF.add(cpBands.getConstant(value));
-            } else if (tag.equals("J")) {
-                final Long value = (Long) valuesIterator.next();
-                caseJ_KJ.add(cpBands.getConstant(value));
-            } else if (tag.equals("c")) {
-                final String value = (String) valuesIterator.next();
-                casec_RS.add(cpBands.getCPSignature(value));
-            } else if (tag.equals("e")) {
-                final String value = (String) valuesIterator.next();
-                final String value2 = (String) valuesIterator.next();
-                caseet_RS.add(cpBands.getCPSignature(value));
-                caseec_RU.add(cpBands.getCPUtf8(value2));
-            } else if (tag.equals("s")) {
-                final String value = (String) valuesIterator.next();
-                cases_RU.add(cpBands.getCPUtf8(value));
-            }
-            // do nothing here for [ or @ (handled below)
-        }
-        for (Object element : caseArrayN) {
-            final int arraySize = ((Integer) element).intValue();
-            casearray_N.add(arraySize);
-            numBackwardsCalls += arraySize;
-        }
-        for (Object element : nestTypeRS) {
-            final String type = (String) element;
-            nesttype_RS.add(cpBands.getCPSignature(type));
-        }
-        for (Object element : nestNameRU) {
-            final String name = (String) element;
-            nestname_RU.add(cpBands.getCPUtf8(name));
-        }
-        for (Object element : nestPairN) {
-            final Integer numPairs = (Integer) element;
-            nestpair_N.add(numPairs.intValue());
-            numBackwardsCalls += numPairs.intValue();
-        }
-    }
+	public void addParameterAnnotation(final int numParams, final int[] annoN, final IntList pairN,
+			final List<String> typeRS, final List<String> nameRU, final List<String> t, final List<Object> values,
+			final List<Integer> caseArrayN, final List<String> nestTypeRS, final List<String> nestNameRU,
+			final List<Integer> nestPairN) {
+		param_NB.add(numParams);
+		for (int element : annoN) {
+			anno_N.add(element);
+		}
+		pair_N.addAll(pairN);
+		for (String desc : typeRS) {
+			type_RS.add(cpBands.getCPSignature(desc));
+		}
+		for (String name : nameRU) {
+			name_RU.add(cpBands.getCPUtf8(name));
+		}
+		final Iterator<Object> valuesIterator = values.iterator();
+		for (String tag : t) {
+			T.add(tag);
+			if (tag.equals("B") || tag.equals("C") || tag.equals("I") || tag.equals("S") || tag.equals("Z")) {
+				final Integer value = (Integer) valuesIterator.next();
+				caseI_KI.add(cpBands.getConstant(value));
+			} else if (tag.equals("D")) {
+				final Double value = (Double) valuesIterator.next();
+				caseD_KD.add(cpBands.getConstant(value));
+			} else if (tag.equals("F")) {
+				final Float value = (Float) valuesIterator.next();
+				caseF_KF.add(cpBands.getConstant(value));
+			} else if (tag.equals("J")) {
+				final Long value = (Long) valuesIterator.next();
+				caseJ_KJ.add(cpBands.getConstant(value));
+			} else if (tag.equals("c")) {
+				final String value = (String) valuesIterator.next();
+				casec_RS.add(cpBands.getCPSignature(value));
+			} else if (tag.equals("e")) {
+				final String value = (String) valuesIterator.next();
+				final String value2 = (String) valuesIterator.next();
+				caseet_RS.add(cpBands.getCPSignature(value));
+				caseec_RU.add(cpBands.getCPUtf8(value2));
+			} else if (tag.equals("s")) {
+				final String value = (String) valuesIterator.next();
+				cases_RU.add(cpBands.getCPUtf8(value));
+			}
+			// do nothing here for [ or @ (handled below)
+		}
+		for (Object element : caseArrayN) {
+			final int arraySize = ((Integer) element).intValue();
+			casearray_N.add(arraySize);
+			numBackwardsCalls += arraySize;
+		}
+		for (Object element : nestTypeRS) {
+			final String type = (String) element;
+			nesttype_RS.add(cpBands.getCPSignature(type));
+		}
+		for (Object element : nestNameRU) {
+			final String name = (String) element;
+			nestname_RU.add(cpBands.getCPUtf8(name));
+		}
+		for (Object element : nestPairN) {
+			final Integer numPairs = (Integer) element;
+			nestpair_N.add(numPairs.intValue());
+			numBackwardsCalls += numPairs.intValue();
+		}
+	}
 
     /**
      * Add an annotation to this set of bands
      *
      * @param desc TODO
      * @param nameRU TODO
-     * @param t TODO
+     * @param tags TODO
      * @param values TODO
      * @param caseArrayN TODO
      * @param nestTypeRS TODO
      * @param nestNameRU TODO
      * @param nestPairN TODO
      */
-    public void addAnnotation(final String desc, final List nameRU, final List t, final List values,
-        final List caseArrayN, final List nestTypeRS, final List nestNameRU, final List nestPairN) {
-        type_RS.add(cpBands.getCPSignature(desc));
-        pair_N.add(nameRU.size());
-
-        for (Object element : nameRU) {
-            final String name = (String) element;
-            name_RU.add(cpBands.getCPUtf8(name));
-        }
-
-        final Iterator valuesIterator = values.iterator();
-        for (Object element : t) {
-            final String tag = (String) element;
-            T.add(tag);
-            if (tag.equals("B") || tag.equals("C") || tag.equals("I") || tag.equals("S") || tag.equals("Z")) {
-                final Integer value = (Integer) valuesIterator.next();
-                caseI_KI.add(cpBands.getConstant(value));
-            } else if (tag.equals("D")) {
-                final Double value = (Double) valuesIterator.next();
-                caseD_KD.add(cpBands.getConstant(value));
-            } else if (tag.equals("F")) {
-                final Float value = (Float) valuesIterator.next();
-                caseF_KF.add(cpBands.getConstant(value));
-            } else if (tag.equals("J")) {
-                final Long value = (Long) valuesIterator.next();
-                caseJ_KJ.add(cpBands.getConstant(value));
-            } else if (tag.equals("c")) {
-                final String value = (String) valuesIterator.next();
-                casec_RS.add(cpBands.getCPSignature(value));
-            } else if (tag.equals("e")) {
-                final String value = (String) valuesIterator.next();
-                final String value2 = (String) valuesIterator.next();
-                caseet_RS.add(cpBands.getCPSignature(value));
-                caseec_RU.add(cpBands.getCPUtf8(value2));
-            } else if (tag.equals("s")) {
-                final String value = (String) valuesIterator.next();
-                cases_RU.add(cpBands.getCPUtf8(value));
-            }
-            // do nothing here for [ or @ (handled below)
-        }
-        for (Object element : caseArrayN) {
-            final int arraySize = ((Integer) element).intValue();
-            casearray_N.add(arraySize);
-            numBackwardsCalls += arraySize;
-        }
-        for (Object element : nestTypeRS) {
-            final String type = (String) element;
-            nesttype_RS.add(cpBands.getCPSignature(type));
-        }
-        for (Object element : nestNameRU) {
-            final String name = (String) element;
-            nestname_RU.add(cpBands.getCPUtf8(name));
-        }
-        for (Object element : nestPairN) {
-            final Integer numPairs = (Integer) element;
-            nestpair_N.add(numPairs.intValue());
-            numBackwardsCalls += numPairs.intValue();
-        }
-    }
+	public void addAnnotation(final String desc, final List<String> nameRU, final List<String> tags,
+			final List<Object> values, final List<Integer> caseArrayN, final List<String> nestTypeRS,
+			final List<String> nestNameRU, final List<Integer> nestPairN) {
+		type_RS.add(cpBands.getCPSignature(desc));
+		pair_N.add(nameRU.size());
+
+		for (String name : nameRU) {
+			name_RU.add(cpBands.getCPUtf8(name));
+		}
+
+		final Iterator<Object> valuesIterator = values.iterator();
+		for (String tag : tags) {
+			T.add(tag);
+			if (tag.equals("B") || tag.equals("C") || tag.equals("I") || tag.equals("S") || tag.equals("Z")) {
+				final Integer value = (Integer) valuesIterator.next();
+				caseI_KI.add(cpBands.getConstant(value));
+			} else if (tag.equals("D")) {
+				final Double value = (Double) valuesIterator.next();
+				caseD_KD.add(cpBands.getConstant(value));
+			} else if (tag.equals("F")) {
+				final Float value = (Float) valuesIterator.next();
+				caseF_KF.add(cpBands.getConstant(value));
+			} else if (tag.equals("J")) {
+				final Long value = (Long) valuesIterator.next();
+				caseJ_KJ.add(cpBands.getConstant(value));
+			} else if (tag.equals("c")) {
+				final String value = (String) valuesIterator.next();
+				casec_RS.add(cpBands.getCPSignature(value));
+			} else if (tag.equals("e")) {
+				final String value = (String) valuesIterator.next();
+				final String value2 = (String) valuesIterator.next();
+				caseet_RS.add(cpBands.getCPSignature(value));
+				caseec_RU.add(cpBands.getCPUtf8(value2));
+			} else if (tag.equals("s")) {
+				final String value = (String) valuesIterator.next();
+				cases_RU.add(cpBands.getCPUtf8(value));
+			}
+			// do nothing here for [ or @ (handled below)
+		}
+		for (Object element : caseArrayN) {
+			final int arraySize = ((Integer) element).intValue();
+			casearray_N.add(arraySize);
+			numBackwardsCalls += arraySize;
+		}
+		for (Object element : nestTypeRS) {
+			final String type = (String) element;
+			nesttype_RS.add(cpBands.getCPSignature(type));
+		}
+		for (Object element : nestNameRU) {
+			final String name = (String) element;
+			nestname_RU.add(cpBands.getCPUtf8(name));
+		}
+		for (Object element : nestPairN) {
+			final Integer numPairs = (Integer) element;
+			nestpair_N.add(numPairs.intValue());
+			numBackwardsCalls += numPairs.intValue();
+		}
+	}
 
     /**
      * Returns true if any annotations have been added to this set of bands.
@@ -399,7 +396,7 @@ public class MetadataBandGroup extends BandSet {
      * Convenience method for removeLatest
      */
     private void removeOnePair() {
-        final String tag = (String) T.remove(T.size() - 1);
+        final String tag = T.remove(T.size() - 1);
         if (tag.equals("B") || tag.equals("C") || tag.equals("I") || tag.equals("S") || tag.equals("Z")) {
             caseI_KI.remove(caseI_KI.size() - 1);
         } else if (tag.equals("D")) {
diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/Segment.java b/src/main/java/org/apache/commons/compress/harmony/pack200/Segment.java
index 7e9e2ba0..6a7d4b75 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/Segment.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/Segment.java
@@ -415,7 +415,7 @@ public class Segment extends ClassVisitor {
         }
 
         @Override
-        public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) {
+        public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label... labels) {
             bcBands.visitTableSwitchInsn(min, max, dflt, labels);
         }
 
@@ -445,13 +445,13 @@ public class Segment extends ClassVisitor {
         private String desc;
         private boolean visible;
 
-        private final List nameRU = new ArrayList();
-        private final List T = new ArrayList(); // tags
-        private final List values = new ArrayList();
-        private final List caseArrayN = new ArrayList();
-        private final List nestTypeRS = new ArrayList();
-        private final List nestNameRU = new ArrayList();
-        private final List nestPairN = new ArrayList();
+        private final List<String> nameRU = new ArrayList<>();
+        private final List<String> tags = new ArrayList<>(); // tags
+        private final List<Object> values = new ArrayList<>();
+        private final List<Integer> caseArrayN = new ArrayList<>();
+        private final List<String> nestTypeRS = new ArrayList<>();
+        private final List<String> nestNameRU = new ArrayList<>();
+        private final List<Integer> nestPairN = new ArrayList<>();
 
         public SegmentAnnotationVisitor(final int context, final String desc, final boolean visible) {
             super(ASM_API);
@@ -480,12 +480,12 @@ public class Segment extends ClassVisitor {
                 name = "";
             }
             nameRU.add(name);
-            addValueAndTag(value, T, values);
+            addValueAndTag(value, tags, values);
         }
 
         @Override
         public AnnotationVisitor visitAnnotation(String name, final String desc) {
-            T.add("@");
+            tags.add("@");
             if (name == null) {
                 name = "";
             }
@@ -495,10 +495,10 @@ public class Segment extends ClassVisitor {
             return new AnnotationVisitor(context, av) {
                 @Override
                 public void visit(final String name, final Object value) {
-                    final Integer numPairs = (Integer) nestPairN.remove(nestPairN.size() - 1);
+                    final Integer numPairs = nestPairN.remove(nestPairN.size() - 1);
                     nestPairN.add(Integer.valueOf(numPairs.intValue() + 1));
                     nestNameRU.add(name);
-                    addValueAndTag(value, T, values);
+                    addValueAndTag(value, tags, values);
                 }
 
                 @Override
@@ -519,9 +519,9 @@ public class Segment extends ClassVisitor {
 
                 @Override
                 public void visitEnum(final String name, final String desc, final String value) {
-                    final Integer numPairs = (Integer) nestPairN.remove(nestPairN.size() - 1);
+                    final Integer numPairs = nestPairN.remove(nestPairN.size() - 1);
                     nestPairN.add(Integer.valueOf(numPairs.intValue() + 1));
-                    T.add("e");
+                    tags.add("e");
                     nestNameRU.add(name);
                     values.add(desc);
                     values.add(value);
@@ -531,32 +531,32 @@ public class Segment extends ClassVisitor {
 
         @Override
         public AnnotationVisitor visitArray(String name) {
-            T.add("[");
+            tags.add("[");
             if (name == null) {
                 name = "";
             }
             nameRU.add(name);
             caseArrayN.add(Integer.valueOf(0));
-            return new ArrayVisitor(caseArrayN, T, nameRU, values);
+            return new ArrayVisitor(caseArrayN, tags, nameRU, values);
         }
 
         @Override
         public void visitEnd() {
             if (desc == null) {
-                Segment.this.classBands.addAnnotationDefault(nameRU, T, values, caseArrayN, nestTypeRS, nestNameRU,
+                Segment.this.classBands.addAnnotationDefault(nameRU, tags, values, caseArrayN, nestTypeRS, nestNameRU,
                     nestPairN);
             } else if (parameter != -1) {
-                Segment.this.classBands.addParameterAnnotation(parameter, desc, visible, nameRU, T, values, caseArrayN,
+                Segment.this.classBands.addParameterAnnotation(parameter, desc, visible, nameRU, tags, values, caseArrayN,
                     nestTypeRS, nestNameRU, nestPairN);
             } else {
-                Segment.this.classBands.addAnnotation(context, desc, visible, nameRU, T, values, caseArrayN, nestTypeRS,
+                Segment.this.classBands.addAnnotation(context, desc, visible, nameRU, tags, values, caseArrayN, nestTypeRS,
                     nestNameRU, nestPairN);
             }
         }
 
         @Override
         public void visitEnum(String name, final String desc, final String value) {
-            T.add("e");
+            tags.add("e");
             if (name == null) {
                 name = "";
             }
@@ -569,16 +569,16 @@ public class Segment extends ClassVisitor {
     public class ArrayVisitor extends AnnotationVisitor {
 
         private final int indexInCaseArrayN;
-        private final List caseArrayN;
-        private final List values;
-        private final List nameRU;
-        private final List T;
+        private final List<Integer> caseArrayN;
+        private final List<Object> values;
+        private final List<String> nameRU;
+        private final List<String> tags;
 
-        public ArrayVisitor(final List caseArrayN, final List T, final List nameRU, final List values) {
+        public ArrayVisitor(final List<Integer> caseArrayN, final List<String> tags, final List<String> nameRU, final List<Object> values) {
             super(ASM_API);
 
             this.caseArrayN = caseArrayN;
-            this.T = T;
+            this.tags = tags;
             this.nameRU = nameRU;
             this.values = values;
             this.indexInCaseArrayN = caseArrayN.size() - 1;
@@ -586,12 +586,12 @@ public class Segment extends ClassVisitor {
 
         @Override
         public void visit(String name, final Object value) {
-            final Integer numCases = (Integer) caseArrayN.remove(indexInCaseArrayN);
+            final Integer numCases = caseArrayN.remove(indexInCaseArrayN);
             caseArrayN.add(indexInCaseArrayN, Integer.valueOf(numCases.intValue() + 1));
             if (name == null) {
                 name = "";
             }
-            addValueAndTag(value, T, values);
+            addValueAndTag(value, tags, values);
         }
 
         @Override
@@ -601,13 +601,13 @@ public class Segment extends ClassVisitor {
 
         @Override
         public AnnotationVisitor visitArray(String name) {
-            T.add("[");
+            tags.add("[");
             if (name == null) {
                 name = "";
             }
             nameRU.add(name);
             caseArrayN.add(Integer.valueOf(0));
-            return new ArrayVisitor(caseArrayN, T, nameRU, values);
+            return new ArrayVisitor(caseArrayN, tags, nameRU, values);
         }
 
         @Override
@@ -616,9 +616,9 @@ public class Segment extends ClassVisitor {
 
         @Override
         public void visitEnum(final String name, final String desc, final String value) {
-            final Integer numCases = (Integer) caseArrayN.remove(caseArrayN.size() - 1);
+            final Integer numCases = caseArrayN.remove(caseArrayN.size() - 1);
             caseArrayN.add(Integer.valueOf(numCases.intValue() + 1));
-            T.add("e");
+            tags.add("e");
             values.add(desc);
             values.add(value);
         }
@@ -670,36 +670,36 @@ public class Segment extends ClassVisitor {
     }
 
     // helper method for annotation visitors
-    private void addValueAndTag(final Object value, final List T, final List values) {
+    private void addValueAndTag(final Object value, final List<String> tags, final List<Object> values) {
         if (value instanceof Integer) {
-            T.add("I");
+            tags.add("I");
             values.add(value);
         } else if (value instanceof Double) {
-            T.add("D");
+            tags.add("D");
             values.add(value);
         } else if (value instanceof Float) {
-            T.add("F");
+            tags.add("F");
             values.add(value);
         } else if (value instanceof Long) {
-            T.add("J");
+            tags.add("J");
             values.add(value);
         } else if (value instanceof Byte) {
-            T.add("B");
+            tags.add("B");
             values.add(Integer.valueOf(((Byte) value).intValue()));
         } else if (value instanceof Character) {
-            T.add("C");
+            tags.add("C");
             values.add(Integer.valueOf(((Character) value).charValue()));
         } else if (value instanceof Short) {
-            T.add("S");
+            tags.add("S");
             values.add(Integer.valueOf(((Short) value).intValue()));
         } else if (value instanceof Boolean) {
-            T.add("Z");
+            tags.add("Z");
             values.add(Integer.valueOf(((Boolean) value).booleanValue() ? 1 : 0));
         } else if (value instanceof String) {
-            T.add("s");
+            tags.add("s");
             values.add(value);
         } else if (value instanceof Type) {
-            T.add("c");
+            tags.add("c");
             values.add(((Type) value).toString());
         }
     }
@@ -738,5 +738,7 @@ public class Segment extends ClassVisitor {
      */
     public static class PassException extends RuntimeException {
 
+		private static final long serialVersionUID = 1L;
+
     }
 }
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/AttributeLayoutMap.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/AttributeLayoutMap.java
index aca5725e..a8579ab0 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/AttributeLayoutMap.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/AttributeLayoutMap.java
@@ -120,17 +120,17 @@ public class AttributeLayoutMap {
             new AttributeLayout(AttributeLayout.ATTRIBUTE_ANNOTATION_DEFAULT, AttributeLayout.CONTEXT_METHOD, "*", 25)};
     }
 
-    private final Map classLayouts = new HashMap();
-    private final Map fieldLayouts = new HashMap();
-    private final Map methodLayouts = new HashMap();
-    private final Map codeLayouts = new HashMap();
+    private final Map<Integer, AttributeLayout> classLayouts = new HashMap<>();
+    private final Map<Integer, AttributeLayout> fieldLayouts = new HashMap<>();
+    private final Map<Integer, AttributeLayout> methodLayouts = new HashMap<>();
+    private final Map<Integer, AttributeLayout> codeLayouts = new HashMap<>();
 
     // The order of the maps in this array should not be changed as their
     // indices correspond to
     // the value of their context constants (AttributeLayout.CONTEXT_CLASS etc.)
-    private final Map[] layouts = {classLayouts, fieldLayouts, methodLayouts, codeLayouts};
+	private final Map[] layouts = { classLayouts, fieldLayouts, methodLayouts, codeLayouts };
 
-    private final Map layoutsToBands = new HashMap();
+    private final Map<AttributeLayout, NewAttributeBands> layoutsToBands = new HashMap<>();
 
     public AttributeLayoutMap() throws Pack200Exception {
         final AttributeLayout[] defaultAttributeLayouts = getDefaultAttributeLayouts();
@@ -140,7 +140,7 @@ public class AttributeLayoutMap {
     }
 
     public void add(final AttributeLayout layout) {
-        layouts[layout.getContext()].put(Integer.valueOf(layout.getIndex()), layout);
+        getLayout(layout.getContext()).put(Integer.valueOf(layout.getIndex()), layout);
     }
 
     public void add(final AttributeLayout layout, final NewAttributeBands newBands) {
@@ -148,38 +148,22 @@ public class AttributeLayoutMap {
         layoutsToBands.put(layout, newBands);
     }
 
-    public AttributeLayout getAttributeLayout(final String name, final int context) {
-        final Map map = layouts[context];
-        for (Object element : map.values()) {
-            final AttributeLayout layout = (AttributeLayout) element;
-            if (layout.getName().equals(name)) {
-                return layout;
-            }
-        }
-        return null;
-    }
-
-    public AttributeLayout getAttributeLayout(final int index, final int context) {
-        final Map map = layouts[context];
-        return (AttributeLayout) map.get(Integer.valueOf(index));
-    }
-
     /**
      * The map should not contain the same layout and name combination more than once for each context.
      *
      * @throws Pack200Exception Thrown when the name layout/name combination exists twice for a context.
      */
     public void checkMap() throws Pack200Exception {
-        for (final Map map : layouts) {
-            Collection c = map.values();
+        for (final Map<Integer, AttributeLayout> map : layouts) {
+            Collection<AttributeLayout> c = map.values();
             if (!(c instanceof List)) {
-                c = new ArrayList(c);
+                c = new ArrayList<>(c);
             }
-            final List l = (List) c;
-            for (int j = 0; j < l.size(); j++) {
-                final AttributeLayout layout1 = (AttributeLayout) l.get(j);
-                for (int j2 = j + 1; j2 < l.size(); j2++) {
-                    final AttributeLayout layout2 = (AttributeLayout) l.get(j2);
+            final List<AttributeLayout> layouts = (List<AttributeLayout>) c;
+            for (int j = 0; j < layouts.size(); j++) {
+                final AttributeLayout layout1 = layouts.get(j);
+                for (int j2 = j + 1; j2 < layouts.size(); j2++) {
+                    final AttributeLayout layout2 = layouts.get(j2);
                     if (layout1.getName().equals(layout2.getName())
                         && layout1.getLayout().equals(layout2.getLayout())) {
                         throw new Pack200Exception(
@@ -191,8 +175,27 @@ public class AttributeLayoutMap {
         }
     }
 
-    public NewAttributeBands getAttributeBands(final AttributeLayout layout) {
-        return (NewAttributeBands) layoutsToBands.get(layout);
+	public NewAttributeBands getAttributeBands(final AttributeLayout layout) {
+        return layoutsToBands.get(layout);
     }
 
+    public AttributeLayout getAttributeLayout(final int index, final int context) {
+        final Map<Integer, AttributeLayout> map = getLayout(context);
+        return map.get(Integer.valueOf(index));
+    }
+
+    public AttributeLayout getAttributeLayout(final String name, final int context) {
+        final Map<Integer, AttributeLayout> map = getLayout(context);
+        for (AttributeLayout layout : map.values()) {
+            if (layout.getName().equals(name)) {
+                return layout;
+            }
+        }
+        return null;
+    }
+
+    private Map<Integer, AttributeLayout> getLayout(final int context) {
+		return layouts[context];
+	}
+
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/BcBands.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/BcBands.java
index fbab0721..1a962562 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/BcBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/BcBands.java
@@ -70,7 +70,7 @@ public class BcBands extends BandSet {
     private int[] bcEscSize;
     private int[][] bcEscByte;
 
-    private List wideByteCodes;
+    private List<Integer> wideByteCodes;
 
     /**
      * @param segment TODO
@@ -121,8 +121,8 @@ public class BcBands extends BandSet {
         methodByteCodePacked = new byte[classCount][][];
         int bcParsed = 0;
 
-        final List switchIsTableSwitch = new ArrayList();
-        wideByteCodes = new ArrayList();
+        final List<Boolean> switchIsTableSwitch = new ArrayList<>();
+        wideByteCodes = new ArrayList<>();
         for (int c = 0; c < classCount; c++) {
             final int numberOfMethods = methodFlags[c].length;
             methodByteCodePacked[c] = new byte[numberOfMethods][];
@@ -293,7 +293,7 @@ public class BcBands extends BandSet {
         bcCaseCount = decodeBandInt("bc_case_count", in, Codec.UNSIGNED5, bcCaseCountCount);
         int bcCaseValueCount = 0;
         for (int i = 0; i < bcCaseCount.length; i++) {
-            final boolean isTableSwitch = ((Boolean) switchIsTableSwitch.get(i)).booleanValue();
+            final boolean isTableSwitch = switchIsTableSwitch.get(i).booleanValue();
             if (isTableSwitch) {
                 bcCaseValueCount += 1;
             } else {
@@ -337,7 +337,7 @@ public class BcBands extends BandSet {
         final long[][] methodFlags = segment.getClassBands().getMethodFlags();
         final int[] codeMaxNALocals = segment.getClassBands().getCodeMaxNALocals();
         final int[] codeMaxStack = segment.getClassBands().getCodeMaxStack();
-        final ArrayList[][] methodAttributes = segment.getClassBands().getMethodAttributes();
+        final ArrayList<Attribute>[][] methodAttributes = segment.getClassBands().getMethodAttributes();
         final String[][] methodDescr = segment.getClassBands().getMethodDescr();
 
         final AttributeLayoutMap attributeDefinitionMap = segment.getAttrDefinitionBands().getAttributeDefinitionMap();
@@ -351,7 +351,7 @@ public class BcBands extends BandSet {
 
         final int[] wideByteCodeArray = new int[wideByteCodes.size()];
         for (int index = 0; index < wideByteCodeArray.length; index++) {
-            wideByteCodeArray[index] = ((Integer) wideByteCodes.get(index)).intValue();
+            wideByteCodeArray[index] = wideByteCodes.get(index).intValue();
         }
         final OperandManager operandManager = new OperandManager(bcCaseCount, bcCaseValue, bcByte, bcShort, bcLocal,
             bcLabel, bcIntRef, bcFloatRef, bcLongRef, bcDoubleRef, bcStringRef, bcClassRef, bcFieldRef, bcMethodRef,
@@ -359,7 +359,7 @@ public class BcBands extends BandSet {
         operandManager.setSegment(segment);
 
         int i = 0;
-        final ArrayList orderedCodeAttributes = segment.getClassBands().getOrderedCodeAttributes();
+        final ArrayList<List<Attribute>> orderedCodeAttributes = segment.getClassBands().getOrderedCodeAttributes();
         int codeAttributeIndex = 0;
 
         // Exception table fields
@@ -387,7 +387,7 @@ public class BcBands extends BandSet {
                     final String[] cpClass = segment.getCpBands().getCpClass();
                     operandManager.setCurrentClass(cpClass[segment.getClassBands().getClassThisInts()[c]]);
                     operandManager.setSuperClass(cpClass[segment.getClassBands().getClassSuperInts()[c]]);
-                    final List exceptionTable = new ArrayList();
+                    final List<ExceptionTableEntry> exceptionTable = new ArrayList<>();
                     if (handlerCount != null) {
                         for (int j = 0; j < handlerCount[i]; j++) {
                             final int handlerClass = handlerClassTypes[i][j] - 1;
@@ -405,11 +405,10 @@ public class BcBands extends BandSet {
                     }
                     final CodeAttribute codeAttr = new CodeAttribute(maxStack, maxLocal, methodByteCodePacked[c][m],
                         segment, operandManager, exceptionTable);
-                    final ArrayList methodAttributesList = methodAttributes[c][m];
+                    final List<Attribute> methodAttributesList = methodAttributes[c][m];
                     // Make sure we add the code attribute in the right place
                     int indexForCodeAttr = 0;
-                    for (Object element : methodAttributesList) {
-                        final Attribute attribute = (Attribute) element;
+                    for (Attribute attribute : methodAttributesList) {
                         if (!(attribute instanceof NewAttribute)
                             || (((NewAttribute) attribute).getLayoutIndex() >= 15)) {
                             break;
@@ -418,11 +417,11 @@ public class BcBands extends BandSet {
                     }
                     methodAttributesList.add(indexForCodeAttr, codeAttr);
                     codeAttr.renumber(codeAttr.byteCodeOffsets);
-                    List currentAttributes;
+                    List<Attribute> currentAttributes;
                     if (allCodeHasFlags) {
-                        currentAttributes = (List) orderedCodeAttributes.get(i);
+                        currentAttributes = orderedCodeAttributes.get(i);
                     } else if (codeHasFlags[i]) {
-                        currentAttributes = (List) orderedCodeAttributes.get(codeAttributeIndex);
+                        currentAttributes = orderedCodeAttributes.get(codeAttributeIndex);
                         codeAttributeIndex++;
                     } else {
                         currentAttributes = Collections.EMPTY_LIST;
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/ClassBands.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/ClassBands.java
index 13bb1af7..c38c077c 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/ClassBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/ClassBands.java
@@ -60,7 +60,7 @@ public class ClassBands extends BandSet {
 
     private int[] classThisInts;
 
-    private ArrayList[] classAttributes;
+    private ArrayList<Attribute>[] classAttributes;
 
     private int[] classVersionMajor;
 
@@ -68,7 +68,7 @@ public class ClassBands extends BandSet {
 
     private IcTuple[][] icLocal;
 
-    private List[] codeAttributes;
+    private List<Attribute>[] codeAttributes;
 
     private int[] codeHandlerCount;
 
@@ -76,7 +76,7 @@ public class ClassBands extends BandSet {
 
     private int[] codeMaxStack;
 
-    private ArrayList[][] fieldAttributes;
+    private ArrayList<Attribute>[][] fieldAttributes;
 
     private String[][] fieldDescr;
 
@@ -86,7 +86,7 @@ public class ClassBands extends BandSet {
 
     private long[][] fieldAccessFlags;
 
-    private ArrayList[][] methodAttributes;
+    private ArrayList<Attribute>[][] methodAttributes;
 
     private String[][] methodDescr;
 
@@ -174,7 +174,7 @@ public class ClassBands extends BandSet {
         for (int i = 0; i < classCount; i++) {
             fieldAttributes[i] = new ArrayList[fieldFlags[i].length];
             for (int j = 0; j < fieldFlags[i].length; j++) {
-                fieldAttributes[i][j] = new ArrayList();
+                fieldAttributes[i][j] = new ArrayList<>();
             }
         }
 
@@ -231,7 +231,7 @@ public class ClassBands extends BandSet {
         final int limit = options.hasFieldFlagsHi() ? 62 : 31;
         final AttributeLayout[] otherLayouts = new AttributeLayout[limit + 1];
         final int[] counts = new int[limit + 1];
-        final List[] otherAttributes = new List[limit + 1];
+        final List<Attribute>[] otherAttributes = new List[limit + 1];
         for (int i = 0; i < limit; i++) {
             final AttributeLayout layout = attrMap.getAttributeLayout(i, AttributeLayout.CONTEXT_FIELD);
             if (layout != null && !(layout.isDefaultLayout())) {
@@ -292,7 +292,7 @@ public class ClassBands extends BandSet {
         for (int i = 0; i < classCount; i++) {
             methodAttributes[i] = new ArrayList[methodFlags[i].length];
             for (int j = 0; j < methodFlags[i].length; j++) {
-                methodAttributes[i][j] = new ArrayList();
+                methodAttributes[i][j] = new ArrayList<>();
             }
         }
 
@@ -355,7 +355,6 @@ public class ClassBands extends BandSet {
         final int limit = options.hasMethodFlagsHi() ? 62 : 31;
         final AttributeLayout[] otherLayouts = new AttributeLayout[limit + 1];
         final int[] counts = new int[limit + 1];
-        final List[] otherAttributes = new List[limit + 1];
         for (int i = 0; i < limit; i++) {
             final AttributeLayout layout = attrMap.getAttributeLayout(i, AttributeLayout.CONTEXT_METHOD);
             if (layout != null && !(layout.isDefaultLayout())) {
@@ -363,6 +362,7 @@ public class ClassBands extends BandSet {
                 counts[i] = SegmentUtils.countMatches(methodFlags, layout);
             }
         }
+        final List<Attribute>[] otherAttributes = new List[limit + 1];
         for (int i = 0; i < counts.length; i++) {
             if (counts[i] > 0) {
                 final NewAttributeBands bands = attrMap.getAttributeBands(otherLayouts[i]);
@@ -428,7 +428,7 @@ public class ClassBands extends BandSet {
         // Prepare empty attribute lists
         classAttributes = new ArrayList[classCount];
         for (int i = 0; i < classCount; i++) {
-            classAttributes[i] = new ArrayList();
+            classAttributes[i] = new ArrayList<>();
         }
 
         classFlags = parseFlags("class_flags", in, classCount, Codec.UNSIGNED5, options.hasClassFlagsHi());
@@ -501,7 +501,7 @@ public class ClassBands extends BandSet {
         final int limit = options.hasClassFlagsHi() ? 62 : 31;
         final AttributeLayout[] otherLayouts = new AttributeLayout[limit + 1];
         final int[] counts = new int[limit + 1];
-        final List[] otherAttributes = new List[limit + 1];
+        final List<Attribute>[] otherAttributes = new List[limit + 1];
         for (int i = 0; i < limit; i++) {
             final AttributeLayout layout = attrMap.getAttributeLayout(i, AttributeLayout.CONTEXT_CLASS);
             if (layout != null && !(layout.isDefaultLayout())) {
@@ -702,7 +702,7 @@ public class ClassBands extends BandSet {
 
         codeAttributes = new List[codeFlagsCount];
         for (int i = 0; i < codeAttributes.length; i++) {
-            codeAttributes[i] = new ArrayList();
+            codeAttributes[i] = new ArrayList<>();
         }
         parseCodeAttrBands(in, codeFlagsCount);
     }
@@ -773,7 +773,7 @@ public class ClassBands extends BandSet {
         final int limit = options.hasCodeFlagsHi() ? 62 : 31;
         final AttributeLayout[] otherLayouts = new AttributeLayout[limit + 1];
         final int[] counts = new int[limit + 1];
-        final List[] otherAttributes = new List[limit + 1];
+        final List<Attribute>[] otherAttributes = new List[limit + 1];
         for (int i = 0; i < limit; i++) {
             final AttributeLayout layout = attrMap.getAttributeLayout(i, AttributeLayout.CONTEXT_CODE);
             if (layout != null && !(layout.isDefaultLayout())) {
@@ -859,8 +859,8 @@ public class ClassBands extends BandSet {
             backwardsCallsUsed++;
         }
         final MetadataBandGroup[] mb = parseMetadata(in, RxA, RxACount, backwardsCalls, "field");
-        final List rvaAttributes = mb[0].getAttributes();
-        final List riaAttributes = mb[1].getAttributes();
+        final List<Attribute> rvaAttributes = mb[0].getAttributes();
+        final List<Attribute> riaAttributes = mb[1].getAttributes();
         int rvaAttributesIndex = 0;
         int riaAttributesIndex = 0;
         for (int i = 0; i < fieldFlags.length; i++) {
@@ -1003,7 +1003,7 @@ public class ClassBands extends BandSet {
             }
         }
         final MetadataBandGroup[] mbgs = parseMetadata(in, RxA, rxaCounts, backwardsCalls, "method");
-        final List[] attributeLists = new List[RxA.length];
+        final List<Attribute>[] attributeLists = new List[RxA.length];
         final int[] attributeListIndexes = new int[RxA.length];
         for (int i = 0; i < mbgs.length; i++) {
             attributeLists[i] = mbgs[i].getAttributes();
@@ -1055,8 +1055,8 @@ public class ClassBands extends BandSet {
             backwardsCalls[1] = classAttrCalls[0];
         }
         final MetadataBandGroup[] mbgs = parseMetadata(in, RxA, RxACount, backwardsCalls, "class");
-        final List rvaAttributes = mbgs[0].getAttributes();
-        final List riaAttributes = mbgs[1].getAttributes();
+        final List<Attribute> rvaAttributes = mbgs[0].getAttributes();
+        final List<Attribute> riaAttributes = mbgs[1].getAttributes();
         int rvaAttributesIndex = 0;
         int riaAttributesIndex = 0;
         for (int i = 0; i < classFlags.length; i++) {
@@ -1070,7 +1070,7 @@ public class ClassBands extends BandSet {
         return numBackwardsCalls;
     }
 
-    public ArrayList[] getClassAttributes() {
+    public ArrayList<Attribute>[] getClassAttributes() {
         return classAttributes;
     }
 
@@ -1123,7 +1123,7 @@ public class ClassBands extends BandSet {
         return codeMaxStack;
     }
 
-    public ArrayList[][] getFieldAttributes() {
+    public ArrayList<Attribute>[][] getFieldAttributes() {
         return fieldAttributes;
     }
 
@@ -1162,20 +1162,19 @@ public class ClassBands extends BandSet {
      *
      * @return ArrayList
      */
-    public ArrayList getOrderedCodeAttributes() {
-        final ArrayList orderedAttributeList = new ArrayList(codeAttributes.length);
+    public ArrayList<List<Attribute>> getOrderedCodeAttributes() {
+        final ArrayList<List<Attribute>> orderedAttributeList = new ArrayList<>(codeAttributes.length);
         for (int classIndex = 0; classIndex < codeAttributes.length; classIndex++) {
-            final ArrayList currentAttributes = new ArrayList(codeAttributes[classIndex].size());
+            final List<Attribute> currentAttributes = new ArrayList<>(codeAttributes[classIndex].size());
             for (int attributeIndex = 0; attributeIndex < codeAttributes[classIndex].size(); attributeIndex++) {
-                final Attribute attribute = (Attribute) codeAttributes[classIndex].get(attributeIndex);
-                currentAttributes.add(attribute);
+                currentAttributes.add(codeAttributes[classIndex].get(attributeIndex));
             }
             orderedAttributeList.add(currentAttributes);
         }
         return orderedAttributeList;
     }
 
-    public ArrayList[][] getMethodAttributes() {
+    public ArrayList<Attribute>[][] getMethodAttributes() {
         return methodAttributes;
     }
 
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/CpBands.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/CpBands.java
index cd5f2746..e9220197 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/CpBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/CpBands.java
@@ -74,17 +74,17 @@ public class CpBands extends BandSet {
     private int[] cpStringInts;
     private String[] cpUTF8;
 
-    private final Map stringsToCPUTF8 = new HashMap();
-    private final Map stringsToCPStrings = new HashMap();
-    private final Map longsToCPLongs = new HashMap();
-    private final Map integersToCPIntegers = new HashMap();
-    private final Map floatsToCPFloats = new HashMap();
-    private final Map stringsToCPClass = new HashMap();
-    private final Map doublesToCPDoubles = new HashMap();
-    private final Map descriptorsToCPNameAndTypes = new HashMap();
-
-    private Map mapClass;
-    private Map mapDescriptor;
+    private final Map<String, CPUTF8> stringsToCPUTF8 = new HashMap<>();
+    private final Map<String, CPString> stringsToCPStrings = new HashMap<>();
+    private final Map<Long, CPLong> longsToCPLongs = new HashMap<>();
+    private final Map<Integer, CPInteger> integersToCPIntegers = new HashMap<>();
+    private final Map<Float, CPFloat> floatsToCPFloats = new HashMap<>();
+    private final Map<String, CPClass> stringsToCPClass = new HashMap<>();
+    private final Map<Double, CPDouble> doublesToCPDoubles = new HashMap<>();
+    private final Map<String, CPNameAndType> descriptorsToCPNameAndTypes = new HashMap<>();
+
+    private Map<String, Integer> mapClass;
+    private Map<String, Integer> mapDescriptor;
     private Map<String, Integer> mapUTF8;
 
     // TODO: Not used
@@ -151,7 +151,7 @@ public class CpBands extends BandSet {
         final int cpClassCount = header.getCpClassCount();
         cpClassInts = decodeBandInt("cp_Class", in, Codec.UDELTA5, cpClassCount);
         cpClass = new String[cpClassCount];
-        mapClass = new HashMap(cpClassCount);
+        mapClass = new HashMap<>(cpClassCount);
         for (int i = 0; i < cpClassCount; i++) {
             cpClass[i] = cpUTF8[cpClassInts[i]];
             mapClass.put(cpClass[i], Integer.valueOf(i));
@@ -175,7 +175,7 @@ public class CpBands extends BandSet {
         final String[] cpDescriptorNames = getReferences(cpDescriptorNameInts, cpUTF8);
         final String[] cpDescriptorTypes = getReferences(cpDescriptorTypeInts, cpSignature);
         cpDescriptor = new String[cpDescriptorCount];
-        mapDescriptor = new HashMap(cpDescriptorCount);
+        mapDescriptor = new HashMap<>(cpDescriptorCount);
         for (int i = 0; i < cpDescriptorCount; i++) {
             cpDescriptor[i] = cpDescriptorNames[i] + ":" + cpDescriptorTypes[i]; //$NON-NLS-1$
             mapDescriptor.put(cpDescriptor[i], Integer.valueOf(i));
@@ -306,7 +306,7 @@ public class CpBands extends BandSet {
             final String form = cpSignatureForm[i];
             final int len = form.length();
             final StringBuilder signature = new StringBuilder(64);
-            final ArrayList list = new ArrayList();
+            final ArrayList<String> list = new ArrayList<>();
             for (int j = 0; j < len; j++) {
                 final char c = form.charAt(j);
                 signature.append(c);
@@ -445,7 +445,7 @@ public class CpBands extends BandSet {
 
     public CPUTF8 cpUTF8Value(final int index) {
         final String string = cpUTF8[index];
-        CPUTF8 cputf8 = (CPUTF8) stringsToCPUTF8.get(string);
+        CPUTF8 cputf8 = stringsToCPUTF8.get(string);
         if (cputf8 == null) {
             cputf8 = new CPUTF8(string, index);
             stringsToCPUTF8.put(string, cputf8);
@@ -460,7 +460,7 @@ public class CpBands extends BandSet {
     }
 
     public CPUTF8 cpUTF8Value(final String string, final boolean searchForIndex) {
-        CPUTF8 cputf8 = (CPUTF8) stringsToCPUTF8.get(string);
+        CPUTF8 cputf8 = stringsToCPUTF8.get(string);
         if (cputf8 == null) {
             Integer index = null;
             if (searchForIndex) {
@@ -485,7 +485,7 @@ public class CpBands extends BandSet {
         final String string = cpString[index];
         final int utf8Index = cpStringInts[index];
         final int globalIndex = stringOffset + index;
-        CPString cpString = (CPString) stringsToCPStrings.get(string);
+        CPString cpString = stringsToCPStrings.get(string);
         if (cpString == null) {
             cpString = new CPString(cpUTF8Value(utf8Index), globalIndex);
             stringsToCPStrings.put(string, cpString);
@@ -495,7 +495,7 @@ public class CpBands extends BandSet {
 
     public CPLong cpLongValue(final int index) {
         final Long l = Long.valueOf(cpLong[index]);
-        CPLong cpLong = (CPLong) longsToCPLongs.get(l);
+        CPLong cpLong = longsToCPLongs.get(l);
         if (cpLong == null) {
             cpLong = new CPLong(l, index + longOffset);
             longsToCPLongs.put(l, cpLong);
@@ -505,7 +505,7 @@ public class CpBands extends BandSet {
 
     public CPInteger cpIntegerValue(final int index) {
         final Integer i = Integer.valueOf(cpInt[index]);
-        CPInteger cpInteger = (CPInteger) integersToCPIntegers.get(i);
+        CPInteger cpInteger = integersToCPIntegers.get(i);
         if (cpInteger == null) {
             cpInteger = new CPInteger(i, index + intOffset);
             integersToCPIntegers.put(i, cpInteger);
@@ -515,7 +515,7 @@ public class CpBands extends BandSet {
 
     public CPFloat cpFloatValue(final int index) {
         final Float f = Float.valueOf(cpFloat[index]);
-        CPFloat cpFloat = (CPFloat) floatsToCPFloats.get(f);
+        CPFloat cpFloat = floatsToCPFloats.get(f);
         if (cpFloat == null) {
             cpFloat = new CPFloat(f, index + floatOffset);
             floatsToCPFloats.put(f, cpFloat);
@@ -527,7 +527,7 @@ public class CpBands extends BandSet {
         final String string = cpClass[index];
         final int utf8Index = cpClassInts[index];
         final int globalIndex = classOffset + index;
-        CPClass cpString = (CPClass) stringsToCPClass.get(string);
+        CPClass cpString = stringsToCPClass.get(string);
         if (cpString == null) {
             cpString = new CPClass(cpUTF8Value(utf8Index), globalIndex);
             stringsToCPClass.put(string, cpString);
@@ -536,9 +536,9 @@ public class CpBands extends BandSet {
     }
 
     public CPClass cpClassValue(final String string) {
-        CPClass cpString = (CPClass) stringsToCPClass.get(string);
+        CPClass cpString = stringsToCPClass.get(string);
         if (cpString == null) {
-            final Integer index = (Integer) mapClass.get(string);
+            final Integer index = mapClass.get(string);
             if (index != null) {
                 return cpClassValue(index.intValue());
             }
@@ -550,7 +550,7 @@ public class CpBands extends BandSet {
 
     public CPDouble cpDoubleValue(final int index) {
         final Double dbl = Double.valueOf(cpDouble[index]);
-        CPDouble cpDouble = (CPDouble) doublesToCPDoubles.get(dbl);
+        CPDouble cpDouble = doublesToCPDoubles.get(dbl);
         if (cpDouble == null) {
             cpDouble = new CPDouble(dbl, index + doubleOffset);
             doublesToCPDoubles.put(dbl, cpDouble);
@@ -560,7 +560,7 @@ public class CpBands extends BandSet {
 
     public CPNameAndType cpNameAndTypeValue(final int index) {
         final String descriptor = cpDescriptor[index];
-        CPNameAndType cpNameAndType = (CPNameAndType) descriptorsToCPNameAndTypes.get(descriptor);
+        CPNameAndType cpNameAndType = descriptorsToCPNameAndTypes.get(descriptor);
         if (cpNameAndType == null) {
             final int nameIndex = cpDescriptorNameInts[index];
             final int descriptorIndex = cpDescriptorTypeInts[index];
@@ -596,7 +596,7 @@ public class CpBands extends BandSet {
             globalIndex = index + signatureOffset;
         }
         final String string = cpSignature[index];
-        CPUTF8 cpUTF8 = (CPUTF8) stringsToCPUTF8.get(string);
+        CPUTF8 cpUTF8 = stringsToCPUTF8.get(string);
         if (cpUTF8 == null) {
             cpUTF8 = new CPUTF8(string, globalIndex);
             stringsToCPUTF8.put(string, cpUTF8);
@@ -605,9 +605,9 @@ public class CpBands extends BandSet {
     }
 
     public CPNameAndType cpNameAndTypeValue(final String descriptor) {
-        CPNameAndType cpNameAndType = (CPNameAndType) descriptorsToCPNameAndTypes.get(descriptor);
+        CPNameAndType cpNameAndType = descriptorsToCPNameAndTypes.get(descriptor);
         if (cpNameAndType == null) {
-            final Integer index = (Integer) mapDescriptor.get(descriptor);
+            final Integer index = mapDescriptor.get(descriptor);
             if (index != null) {
                 return cpNameAndTypeValue(index.intValue());
             }
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/IcBands.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/IcBands.java
index 76f43cd0..89a2a7ea 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/IcBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/IcBands.java
@@ -29,6 +29,7 @@ import org.apache.commons.compress.harmony.pack200.Codec;
 import org.apache.commons.compress.harmony.pack200.Pack200Exception;
 import org.apache.commons.compress.harmony.unpack200.bytecode.CPClass;
 import org.apache.commons.compress.harmony.unpack200.bytecode.ClassConstantPool;
+import org.apache.commons.compress.harmony.unpack200.bytecode.ClassFileEntry;
 import org.apache.commons.compress.harmony.unpack200.bytecode.ConstantPoolEntry;
 
 /**
@@ -42,8 +43,8 @@ public class IcBands extends BandSet {
 
     private final String[] cpClass;
 
-    private Map thisClassToTuple;
-    private Map outerClassToTuples;
+    private Map<String, IcTuple> thisClassToTuple;
+    private Map<String, List<IcTuple>> outerClassToTuples;
 
     /**
      * @param segment TODO
@@ -111,8 +112,8 @@ public class IcBands extends BandSet {
     @Override
     public void unpack() throws IOException, Pack200Exception {
         final IcTuple[] allTuples = getIcTuples();
-        thisClassToTuple = new HashMap(allTuples.length);
-        outerClassToTuples = new HashMap(allTuples.length);
+        thisClassToTuple = new HashMap<>(allTuples.length);
+        outerClassToTuples = new HashMap<>(allTuples.length);
         for (final IcTuple tuple : allTuples) {
 
             // generate mapping thisClassString -> IcTuple
@@ -132,9 +133,9 @@ public class IcBands extends BandSet {
 
                 // add tuple to corresponding bucket
                 final String key = tuple.outerClassString();
-                List bucket = (List) outerClassToTuples.get(key);
+                List<IcTuple> bucket = outerClassToTuples.get(key);
                 if (bucket == null) {
-                    bucket = new ArrayList();
+                    bucket = new ArrayList<>();
                     outerClassToTuples.put(key, bucket);
                 }
                 bucket.add(tuple);
@@ -154,19 +155,19 @@ public class IcBands extends BandSet {
      * @return array of IcTuple
      */
     public IcTuple[] getRelevantIcTuples(final String className, final ClassConstantPool cp) {
-        final Set relevantTuplesContains = new HashSet();
-        final List relevantTuples = new ArrayList();
+        final Set<IcTuple> relevantTuplesContains = new HashSet<>();
+        final List<IcTuple> relevantTuples = new ArrayList<>();
 
-        final List relevantCandidates = (List) outerClassToTuples.get(className);
+        final List<IcTuple> relevantCandidates = outerClassToTuples.get(className);
         if (relevantCandidates != null) {
             for (int index = 0; index < relevantCandidates.size(); index++) {
-                final IcTuple tuple = (IcTuple) relevantCandidates.get(index);
+                final IcTuple tuple = relevantCandidates.get(index);
                 relevantTuplesContains.add(tuple);
                 relevantTuples.add(tuple);
             }
         }
 
-        final List entries = cp.entries();
+        final List<ClassFileEntry> entries = cp.entries();
 
         // For every class constant in both ic_this_class and cp,
         // add it to ic_relevant. Repeat until no more
@@ -176,7 +177,7 @@ public class IcBands extends BandSet {
             final ConstantPoolEntry entry = (ConstantPoolEntry) entries.get(eIndex);
             if (entry instanceof CPClass) {
                 final CPClass clazz = (CPClass) entry;
-                final IcTuple relevant = (IcTuple) thisClassToTuple.get(clazz.name);
+                final IcTuple relevant = thisClassToTuple.get(clazz.name);
                 if (relevant != null && relevantTuplesContains.add(relevant)) {
                     relevantTuples.add(relevant);
                 }
@@ -189,15 +190,15 @@ public class IcBands extends BandSet {
         // added
         // as well.
 
-        final ArrayList tuplesToScan = new ArrayList(relevantTuples);
-        final ArrayList tuplesToAdd = new ArrayList();
+        final List<IcTuple> tuplesToScan = new ArrayList<>(relevantTuples);
+        final List<IcTuple> tuplesToAdd = new ArrayList<>();
 
         while (tuplesToScan.size() > 0) {
 
             tuplesToAdd.clear();
             for (int index = 0; index < tuplesToScan.size(); index++) {
-                final IcTuple aRelevantTuple = (IcTuple) tuplesToScan.get(index);
-                final IcTuple relevant = (IcTuple) thisClassToTuple.get(aRelevantTuple.outerClassString());
+                final IcTuple aRelevantTuple = tuplesToScan.get(index);
+                final IcTuple relevant = thisClassToTuple.get(aRelevantTuple.outerClassString());
                 if (relevant != null && !aRelevantTuple.outerIsAnonymous()) {
                     tuplesToAdd.add(relevant);
                 }
@@ -205,7 +206,7 @@ public class IcBands extends BandSet {
 
             tuplesToScan.clear();
             for (int index = 0; index < tuplesToAdd.size(); index++) {
-                final IcTuple tuple = (IcTuple) tuplesToAdd.get(index);
+                final IcTuple tuple = tuplesToAdd.get(index);
                 if (relevantTuplesContains.add(tuple)) {
                     relevantTuples.add(tuple);
                     tuplesToScan.add(tuple);
@@ -218,14 +219,14 @@ public class IcBands extends BandSet {
 
         // Now order the result as a subsequence of ic_all
         relevantTuples.sort((arg0, arg1) -> {
-            final Integer index1 = Integer.valueOf(((IcTuple) arg0).getTupleIndex());
-            final Integer index2 = Integer.valueOf(((IcTuple) arg1).getTupleIndex());
+            final Integer index1 = Integer.valueOf(arg0.getTupleIndex());
+            final Integer index2 = Integer.valueOf(arg1.getTupleIndex());
             return index1.compareTo(index2);
         });
 
         final IcTuple[] relevantTuplesArray = new IcTuple[relevantTuples.size()];
         for (int i = 0; i < relevantTuplesArray.length; i++) {
-            relevantTuplesArray[i] = (IcTuple) relevantTuples.get(i);
+            relevantTuplesArray[i] = relevantTuples.get(i);
         }
 
         return relevantTuplesArray;
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/IcTuple.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/IcTuple.java
index 83832b62..df6c0b65 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/IcTuple.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/IcTuple.java
@@ -17,6 +17,7 @@
 package org.apache.commons.compress.harmony.unpack200;
 
 import java.util.ArrayList;
+import java.util.List;
 
 /**
  * An IcTuple is the set of information that describes an inner class.
@@ -107,7 +108,7 @@ public class IcTuple {
      * @return TODO
      */
     public String[] innerBreakAtDollar(final String className) {
-        final ArrayList resultList = new ArrayList();
+        final List<String> resultList = new ArrayList<>();
         int start = 0;
         int index = 0;
         while (index < className.length()) {
@@ -123,7 +124,7 @@ public class IcTuple {
         }
         final String[] result = new String[resultList.size()];
         for (int i = 0; i < resultList.size(); i++) {
-            result[i] = (String) resultList.get(i);
+            result[i] = resultList.get(i);
         }
         return result;
     }
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/MetadataBandGroup.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/MetadataBandGroup.java
index aaac3446..0b2307a2 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/MetadataBandGroup.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/MetadataBandGroup.java
@@ -68,7 +68,7 @@ public class MetadataBandGroup {
         this.cpBands = cpBands;
     }
 
-    private List attributes;
+    private List<Attribute> attributes;
 
     public int[] param_NB;
     public int[] anno_N;
@@ -113,18 +113,18 @@ public class MetadataBandGroup {
 
     private int nestpair_N_Index;
 
-    private Iterator nestname_RU_Iterator;
+    private Iterator<CPUTF8> nestname_RU_Iterator;
 
     private int anno_N_Index;
 
     private int pair_N_Index;
 
-    public List getAttributes() {
+    public List<Attribute> getAttributes() {
         // TODO: Optimize iterators!
         if (attributes == null) {
-            attributes = new ArrayList();
+            attributes = new ArrayList<>();
             if (name_RU != null) {
-                final Iterator name_RU_Iterator = Arrays.asList(name_RU).iterator();
+                final Iterator<CPUTF8> name_RU_Iterator = Arrays.asList(name_RU).iterator();
                 if (!type.equals("AD")) {
                     T_index = 0;
                 }
@@ -161,7 +161,7 @@ public class MetadataBandGroup {
     }
 
     private Attribute getAttribute(final int numAnnotations, final CPUTF8[] types, final int[] pairCounts,
-        final Iterator namesIterator) {
+        final Iterator<CPUTF8> namesIterator) {
         final Annotation[] annotations = new Annotation[numAnnotations];
         for (int i = 0; i < numAnnotations; i++) {
             annotations[i] = getAnnotation(types[i], pairCounts[i], namesIterator);
@@ -169,7 +169,7 @@ public class MetadataBandGroup {
         return new RuntimeVisibleorInvisibleAnnotationsAttribute(type.equals("RVA") ? rvaUTF8 : riaUTF8, annotations);
     }
 
-    private Attribute getParameterAttribute(final int numParameters, final Iterator namesIterator) {
+    private Attribute getParameterAttribute(final int numParameters, final Iterator<CPUTF8> namesIterator) {
         final ParameterAnnotation[] parameter_annotations = new ParameterAnnotation[numParameters];
         for (int i = 0; i < numParameters; i++) {
             final int numAnnotations = anno_N[anno_N_Index++];
@@ -184,11 +184,11 @@ public class MetadataBandGroup {
             parameter_annotations);
     }
 
-    private Annotation getAnnotation(final CPUTF8 type, final int pairCount, final Iterator namesIterator) {
+    private Annotation getAnnotation(final CPUTF8 type, final int pairCount, final Iterator<CPUTF8> namesIterator) {
         final CPUTF8[] elementNames = new CPUTF8[pairCount];
         final ElementValue[] elementValues = new ElementValue[pairCount];
         for (int j = 0; j < elementNames.length; j++) {
-            elementNames[j] = (CPUTF8) namesIterator.next();
+            elementNames[j] = namesIterator.next();
             final int t = T[T_index++];
             elementValues[j] = new ElementValue(t, getNextValue(t));
         }
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/NewAttributeBands.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/NewAttributeBands.java
index f27a07ba..c4fa952e 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/NewAttributeBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/NewAttributeBands.java
@@ -49,7 +49,7 @@ public class NewAttributeBands extends BandSet {
 
     private int backwardsCallCount;
 
-    protected List attributeLayoutElements;
+    protected List<AttributeLayoutElement> attributeLayoutElements;
 
     public NewAttributeBands(final Segment segment, final AttributeLayout attributeLayout) throws IOException {
         super(segment);
@@ -78,13 +78,12 @@ public class NewAttributeBands extends BandSet {
      * @throws IOException If an I/O error occurs.
      * @throws Pack200Exception TODO
      */
-    public List parseAttributes(final InputStream in, final int occurrenceCount) throws IOException, Pack200Exception {
-        for (Object attributeLayoutElement : attributeLayoutElements) {
-            final AttributeLayoutElement element = (AttributeLayoutElement) attributeLayoutElement;
+    public List<Attribute> parseAttributes(final InputStream in, final int occurrenceCount) throws IOException, Pack200Exception {
+        for (AttributeLayoutElement element : attributeLayoutElements) {
             element.readBands(in, occurrenceCount);
         }
 
-        final List attributes = new ArrayList(occurrenceCount);
+        final List<Attribute> attributes = new ArrayList<>(occurrenceCount);
         for (int i = 0; i < occurrenceCount; i++) {
             attributes.add(getOneAttribute(i, attributeLayoutElements));
         }
@@ -98,11 +97,10 @@ public class NewAttributeBands extends BandSet {
      * @param elements TODO
      * @return attribute at the given index.
      */
-    private Attribute getOneAttribute(final int index, final List elements) {
+    private Attribute getOneAttribute(final int index, final List<AttributeLayoutElement> elements) {
         final NewAttribute attribute = new NewAttribute(segment.getCpBands().cpUTF8Value(attributeLayout.getName()),
             attributeLayout.getIndex());
-        for (Object element2 : elements) {
-            final AttributeLayoutElement element = (AttributeLayoutElement) element2;
+        for (AttributeLayoutElement element : elements) {
             element.addToAttribute(index, attribute);
         }
         return attribute;
@@ -115,7 +113,7 @@ public class NewAttributeBands extends BandSet {
      */
     private void parseLayout() throws IOException {
         if (attributeLayoutElements == null) {
-            attributeLayoutElements = new ArrayList();
+            attributeLayoutElements = new ArrayList<>();
             final StringReader stream = new StringReader(attributeLayout.getLayout());
             AttributeLayoutElement e;
             while ((e = readNextAttributeElement(stream)) != null) {
@@ -131,15 +129,14 @@ public class NewAttributeBands extends BandSet {
     private void resolveCalls() {
         int backwardsCalls = 0;
         for (int i = 0; i < attributeLayoutElements.size(); i++) {
-            final AttributeLayoutElement element = (AttributeLayoutElement) attributeLayoutElements.get(i);
+            final AttributeLayoutElement element = attributeLayoutElements.get(i);
             if (element instanceof Callable) {
                 final Callable callable = (Callable) element;
                 if (i == 0) {
                     callable.setFirstCallable(true);
                 }
-                final List body = callable.body; // Look for calls in the body
-                for (Object element2 : body) {
-                    final LayoutElement layoutElement = (LayoutElement) element2;
+                // Look for calls in the body
+                for (LayoutElement layoutElement : callable.body) {
                     // Set the callable for each call
                     backwardsCalls += resolveCallsForElement(i, callable, layoutElement);
                 }
@@ -158,7 +155,7 @@ public class NewAttributeBands extends BandSet {
                 call.setCallable(currentCallable);
             } else if (index > 0) { // Forwards call
                 for (int k = i + 1; k < attributeLayoutElements.size(); k++) {
-                    final AttributeLayoutElement el = (AttributeLayoutElement) attributeLayoutElements.get(k);
+                    final AttributeLayoutElement el = attributeLayoutElements.get(k);
                     if (el instanceof Callable) {
                         index--;
                         if (index == 0) {
@@ -170,7 +167,7 @@ public class NewAttributeBands extends BandSet {
             } else { // Backwards call
                 backwardsCalls++;
                 for (int k = i - 1; k >= 0; k--) {
-                    final AttributeLayoutElement el = (AttributeLayoutElement) attributeLayoutElements.get(k);
+                    final AttributeLayoutElement el = attributeLayoutElements.get(k);
                     if (el instanceof Callable) {
                         index++;
                         if (index == 0) {
@@ -181,10 +178,9 @@ public class NewAttributeBands extends BandSet {
                 }
             }
         } else if (layoutElement instanceof Replication) {
-            final List children = ((Replication) layoutElement).layoutElements;
-            for (Object child : children) {
-                final LayoutElement object = (LayoutElement) child;
-                backwardsCalls += resolveCallsForElement(i, currentCallable, object);
+            final List<LayoutElement> children = ((Replication) layoutElement).layoutElements;
+            for (LayoutElement child : children) {
+                backwardsCalls += resolveCallsForElement(i, currentCallable, child);
             }
         }
         return backwardsCalls;
@@ -246,7 +242,7 @@ public class NewAttributeBands extends BandSet {
             if (int_type.equals("S")) {
                 int_type += (char) stream.read();
             }
-            final List unionCases = new ArrayList();
+            final List<UnionCase> unionCases = new ArrayList<>();
             UnionCase c;
             while ((c = readNextUnionCase(stream)) != null) {
                 unionCases.add(c);
@@ -442,7 +438,7 @@ public class NewAttributeBands extends BandSet {
 
         private final Integral countElement;
 
-        private final List layoutElements = new ArrayList();
+        private final List<LayoutElement> layoutElements = new ArrayList<>();
 
         public Replication(final String tag, final String contents) throws IOException {
             this.countElement = new Integral(tag);
@@ -489,7 +485,7 @@ public class NewAttributeBands extends BandSet {
             return countElement;
         }
 
-        public List getLayoutElements() {
+        public List<LayoutElement> getLayoutElements() {
             return layoutElements;
         }
     }
@@ -500,12 +496,12 @@ public class NewAttributeBands extends BandSet {
     public class Union extends LayoutElement {
 
         private final Integral unionTag;
-        private final List unionCases;
+        private final List<UnionCase> unionCases;
         private final List<LayoutElement> defaultCaseBody;
         private int[] caseCounts;
         private int defaultCount;
 
-        public Union(final String tag, final List unionCases, final List<LayoutElement> body) {
+        public Union(final String tag, final List<UnionCase> unionCases, final List<LayoutElement> body) {
             this.unionTag = new Integral(tag);
             this.unionCases = unionCases;
             this.defaultCaseBody = body;
@@ -518,7 +514,7 @@ public class NewAttributeBands extends BandSet {
             // Count the band size for each union case then read the bands
             caseCounts = new int[unionCases.size()];
             for (int i = 0; i < caseCounts.length; i++) {
-                final UnionCase unionCase = (UnionCase) unionCases.get(i);
+                final UnionCase unionCase = unionCases.get(i);
                 for (int value : values) {
                     if (unionCase.hasTag(value)) {
                         caseCounts[i]++;
@@ -592,7 +588,7 @@ public class NewAttributeBands extends BandSet {
             return unionTag;
         }
 
-        public List getUnionCases() {
+        public List<UnionCase> getUnionCases() {
             return unionCases;
         }
 
@@ -799,7 +795,7 @@ public class NewAttributeBands extends BandSet {
             this.isFirstCallable = isFirstCallable;
         }
 
-        public List getBody() {
+        public List<LayoutElement> getBody() {
             return body;
         }
     }
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/Segment.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/Segment.java
index f6091f56..6564cc21 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/Segment.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/Segment.java
@@ -126,10 +126,10 @@ public class Segment {
         // == str
 
         // Get the source file attribute
-        final ArrayList classAttributes = classBands.getClassAttributes()[classNum];
+        final List<Attribute> classAttributes = classBands.getClassAttributes()[classNum];
         SourceFileAttribute sourceFileAttribute = null;
-        for (Object classAttribute : classAttributes) {
-            if (((Attribute) classAttribute).isSourceFileAttribute()) {
+        for (Attribute classAttribute : classAttributes) {
+            if (classAttribute.isSourceFileAttribute()) {
                 sourceFileAttribute = ((SourceFileAttribute) classAttribute);
             }
         }
@@ -166,9 +166,9 @@ public class Segment {
         // that will
         // be written out. Keep SourceFileAttributes out since we just
         // did them above.
-        final ArrayList classAttributesWithoutSourceFileAttribute = new ArrayList(classAttributes.size());
+        final List<Attribute> classAttributesWithoutSourceFileAttribute = new ArrayList<>(classAttributes.size());
         for (int index = 0; index < classAttributes.size(); index++) {
-            final Attribute attrib = (Attribute) classAttributes.get(index);
+            final Attribute attrib = classAttributes.get(index);
             if (!attrib.isSourceFileAttribute()) {
                 classAttributesWithoutSourceFileAttribute.add(attrib);
             }
@@ -178,7 +178,7 @@ public class Segment {
             + classAttributesWithoutSourceFileAttribute.size()];
         System.arraycopy(originalAttributes, 0, classFile.attributes, 0, originalAttributes.length);
         for (int index = 0; index < classAttributesWithoutSourceFileAttribute.size(); index++) {
-            final Attribute attrib = ((Attribute) classAttributesWithoutSourceFileAttribute.get(index));
+            final Attribute attrib = (classAttributesWithoutSourceFileAttribute.get(index));
             cp.add(attrib);
             classFile.attributes[originalAttributes.length + index] = attrib;
         }
@@ -223,9 +223,8 @@ public class Segment {
         final boolean ic_local_sent = ic_local != null;
         final InnerClassesAttribute innerClassesAttribute = new InnerClassesAttribute("InnerClasses");
         final IcTuple[] ic_relevant = getIcBands().getRelevantIcTuples(fullName, cp);
-        final List ic_stored = computeIcStored(ic_local, ic_relevant);
-        for (Object element : ic_stored) {
-            final IcTuple icStored = (IcTuple) element;
+        final List<IcTuple> ic_stored = computeIcStored(ic_local, ic_relevant);
+        for (IcTuple icStored : ic_stored) {
             final int innerClassIndex = icStored.thisClassIndex();
             final int outerClassIndex = icStored.outerClassIndex();
             final int simpleClassNameIndex = icStored.simpleClassNameIndex();
@@ -300,10 +299,10 @@ public class Segment {
      * @return List of tuples to be stored. If ic_local is null or empty, the values returned may not be correct. The
      *         caller will have to determine if this is the case.
      */
-    private List computeIcStored(final IcTuple[] ic_local, final IcTuple[] ic_relevant) {
-        final List result = new ArrayList(ic_relevant.length);
-        final List duplicates = new ArrayList(ic_relevant.length);
-        final Set isInResult = new HashSet(ic_relevant.length);
+    private List<IcTuple> computeIcStored(final IcTuple[] ic_local, final IcTuple[] ic_relevant) {
+        final List<IcTuple> result = new ArrayList<>(ic_relevant.length);
+        final List<IcTuple> duplicates = new ArrayList<>(ic_relevant.length);
+        final Set<IcTuple> isInResult = new HashSet<>(ic_relevant.length);
 
         // need to compute:
         // result = ic_local XOR ic_relevant
@@ -328,7 +327,7 @@ public class Segment {
 
         // eliminate "duplicates"
         for (int index = 0; index < duplicates.size(); index++) {
-            final IcTuple tuple = (IcTuple) duplicates.get(index);
+            final IcTuple tuple = duplicates.get(index);
             result.remove(tuple);
         }
 
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java
index 8e1e9d59..faadb980 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java
@@ -204,7 +204,7 @@ public class SegmentConstantPool {
     protected int matchSpecificPoolEntryIndex(final String[] primaryArray, final String[] secondaryArray,
         final String primaryCompareString, final String secondaryCompareRegex, final int desiredIndex) {
         int instanceCount = -1;
-        final List indexList = arrayCache.indexesForArrayKey(primaryArray, primaryCompareString);
+        final List<Integer> indexList = arrayCache.indexesForArrayKey(primaryArray, primaryCompareString);
         if (indexList.isEmpty()) {
             // Primary key not found, no chance of finding secondary
             return -1;
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPoolArrayCache.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPoolArrayCache.java
index 2f6a7f06..d5570da5 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPoolArrayCache.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPoolArrayCache.java
@@ -34,9 +34,9 @@ import java.util.List;
  */
 public class SegmentConstantPoolArrayCache {
 
-    protected IdentityHashMap knownArrays = new IdentityHashMap(1000);
+    protected IdentityHashMap<String[], CachedArray> knownArrays = new IdentityHashMap<>(1000);
 
-    protected List lastIndexes;
+    protected List<Integer> lastIndexes;
     protected String[] lastArray;
     protected String lastKey;
 
@@ -47,7 +47,7 @@ public class SegmentConstantPoolArrayCache {
      * @param key String value for which to search
      * @return List collection of index positions in the array
      */
-    public List indexesForArrayKey(final String[] array, final String key) {
+    public List<Integer> indexesForArrayKey(final String[] array, final String key) {
         if (!arrayIsCached(array)) {
             cacheArray(array);
         }
@@ -65,7 +65,7 @@ public class SegmentConstantPoolArrayCache {
         // Remember the last thing we found.
         lastArray = array;
         lastKey = key;
-        lastIndexes = ((CachedArray) knownArrays.get(array)).indexesForKey(key);
+        lastIndexes = knownArrays.get(array).indexesForKey(key);
 
         return lastIndexes;
     }
@@ -81,7 +81,7 @@ public class SegmentConstantPoolArrayCache {
         if (!knownArrays.containsKey(array)) {
             return false;
         }
-        final CachedArray cachedArray = (CachedArray) knownArrays.get(array);
+        final CachedArray cachedArray = knownArrays.get(array);
         if (cachedArray.lastKnownSize() != array.length) {
             return false;
         }
@@ -109,13 +109,13 @@ public class SegmentConstantPoolArrayCache {
     protected class CachedArray {
         String[] primaryArray;
         int lastKnownSize;
-        HashMap primaryTable;
+        HashMap<String, List<Integer>> primaryTable;
 
         public CachedArray(final String[] array) {
             super();
             this.primaryArray = array;
             this.lastKnownSize = array.length;
-            this.primaryTable = new HashMap(lastKnownSize);
+            this.primaryTable = new HashMap<>(lastKnownSize);
             cacheIndexes();
         }
 
@@ -137,11 +137,11 @@ public class SegmentConstantPoolArrayCache {
          * @param key String element of the array
          * @return List of indexes containing that key in the array.
          */
-        public List indexesForKey(final String key) {
+        public List<Integer> indexesForKey(final String key) {
             if (!primaryTable.containsKey(key)) {
                 return Collections.EMPTY_LIST;
             }
-            return (List) primaryTable.get(key);
+            return primaryTable.get(key);
         }
 
         /**
@@ -153,9 +153,9 @@ public class SegmentConstantPoolArrayCache {
             for (int index = 0; index < primaryArray.length; index++) {
                 final String key = primaryArray[index];
                 if (!primaryTable.containsKey(key)) {
-                    primaryTable.put(key, new ArrayList());
+                    primaryTable.put(key, new ArrayList<>());
                 }
-                ((ArrayList) primaryTable.get(key)).add(Integer.valueOf(index));
+                primaryTable.get(key).add(Integer.valueOf(index));
             }
         }
     }
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/AnnotationDefaultAttribute.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/AnnotationDefaultAttribute.java
index 104dabf5..b5f6a35f 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/AnnotationDefaultAttribute.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/AnnotationDefaultAttribute.java
@@ -67,7 +67,7 @@ public class AnnotationDefaultAttribute extends AnnotationsAttribute {
 
     @Override
     protected ClassFileEntry[] getNestedClassFileEntries() {
-        final List nested = new ArrayList();
+        final List<Object> nested = new ArrayList<>();
         nested.add(attributeName);
         nested.addAll(element_value.getClassFileEntries());
         final ClassFileEntry[] nestedEntries = new ClassFileEntry[nested.size()];
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/AnnotationsAttribute.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/AnnotationsAttribute.java
index 2cac234a..6dede86a 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/AnnotationsAttribute.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/AnnotationsAttribute.java
@@ -77,8 +77,8 @@ public abstract class AnnotationsAttribute extends Attribute {
             }
         }
 
-        public List getClassFileEntries() {
-            final List entries = new ArrayList();
+        public List<Object> getClassFileEntries() {
+            final List<Object> entries = new ArrayList<>();
             for (int i = 0; i < element_names.length; i++) {
                 entries.add(element_names[i]);
                 entries.addAll(element_values[i].getClassFileEntries());
@@ -101,13 +101,14 @@ public abstract class AnnotationsAttribute extends Attribute {
             this.value = value;
         }
 
-        public List getClassFileEntries() {
-            final List entries = new ArrayList(1);
+        public List<Object> getClassFileEntries() {
+            final List<Object> entries = new ArrayList<>(1);
             if (value instanceof CPNameAndType) {
                 // used to represent enum, so don't include the actual CPNameAndType
                 entries.add(((CPNameAndType) value).name);
                 entries.add(((CPNameAndType) value).descriptor);
             } else if (value instanceof ClassFileEntry) {
+            	// TODO? ClassFileEntry is an Object
                 entries.add(value);
             } else if (value instanceof ElementValue[]) {
                 final ElementValue[] values = (ElementValue[]) value;
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/BCIRenumberedAttribute.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/BCIRenumberedAttribute.java
index b3840c9d..14941724 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/BCIRenumberedAttribute.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/BCIRenumberedAttribute.java
@@ -62,14 +62,14 @@ public abstract class BCIRenumberedAttribute extends Attribute {
      * @param byteCodeOffsets List of Integer offsets of the bytecode array
      * @throws Pack200Exception TODO
      */
-    public void renumber(final List byteCodeOffsets) throws Pack200Exception {
+    public void renumber(final List<Integer> byteCodeOffsets) throws Pack200Exception {
         if (renumbered) {
             throw new Error("Trying to renumber a line number table that has already been renumbered");
         }
         renumbered = true;
         final int[] startPCs = getStartPCs();
         for (int index = 0; index < startPCs.length; index++) {
-            startPCs[index] = ((Integer) byteCodeOffsets.get(startPCs[index])).intValue();
+            startPCs[index] = byteCodeOffsets.get(startPCs[index]).intValue();
         }
     }
 
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPField.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPField.java
index ef11423a..5d25fa0c 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPField.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPField.java
@@ -23,7 +23,7 @@ import java.util.List;
  */
 public class CPField extends CPMember {
 
-    public CPField(final CPUTF8 name, final CPUTF8 descriptor, final long flags, final List attributes) {
+    public CPField(final CPUTF8 name, final CPUTF8 descriptor, final long flags, final List<Attribute> attributes) {
         super(name, descriptor, flags, attributes);
     }
 
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMember.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMember.java
index f05610d6..64616067 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMember.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMember.java
@@ -27,7 +27,7 @@ import java.util.Objects;
  */
 public class CPMember extends ClassFileEntry {
 
-    List attributes;
+    List<Attribute> attributes;
     short flags;
     CPUTF8 name;
     transient int nameIndex;
@@ -43,7 +43,7 @@ public class CPMember extends ClassFileEntry {
      * @param attributes TODO
      * @throws NullPointerException if name or descriptor is null
      */
-    public CPMember(final CPUTF8 name, final CPUTF8 descriptor, final long flags, final List attributes) {
+    public CPMember(final CPUTF8 name, final CPUTF8 descriptor, final long flags, final List<Attribute> attributes) {
         this.name = Objects.requireNonNull(name, "name");
         this.descriptor = Objects.requireNonNull(descriptor, "descriptor");
         this.flags = (short) flags;
@@ -57,7 +57,7 @@ public class CPMember extends ClassFileEntry {
         entries[0] = name;
         entries[1] = descriptor;
         for (int i = 0; i < attributeCount; i++) {
-            entries[i + 2] = (Attribute) attributes.get(i);
+            entries[i + 2] = attributes.get(i);
         }
         return entries;
     }
@@ -124,7 +124,7 @@ public class CPMember extends ClassFileEntry {
         final int attributeCount = attributes.size();
         dos.writeShort(attributeCount);
         for (int i = 0; i < attributeCount; i++) {
-            final Attribute attribute = (Attribute) attributes.get(i);
+            final Attribute attribute = attributes.get(i);
             attribute.doWrite(dos);
         }
     }
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMethod.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMethod.java
index 3e0bbb45..f33f4686 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMethod.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMethod.java
@@ -23,7 +23,7 @@ import java.util.List;
  */
 public class CPMethod extends CPMember {
 
-    public CPMethod(final CPUTF8 name, final CPUTF8 descriptor, final long flags, final List attributes) {
+    public CPMethod(final CPUTF8 name, final CPUTF8 descriptor, final long flags, final List<Attribute> attributes) {
         super(name, descriptor, flags, attributes);
     }
 
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ClassConstantPool.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ClassConstantPool.java
index 2954da7c..9b43ce85 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ClassConstantPool.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ClassConstantPool.java
@@ -33,15 +33,15 @@ import org.apache.commons.compress.harmony.unpack200.Segment;
  */
 public class ClassConstantPool {
 
-    protected HashSet entriesContainsSet = new HashSet();
-    protected HashSet othersContainsSet = new HashSet();
+    protected HashSet<ClassFileEntry> entriesContainsSet = new HashSet<>();
+    protected HashSet<ClassFileEntry> othersContainsSet = new HashSet<>();
 
-    private final HashSet mustStartClassPool = new HashSet();
+    private final HashSet<ClassFileEntry> mustStartClassPool = new HashSet<>();
 
-    protected Map indexCache;
+    protected Map<ClassFileEntry, Integer> indexCache;
 
-    private final List others = new ArrayList(500);
-    private final List entries = new ArrayList(500);
+    private final List<ClassFileEntry> others = new ArrayList<>(500);
+    private final List<ClassFileEntry> entries = new ArrayList<>(500);
 
     private boolean resolved;
 
@@ -64,8 +64,8 @@ public class ClassConstantPool {
         boolean added = true;
 
         // initial assignment
-        final ArrayList parents = new ArrayList(512);
-        final ArrayList children = new ArrayList(512);
+        final List<ClassFileEntry> parents = new ArrayList<>(512);
+        final List<ClassFileEntry> children = new ArrayList<>(512);
 
         // adding old entries
         parents.addAll(entries);
@@ -83,7 +83,7 @@ public class ClassConstantPool {
             // get the parents' children and add them to buffer
             // concurrently add parents to target storage
             for (int indexParents = 0; indexParents < parents.size(); indexParents++) {
-                final ClassFileEntry entry = (ClassFileEntry) parents.get(indexParents);
+                final ClassFileEntry entry = parents.get(indexParents);
 
                 // traverse children
                 final ClassFileEntry[] entryChildren = entry.getNestedClassFileEntries();
@@ -115,7 +115,7 @@ public class ClassConstantPool {
         if (null == indexCache) {
             throw new IllegalStateException("Index cache is not initialized!");
         }
-        final Integer entryIndex = ((Integer) indexCache.get(entry));
+        final Integer entryIndex = (indexCache.get(entry));
         // If the entry isn't found, answer -1. Otherwise answer the entry.
         if (entryIndex != null) {
             return entryIndex.intValue() + 1;
@@ -131,7 +131,7 @@ public class ClassConstantPool {
         if (!resolved) {
             throw new IllegalStateException("Constant pool is not yet resolved; this does not make any sense");
         }
-        return (ClassFileEntry) entries.get(--i);
+        return entries.get(--i);
     }
 
     public void resolve(final Segment segment) {
@@ -140,27 +140,25 @@ public class ClassConstantPool {
 
         resolved = true;
 
-        for (Object entry2 : entries) {
-            final ClassFileEntry entry = (ClassFileEntry) entry2;
+        for (ClassFileEntry entry : entries) {
             entry.resolve(this);
         }
 
-        for (Object other : others) {
-            final ClassFileEntry entry = (ClassFileEntry) other;
-            entry.resolve(this);
+        for (ClassFileEntry other : others) {
+            other.resolve(this);
         }
 
     }
 
     private void initialSort() {
-        final TreeSet inCpAll = new TreeSet(
+        final TreeSet<ClassFileEntry> inCpAll = new TreeSet<>(
                 Comparator.comparingInt(arg0 -> ((ConstantPoolEntry) arg0).getGlobalIndex()));
-        final TreeSet cpUtf8sNotInCpAll = new TreeSet(
+        final TreeSet<ClassFileEntry> cpUtf8sNotInCpAll = new TreeSet<>(
                 Comparator.comparing(arg0 -> ((CPUTF8) arg0).underlyingString()));
-        final TreeSet cpClassesNotInCpAll = new TreeSet(
+        final TreeSet<ClassFileEntry> cpClassesNotInCpAll = new TreeSet<>(
                 Comparator.comparing(arg0 -> ((CPClass) arg0).getName()));
 
-        for (Object entry2 : entries) {
+        for (ClassFileEntry entry2 : entries) {
             final ConstantPoolEntry entry = (ConstantPoolEntry) entry2;
             if (entry.getGlobalIndex() == -1) {
                 if (entry instanceof CPUTF8) {
@@ -180,7 +178,7 @@ public class ClassConstantPool {
         entries.addAll(cpClassesNotInCpAll);
     }
 
-    public List entries() {
+    public List<ClassFileEntry> entries() {
         return Collections.unmodifiableList(entries);
     }
 
@@ -190,21 +188,20 @@ public class ClassConstantPool {
         // references to objects which need to be at the
         // start of the class pool
 
-        final ArrayList startOfPool = new ArrayList(entries.size());
-        final ArrayList finalSort = new ArrayList(entries.size());
+        final List<ClassFileEntry> startOfPool = new ArrayList<>(entries.size());
+        final List<ClassFileEntry> finalSort = new ArrayList<>(entries.size());
 
-        for (Object entry : entries) {
-            final ClassFileEntry nextEntry = (ClassFileEntry) entry;
-            if (mustStartClassPool.contains(nextEntry)) {
-                startOfPool.add(nextEntry);
+        for (ClassFileEntry entry : entries) {
+            if (mustStartClassPool.contains(entry)) {
+                startOfPool.add(entry);
             } else {
-                finalSort.add(nextEntry);
+                finalSort.add(entry);
             }
         }
 
         // copy over and rebuild the cache
         //
-        indexCache = new HashMap(entries.size());
+        indexCache = new HashMap<>(entries.size());
         int index = 0;
 
         entries.clear();
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CodeAttribute.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CodeAttribute.java
index 34b412d6..72be6986 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CodeAttribute.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CodeAttribute.java
@@ -25,18 +25,18 @@ import org.apache.commons.compress.harmony.unpack200.Segment;
 
 public class CodeAttribute extends BCIRenumberedAttribute {
 
-    public List attributes = new ArrayList();
+    public List<Attribute> attributes = new ArrayList<>();
     // instances
-    public List byteCodeOffsets = new ArrayList();
-    public List byteCodes = new ArrayList();
+    public List<Integer> byteCodeOffsets = new ArrayList<>();
+    public List<ByteCode> byteCodes = new ArrayList<>();
     public int codeLength;
-    public List exceptionTable; // of ExceptionTableEntry
+    public List<ExceptionTableEntry> exceptionTable;
     public int maxLocals;
     public int maxStack;
     private static CPUTF8 attributeName;
 
     public CodeAttribute(final int maxStack, final int maxLocals, final byte[] codePacked, final Segment segment,
-        final OperandManager operandManager, final List exceptionTable) {
+        final OperandManager operandManager, final List<ExceptionTableEntry> exceptionTable) {
         super(attributeName);
         this.maxLocals = maxLocals;
         this.maxStack = maxStack;
@@ -53,7 +53,7 @@ public class CodeAttribute extends BCIRenumberedAttribute {
             byteCode.extractOperands(operandManager, segment, codeLength);
             byteCodes.add(byteCode);
             codeLength += byteCode.getLength();
-            final int lastBytecodePosition = ((Integer) byteCodeOffsets.get(byteCodeOffsets.size() - 1)).intValue();
+            final int lastBytecodePosition = byteCodeOffsets.get(byteCodeOffsets.size() - 1).intValue();
             // This code assumes all multiple byte bytecodes are
             // replaced by a single-byte bytecode followed by
             // another bytecode.
@@ -78,8 +78,7 @@ public class CodeAttribute extends BCIRenumberedAttribute {
         // sizes, fix up the byte code targets
         // At this point, byteCodes may be a different size than
         // codePacked because of wide bytecodes.
-        for (Object byteCode2 : byteCodes) {
-            final ByteCode byteCode = (ByteCode) byteCode2;
+        for (ByteCode byteCode : byteCodes) {
             byteCode.applyByteCodeTargetFixup(this);
         }
     }
@@ -96,13 +95,12 @@ public class CodeAttribute extends BCIRenumberedAttribute {
 
     @Override
     protected ClassFileEntry[] getNestedClassFileEntries() {
-        final ArrayList nestedEntries = new ArrayList(attributes.size() + byteCodes.size() + 10);
+        final List<ClassFileEntry> nestedEntries = new ArrayList<>(attributes.size() + byteCodes.size() + 10);
         nestedEntries.add(getAttributeName());
         nestedEntries.addAll(byteCodes);
         nestedEntries.addAll(attributes);
         // Don't forget to add the ExceptionTable catch_types
-        for (Object element : exceptionTable) {
-            final ExceptionTableEntry entry = (ExceptionTableEntry) element;
+        for (ExceptionTableEntry entry : exceptionTable) {
             final CPClass catchType = entry.getCatchType();
             // If the catch type is null, this is a finally
             // block. If it's not null, we need to add the
@@ -146,8 +144,7 @@ public class CodeAttribute extends BCIRenumberedAttribute {
         dos.writeShort(maxLocals);
 
         dos.writeInt(codeLength);
-        for (Object byteCode2 : byteCodes) {
-            final ByteCode byteCode = (ByteCode) byteCode2;
+        for (ByteCode byteCode : byteCodes) {
             byteCode.write(dos);
         }
 
@@ -181,9 +178,8 @@ public class CodeAttribute extends BCIRenumberedAttribute {
     }
 
     @Override
-    public void renumber(final List byteCodeOffsets) {
-        for (Object element : exceptionTable) {
-            final ExceptionTableEntry entry = (ExceptionTableEntry) element;
+    public void renumber(final List<Integer> byteCodeOffsets) {
+        for (ExceptionTableEntry entry : exceptionTable) {
             entry.renumber(byteCodeOffsets);
         }
     }
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ExceptionTableEntry.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ExceptionTableEntry.java
index 01c1d446..f28b2922 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ExceptionTableEntry.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ExceptionTableEntry.java
@@ -61,12 +61,12 @@ public class ExceptionTableEntry {
         dos.writeShort(catchTypeIndex);
     }
 
-    public void renumber(final List byteCodeOffsets) {
-        startPcRenumbered = ((Integer) byteCodeOffsets.get(startPC)).intValue();
+    public void renumber(final List<Integer> byteCodeOffsets) {
+        startPcRenumbered = byteCodeOffsets.get(startPC).intValue();
         final int endPcIndex = startPC + endPC;
-        endPcRenumbered = ((Integer) byteCodeOffsets.get(endPcIndex)).intValue();
+        endPcRenumbered = byteCodeOffsets.get(endPcIndex).intValue();
         final int handlerPcIndex = endPcIndex + handlerPC;
-        handlerPcRenumbered = ((Integer) byteCodeOffsets.get(handlerPcIndex)).intValue();
+        handlerPcRenumbered = byteCodeOffsets.get(handlerPcIndex).intValue();
     }
 
     public CPClass getCatchType() {
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/InnerClassesAttribute.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/InnerClassesAttribute.java
index ba4b565f..358a3944 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/InnerClassesAttribute.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/InnerClassesAttribute.java
@@ -88,8 +88,8 @@ public class InnerClassesAttribute extends Attribute {
 
     }
 
-    private final List innerClasses = new ArrayList();
-    private final List nestedClassFileEntries = new ArrayList();
+    private final List<InnerClassesEntry> innerClasses = new ArrayList<>();
+    private final List<ConstantPoolEntry> nestedClassFileEntries = new ArrayList<>();
 
     public InnerClassesAttribute(final String name) {
         super(attributeName);
@@ -127,7 +127,7 @@ public class InnerClassesAttribute extends Attribute {
     protected ClassFileEntry[] getNestedClassFileEntries() {
         final ClassFileEntry[] result = new ClassFileEntry[nestedClassFileEntries.size()];
         for (int index = 0; index < result.length; index++) {
-            result[index] = (ClassFileEntry) nestedClassFileEntries.get(index);
+            result[index] = nestedClassFileEntries.get(index);
         }
         return result;
     }
@@ -143,8 +143,7 @@ public class InnerClassesAttribute extends Attribute {
     @Override
     protected void resolve(final ClassConstantPool pool) {
         super.resolve(pool);
-        for (Object element : innerClasses) {
-            final InnerClassesEntry entry = (InnerClassesEntry) element;
+        for (InnerClassesEntry entry : innerClasses) {
             entry.resolve(pool);
         }
     }
@@ -164,8 +163,7 @@ public class InnerClassesAttribute extends Attribute {
     protected void writeBody(final DataOutputStream dos) throws IOException {
         dos.writeShort(innerClasses.size());
 
-        for (Object element : innerClasses) {
-            final InnerClassesEntry entry = (InnerClassesEntry) element;
+        for (InnerClassesEntry entry : innerClasses) {
             entry.write(dos);
         }
     }
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/LocalVariableTableAttribute.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/LocalVariableTableAttribute.java
index 8de1ea3f..0c9c48a5 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/LocalVariableTableAttribute.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/LocalVariableTableAttribute.java
@@ -77,7 +77,7 @@ public class LocalVariableTableAttribute extends BCIRenumberedAttribute {
 
     @Override
     protected ClassFileEntry[] getNestedClassFileEntries() {
-        final ArrayList nestedEntries = new ArrayList();
+        final List<CPUTF8> nestedEntries = new ArrayList<>();
         nestedEntries.add(getAttributeName());
         for (int i = 0; i < local_variable_table_length; i++) {
             nestedEntries.add(names[i]);
@@ -117,7 +117,7 @@ public class LocalVariableTableAttribute extends BCIRenumberedAttribute {
      * @see org.apache.commons.compress.harmony.unpack200.bytecode.BCIRenumberedAttribute#renumber(java.util.List)
      */
     @Override
-    public void renumber(final List byteCodeOffsets) throws Pack200Exception {
+    public void renumber(final List<Integer> byteCodeOffsets) throws Pack200Exception {
         // Remember the unrenumbered start_pcs, since that's used later
         // to calculate end position.
         final int[] unrenumbered_start_pcs = new int[start_pcs.length];
@@ -159,7 +159,7 @@ public class LocalVariableTableAttribute extends BCIRenumberedAttribute {
                 revisedLength = maxSize - start_pc;
             } else {
                 // We're indexed into the byte code array
-                final int stopValue = ((Integer) byteCodeOffsets.get(stopIndex)).intValue();
+                final int stopValue = byteCodeOffsets.get(stopIndex).intValue();
                 revisedLength = stopValue - start_pc;
             }
             lengths[index] = revisedLength;
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/LocalVariableTypeTableAttribute.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/LocalVariableTypeTableAttribute.java
index 2912f90a..514eb143 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/LocalVariableTypeTableAttribute.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/LocalVariableTypeTableAttribute.java
@@ -90,7 +90,7 @@ public class LocalVariableTypeTableAttribute extends BCIRenumberedAttribute {
 
     @Override
     protected ClassFileEntry[] getNestedClassFileEntries() {
-        final ArrayList nestedEntries = new ArrayList();
+        final List<CPUTF8> nestedEntries = new ArrayList<>();
         nestedEntries.add(getAttributeName());
         for (int i = 0; i < local_variable_type_table_length; i++) {
             nestedEntries.add(names[i]);
@@ -112,7 +112,7 @@ public class LocalVariableTypeTableAttribute extends BCIRenumberedAttribute {
      * @see org.apache.commons.compress.harmony.unpack200.bytecode.BCIRenumberedAttribute#renumber(java.util.List)
      */
     @Override
-    public void renumber(final List byteCodeOffsets) throws Pack200Exception {
+    public void renumber(final List<Integer> byteCodeOffsets) throws Pack200Exception {
         // Remember the unrenumbered start_pcs, since that's used later
         // to calculate end position.
         final int[] unrenumbered_start_pcs = new int[start_pcs.length];
@@ -154,7 +154,7 @@ public class LocalVariableTypeTableAttribute extends BCIRenumberedAttribute {
                 revisedLength = maxSize - start_pc;
             } else {
                 // We're indexed into the byte code array
-                final int stopValue = ((Integer) byteCodeOffsets.get(stopIndex)).intValue();
+                final int stopValue = byteCodeOffsets.get(stopIndex).intValue();
                 revisedLength = stopValue - start_pc;
             }
             lengths[index] = revisedLength;
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/NewAttribute.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/NewAttribute.java
index a1e25abe..1b3220eb 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/NewAttribute.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/NewAttribute.java
@@ -26,8 +26,8 @@ import java.util.List;
  */
 public class NewAttribute extends BCIRenumberedAttribute {
 
-    private final List lengths = new ArrayList(); // List of Integers
-    private final List body = new ArrayList();
+    private final List<Integer> lengths = new ArrayList<>();
+    private final List<Object> body = new ArrayList<>();
     private ClassConstantPool pool;
     private final int layoutIndex;
 
@@ -48,8 +48,8 @@ public class NewAttribute extends BCIRenumberedAttribute {
     @Override
     protected int getLength() {
         int length = 0;
-        for (Object length2 : lengths) {
-            length += ((Integer) length2).intValue();
+        for (Integer len : lengths) {
+            length += len.intValue();
         }
         return length;
     }
@@ -62,7 +62,7 @@ public class NewAttribute extends BCIRenumberedAttribute {
     @Override
     protected void writeBody(final DataOutputStream dos) throws IOException {
         for (int i = 0; i < lengths.size(); i++) {
-            final int length = ((Integer) lengths.get(i)).intValue();
+            final int length = lengths.get(i).intValue();
             final Object obj = body.get(i);
             long value = 0;
             if (obj instanceof Long) {
@@ -202,33 +202,33 @@ public class NewAttribute extends BCIRenumberedAttribute {
     }
 
     @Override
-    public void renumber(final List byteCodeOffsets) {
+    public void renumber(final List<Integer> byteCodeOffsets) {
         if (!renumbered) {
             Object previous = null;
             for (Object obj : body) {
                 if (obj instanceof BCIndex) {
                     final BCIndex bcIndex = (BCIndex) obj;
-                    bcIndex.setActualValue(((Integer) byteCodeOffsets.get(bcIndex.index)).intValue());
+                    bcIndex.setActualValue(byteCodeOffsets.get(bcIndex.index).intValue());
                 } else if (obj instanceof BCOffset) {
                     final BCOffset bcOffset = (BCOffset) obj;
                     if (previous instanceof BCIndex) {
                         final int index = ((BCIndex) previous).index + bcOffset.offset;
                         bcOffset.setIndex(index);
-                        bcOffset.setActualValue(((Integer) byteCodeOffsets.get(index)).intValue());
+                        bcOffset.setActualValue(byteCodeOffsets.get(index).intValue());
                     } else if (previous instanceof BCOffset) {
                         final int index = ((BCOffset) previous).index + bcOffset.offset;
                         bcOffset.setIndex(index);
-                        bcOffset.setActualValue(((Integer) byteCodeOffsets.get(index)).intValue());
+                        bcOffset.setActualValue(byteCodeOffsets.get(index).intValue());
                     } else {
                         // Not sure if this should be able to happen
-                        bcOffset.setActualValue(((Integer) byteCodeOffsets.get(bcOffset.offset)).intValue());
+                        bcOffset.setActualValue(byteCodeOffsets.get(bcOffset.offset).intValue());
                     }
                 } else if (obj instanceof BCLength) {
                     // previous must be a BCIndex
                     final BCLength bcLength = (BCLength) obj;
                     final BCIndex prevIndex = (BCIndex) previous;
                     final int index = prevIndex.index + bcLength.length;
-                    final int actualLength = ((Integer) byteCodeOffsets.get(index)).intValue() - prevIndex.actualValue;
+                    final int actualLength = byteCodeOffsets.get(index).intValue() - prevIndex.actualValue;
                     bcLength.setActualValue(actualLength);
                 }
                 previous = obj;
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/RuntimeVisibleorInvisibleAnnotationsAttribute.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/RuntimeVisibleorInvisibleAnnotationsAttribute.java
index 18f50c42..4612d451 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/RuntimeVisibleorInvisibleAnnotationsAttribute.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/RuntimeVisibleorInvisibleAnnotationsAttribute.java
@@ -72,7 +72,7 @@ public class RuntimeVisibleorInvisibleAnnotationsAttribute extends AnnotationsAt
 
     @Override
     protected ClassFileEntry[] getNestedClassFileEntries() {
-        final List nested = new ArrayList();
+        final List<Object> nested = new ArrayList<>();
         nested.add(attributeName);
         for (Annotation annotation : annotations) {
             nested.addAll(annotation.getClassFileEntries());
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/RuntimeVisibleorInvisibleParameterAnnotationsAttribute.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/RuntimeVisibleorInvisibleParameterAnnotationsAttribute.java
index b762928d..d9be8098 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/RuntimeVisibleorInvisibleParameterAnnotationsAttribute.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/RuntimeVisibleorInvisibleParameterAnnotationsAttribute.java
@@ -101,8 +101,8 @@ public class RuntimeVisibleorInvisibleParameterAnnotationsAttribute extends Anno
             return length;
         }
 
-        public List getClassFileEntries() {
-            final List nested = new ArrayList();
+        public List<Object> getClassFileEntries() {
+            final List<Object> nested = new ArrayList<>();
             for (Annotation annotation : annotations) {
                 nested.addAll(annotation.getClassFileEntries());
             }
@@ -113,7 +113,7 @@ public class RuntimeVisibleorInvisibleParameterAnnotationsAttribute extends Anno
 
     @Override
     protected ClassFileEntry[] getNestedClassFileEntries() {
-        final List nested = new ArrayList();
+        final List<Object> nested = new ArrayList<>();
         nested.add(attributeName);
         for (ParameterAnnotation parameter_annotation : parameter_annotations) {
             nested.addAll(parameter_annotation.getClassFileEntries());
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/LabelForm.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/LabelForm.java
index 82ed7d17..1b682343 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/LabelForm.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/LabelForm.java
@@ -50,9 +50,9 @@ public class LabelForm extends ByteCodeForm {
         final int originalTarget = byteCode.getByteCodeTargets()[0];
         final int sourceIndex = byteCode.getByteCodeIndex();
         final int absoluteInstructionTargetIndex = sourceIndex + originalTarget;
-        final int targetValue = ((Integer) codeAttribute.byteCodeOffsets.get(absoluteInstructionTargetIndex))
+        final int targetValue = codeAttribute.byteCodeOffsets.get(absoluteInstructionTargetIndex)
             .intValue();
-        final int sourceValue = ((Integer) codeAttribute.byteCodeOffsets.get(sourceIndex)).intValue();
+        final int sourceValue = codeAttribute.byteCodeOffsets.get(sourceIndex).intValue();
         // The operand is the difference between the source instruction
         // and the destination instruction.
         byteCode.setOperandSigned2Bytes(targetValue - sourceValue, 0);
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/SwitchForm.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/SwitchForm.java
index 4c695eab..a1814771 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/SwitchForm.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/SwitchForm.java
@@ -41,10 +41,10 @@ public abstract class SwitchForm extends VariableInstructionForm {
         final int[] replacementTargets = new int[numberOfLabels];
 
         final int sourceIndex = byteCode.getByteCodeIndex();
-        final int sourceValue = ((Integer) codeAttribute.byteCodeOffsets.get(sourceIndex)).intValue();
+        final int sourceValue = codeAttribute.byteCodeOffsets.get(sourceIndex).intValue();
         for (int index = 0; index < numberOfLabels; index++) {
             final int absoluteInstructionTargetIndex = sourceIndex + originalTargets[index];
-            final int targetValue = ((Integer) codeAttribute.byteCodeOffsets.get(absoluteInstructionTargetIndex))
+            final int targetValue = codeAttribute.byteCodeOffsets.get(absoluteInstructionTargetIndex)
                 .intValue();
             replacementTargets[index] = targetValue - sourceValue;
         }
diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java
index b7b4c8b1..d33d5937 100755
--- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/ArchiveTest.java
@@ -297,10 +297,10 @@ public class ArchiveTest extends TestCase {
     }
 
     private void compareJarEntries(JarFile jarFile, JarFile jarFile2) {
-        Enumeration entries = jarFile.entries();
+        Enumeration<JarEntry> entries = jarFile.entries();
         while (entries.hasMoreElements()) {
 
-            JarEntry entry = (JarEntry) entries.nextElement();
+            JarEntry entry = entries.nextElement();
             assertNotNull(entry);
 
             String name = entry.getName();
@@ -311,10 +311,10 @@ public class ArchiveTest extends TestCase {
 
     private void compareFiles(JarFile jarFile, JarFile jarFile2)
             throws IOException {
-        Enumeration entries = jarFile.entries();
+        Enumeration<JarEntry> entries = jarFile.entries();
         while (entries.hasMoreElements()) {
 
-            JarEntry entry = (JarEntry) entries.nextElement();
+            JarEntry entry = entries.nextElement();
             assertNotNull(entry);
 
             String name = entry.getName();
diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java
index 9617afd5..c69592c7 100644
--- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/CodecEncodingTest.java
@@ -40,7 +40,7 @@ public class CodecEncodingTest extends TestCase {
         Codec defaultCodec = new BHSDCodec(2, 16, 0, 0);
         assertEquals(defaultCodec, CodecEncoding
                 .getCodec(0, null, defaultCodec));
-        Map map = new HashMap();
+        Map<Integer, String> map = new HashMap<>();
         // These are the canonical encodings specified by the Pack200 spec
         map.put(new Integer(1), "(1,256)");
         map.put(new Integer(2), "(1,256,1)");
diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PackingOptionsTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PackingOptionsTest.java
index f9ad89fa..68e76df5 100644
--- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PackingOptionsTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PackingOptionsTest.java
@@ -81,13 +81,13 @@ public class PackingOptionsTest extends TestCase {
         JarFile jarFile2 = new JarFile(compareFile);
 
         // Check that both jars have the same entries in the same order
-        Enumeration entries = jarFile.entries();
-        Enumeration entries2 = jarFile2.entries();
+        Enumeration<JarEntry> entries = jarFile.entries();
+        Enumeration<JarEntry> entries2 = jarFile2.entries();
         while (entries.hasMoreElements()) {
 
-            JarEntry entry = (JarEntry) entries.nextElement();
+            JarEntry entry = entries.nextElement();
             assertNotNull(entry);
-            JarEntry entry2 = (JarEntry) entries2.nextElement();
+            JarEntry entry2 = entries2.nextElement();
             String name = entry.getName();
             String name2 = entry2.getName();
             assertEquals(name, name2);
@@ -128,9 +128,9 @@ public class PackingOptionsTest extends TestCase {
         entries2 = jarFile2.entries();
         boolean inOrder = true;
         while (entries.hasMoreElements()) {
-            JarEntry entry = (JarEntry) entries.nextElement();
+            JarEntry entry = entries.nextElement();
             assertNotNull(entry);
-            JarEntry entry2 = (JarEntry) entries2.nextElement();
+            JarEntry entry2 = entries2.nextElement();
             String name = entry.getName();
             String name2 = entry2.getName();
             if (!name.equals(name2)) {
@@ -198,13 +198,13 @@ public class PackingOptionsTest extends TestCase {
         JarFile jarFile2 = new JarFile(compareFile);
 
         // Check that both jars have the same entries in the same order
-        Enumeration entries = jarFile.entries();
-        Enumeration entries2 = jarFile2.entries();
+        Enumeration<JarEntry> entries = jarFile.entries();
+        Enumeration<JarEntry> entries2 = jarFile2.entries();
         while (entries.hasMoreElements()) {
 
-            JarEntry entry = (JarEntry) entries.nextElement();
+            JarEntry entry = entries.nextElement();
             assertNotNull(entry);
-            JarEntry entry2 = (JarEntry) entries2.nextElement();
+            JarEntry entry2 = entries2.nextElement();
             String name = entry.getName();
             String name2 = entry2.getName();
             assertEquals(name, name2);
@@ -245,9 +245,9 @@ public class PackingOptionsTest extends TestCase {
         long modtime = -1;
         boolean sameAsOriginal = true;
         while (entries.hasMoreElements()) {
-            JarEntry entry = (JarEntry) entries.nextElement();
+            JarEntry entry = entries.nextElement();
             assertNotNull(entry);
-            JarEntry entry2 = (JarEntry) entries2.nextElement();
+            JarEntry entry2 = entries2.nextElement();
             String name = entry.getName();
             if (!name.startsWith("META-INF")) {
                 if (modtime == -1) {
@@ -638,10 +638,10 @@ public class PackingOptionsTest extends TestCase {
     // }
 
     private void compareJarEntries(JarFile jarFile, JarFile jarFile2) {
-        Enumeration entries = jarFile.entries();
+        Enumeration<JarEntry> entries = jarFile.entries();
         while (entries.hasMoreElements()) {
 
-            JarEntry entry = (JarEntry) entries.nextElement();
+            JarEntry entry = entries.nextElement();
             assertNotNull(entry);
 
             String name = entry.getName();
@@ -652,10 +652,10 @@ public class PackingOptionsTest extends TestCase {
 
     private void compareFiles(JarFile jarFile, JarFile jarFile2)
             throws IOException {
-        Enumeration entries = jarFile.entries();
+        Enumeration<JarEntry> entries = jarFile.entries();
         while (entries.hasMoreElements()) {
 
-            JarEntry entry = (JarEntry) entries.nextElement();
+            JarEntry entry = entries.nextElement();
             assertNotNull(entry);
 
             String name = entry.getName();
diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java
index 13c960b2..8979d5ab 100644
--- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/PopulationCodecTest.java
@@ -20,7 +20,6 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 
-import org.apache.commons.compress.harmony.pack200.BHSDCodec;
 import org.apache.commons.compress.harmony.pack200.Codec;
 import org.apache.commons.compress.harmony.pack200.Pack200Exception;
 import org.apache.commons.compress.harmony.pack200.PopulationCodec;
@@ -67,13 +66,13 @@ public class PopulationCodecTest extends TestCase {
 
     public void testEncodeSingleValue() {
         try {
-            new PopulationCodec(BHSDCodec.SIGNED5, BHSDCodec.SIGNED5, BHSDCodec.UDELTA5).encode(5);
+            new PopulationCodec(Codec.SIGNED5, Codec.SIGNED5, Codec.UDELTA5).encode(5);
             fail("Should not allow a single value to be encoded as we don't know which codec to use");
         } catch (Pack200Exception e) {
             // pass
         }
         try {
-            new PopulationCodec(BHSDCodec.SIGNED5, BHSDCodec.SIGNED5, BHSDCodec.UDELTA5).encode(5, 8);
+            new PopulationCodec(Codec.SIGNED5, Codec.SIGNED5, Codec.UDELTA5).encode(5, 8);
             fail("Should not allow a single value to be encoded as we don't know which codec to use");
         } catch (Pack200Exception e) {
             // pass
diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java
index 278b6289..2e7ba000 100644
--- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java
@@ -18,7 +18,6 @@ package org.apache.commons.compress.harmony.pack200.tests;
 
 import java.io.ByteArrayInputStream;
 
-import org.apache.commons.compress.harmony.pack200.BHSDCodec;
 import org.apache.commons.compress.harmony.pack200.Codec;
 import org.apache.commons.compress.harmony.pack200.Pack200Exception;
 import org.apache.commons.compress.harmony.pack200.PopulationCodec;
@@ -33,19 +32,19 @@ public class RunCodecTest extends TestCase {
 
     public void testRunCodec() {
         try {
-            new RunCodec(0, BHSDCodec.SIGNED5, BHSDCodec.UDELTA5);
+            new RunCodec(0, Codec.SIGNED5, Codec.UDELTA5);
             fail("Should not allow a k value of 0");
         } catch (Pack200Exception e) {
             // pass
         }
         try {
-            new RunCodec(10, null, BHSDCodec.UDELTA5);
+            new RunCodec(10, null, Codec.UDELTA5);
             fail("Should not allow a null codec");
         } catch (Pack200Exception e) {
             // pass
         }
         try {
-            new RunCodec(10, BHSDCodec.UDELTA5, null);
+            new RunCodec(10, Codec.UDELTA5, null);
             fail("Should not allow a null codec");
         } catch (Pack200Exception e) {
             // pass
@@ -150,13 +149,13 @@ public class RunCodecTest extends TestCase {
 
     public void testEncodeSingleValue() {
         try {
-            new RunCodec(10, BHSDCodec.SIGNED5, BHSDCodec.UDELTA5).encode(5);
+            new RunCodec(10, Codec.SIGNED5, Codec.UDELTA5).encode(5);
             fail("Should not allow a single value to be encoded as we don't know which codec to use");
         } catch (Pack200Exception e) {
             // pass
         }
         try {
-            new RunCodec(10, BHSDCodec.SIGNED5, BHSDCodec.UDELTA5).encode(5, 8);
+            new RunCodec(10, Codec.SIGNED5, Codec.UDELTA5).encode(5, 8);
             fail("Should not allow a single value to be encoded as we don't know which codec to use");
         } catch (Pack200Exception e) {
             // pass
diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ArchiveTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ArchiveTest.java
index 60af73bb..020987f8 100644
--- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ArchiveTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ArchiveTest.java
@@ -87,15 +87,15 @@ public class ArchiveTest extends TestCase {
         assertTrue("Expected jar files to be a similar size, difference was "
                 + differenceInJarSizes + " bytes", differenceInJarSizes < 100);
 
-        Enumeration entries = jarFile.entries();
-        Enumeration entries2 = jarFile2.entries();
+        Enumeration<JarEntry> entries = jarFile.entries();
+        Enumeration<JarEntry> entries2 = jarFile2.entries();
         while(entries.hasMoreElements() && entries2.hasMoreElements()) {
 
-            JarEntry entry = (JarEntry) entries.nextElement();
+            JarEntry entry = entries.nextElement();
             assertNotNull(entry);
             String name = entry.getName();
 
-            JarEntry entry2 = (JarEntry) entries2.nextElement();
+            JarEntry entry2 = entries2.nextElement();
             assertNotNull(entry2);
             String name2 = entry2.getName();
 
diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/BcBandsTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/BcBandsTest.java
index 2a0b6717..7f89d214 100644
--- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/BcBandsTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/BcBandsTest.java
@@ -221,8 +221,7 @@ public class BcBandsTest extends AbstractBandsTestCase {
             }
             ArrayList orderedAttributeList = new ArrayList();
             for (int classIndex = 0; classIndex < totalMethods; classIndex++) {
-                ArrayList currentAttributes = new ArrayList();
-                orderedAttributeList.add(currentAttributes);
+                orderedAttributeList.add(new ArrayList());
             }
             return orderedAttributeList;
         }
diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/CodeAttributeTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/CodeAttributeTest.java
index 0bcdb5eb..63c0348b 100644
--- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/CodeAttributeTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/CodeAttributeTest.java
@@ -22,12 +22,12 @@ import java.util.List;
 import org.apache.commons.compress.harmony.unpack200.CpBands;
 import org.apache.commons.compress.harmony.unpack200.Segment;
 import org.apache.commons.compress.harmony.unpack200.SegmentConstantPool;
-import org.apache.commons.compress.harmony.unpack200.bytecode.ByteCode;
 import org.apache.commons.compress.harmony.unpack200.bytecode.CPFieldRef;
 import org.apache.commons.compress.harmony.unpack200.bytecode.CPMethodRef;
 import org.apache.commons.compress.harmony.unpack200.bytecode.CPString;
 import org.apache.commons.compress.harmony.unpack200.bytecode.CPUTF8;
 import org.apache.commons.compress.harmony.unpack200.bytecode.CodeAttribute;
+import org.apache.commons.compress.harmony.unpack200.bytecode.ExceptionTableEntry;
 import org.apache.commons.compress.harmony.unpack200.bytecode.LocalVariableTableAttribute;
 import org.apache.commons.compress.harmony.unpack200.bytecode.OperandManager;
 
@@ -38,20 +38,18 @@ import junit.framework.TestCase;
  */
 public class CodeAttributeTest extends TestCase {
 
-    public class MockCodeAttribute extends CodeAttribute {
+	public class MockCodeAttribute extends CodeAttribute {
 
-        public MockCodeAttribute(int maxStack, int maxLocals,
-                byte[] codePacked, Segment segment,
-                OperandManager operandManager, List exceptionTable) {
-            super(maxStack, maxLocals, codePacked, segment, operandManager,
-                    exceptionTable);
-        }
+		public MockCodeAttribute(int maxStack, int maxLocals, byte[] codePacked, Segment segment,
+				OperandManager operandManager, List<ExceptionTableEntry> exceptionTable) {
+			super(maxStack, maxLocals, codePacked, segment, operandManager, exceptionTable);
+		}
 
-        @Override
-        public int getLength() {
-            return super.getLength();
-        }
-    }
+		@Override
+		public int getLength() {
+			return super.getLength();
+		}
+	}
 
     public class MockCpBands extends CpBands {
 
@@ -170,16 +168,16 @@ public class CodeAttributeTest extends TestCase {
                 mixedByteArray, // codePacked
                 segment, // segment
                 operandManager, // operandManager
-                new ArrayList());
+                new ArrayList<>());
         assertEquals(2, attribute.maxLocals);
         assertEquals(3, attribute.maxStack);
-        assertEquals("aload_0_putfield_this", ((ByteCode) attribute.byteCodes
-                .get(4)).toString());
+        assertEquals("aload_0_putfield_this", attribute.byteCodes
+                .get(4).toString());
 
         int expectedLabels[] = new int[] { 0, 1, 4, 5, 8, 9, 10, 13, 14 };
         for (int index = 0; index < expectedLabels.length; index++) {
             assertEquals(expectedLabels[index],
-                    ((Integer) attribute.byteCodeOffsets.get(index)).intValue());
+                    attribute.byteCodeOffsets.get(index).intValue());
         }
     }
 
@@ -193,16 +191,16 @@ public class CodeAttributeTest extends TestCase {
                 singleByteArray, // codePacked
                 segment, // segment
                 operandManager, // operandManager
-                new ArrayList());
+                new ArrayList<>());
         assertEquals(3, attribute.maxLocals);
         assertEquals(4, attribute.maxStack);
-        assertEquals("invokespecial_this", ((ByteCode) attribute.byteCodes
-                .get(3)).toString());
+        assertEquals("invokespecial_this", attribute.byteCodes
+                .get(3).toString());
 
         int expectedLabels[] = new int[] { 0, 1, 2, 4 };
         for (int index = 0; index < expectedLabels.length; index++) {
             assertEquals(expectedLabels[index],
-                    ((Integer) attribute.byteCodeOffsets.get(index)).intValue());
+                    attribute.byteCodeOffsets.get(index).intValue());
         }
     }
 
diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/NewAttributeBandsTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/NewAttributeBandsTest.java
index b7764d43..441ee194 100644
--- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/NewAttributeBandsTest.java
+++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/NewAttributeBandsTest.java
@@ -40,7 +40,7 @@ public class NewAttributeBandsTest extends AbstractBandsTestCase {
         MockNewAttributeBands newAttributeBands = new MockNewAttributeBands(
                 new MockSegment(), new AttributeLayout("test",
                         AttributeLayout.CONTEXT_CLASS, "", 25));
-        List layoutElements = newAttributeBands.getLayoutElements();
+        List<?> layoutElements = newAttributeBands.getLayoutElements();
         assertEquals(0, layoutElements.size());
     }
 
@@ -249,7 +249,7 @@ public class NewAttributeBandsTest extends AbstractBandsTestCase {
             super(segment, layout);
         }
 
-        public List getLayoutElements() {
+        public List<?> getLayoutElements() {
             return attributeLayoutElements;
         }
     }


[commons-compress] 02/02: Use generics

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-compress.git

commit 7005afe46d54229ccdb174f686d34ce23f1f6f2e
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Fri Sep 30 18:12:19 2022 -0400

    Use generics
    
    Use lambdas
---
 .../commons/compress/harmony/pack200/CpBands.java  | 12 ++++-----
 .../harmony/pack200/MetadataBandGroup.java         | 29 ++++++++++-----------
 .../harmony/pack200/NewAttributeBands.java         |  7 +++--
 .../commons/compress/harmony/pack200/Segment.java  |  6 ++---
 .../harmony/unpack200/AttributeLayoutMap.java      |  3 +--
 .../compress/harmony/unpack200/BcBands.java        |  3 +--
 .../harmony/unpack200/NewAttributeBands.java       | 30 +++++++++-------------
 .../harmony/unpack200/SegmentConstantPool.java     |  4 +--
 .../harmony/unpack200/bytecode/CPMember.java       |  5 +---
 .../unpack200/bytecode/ClassConstantPool.java      | 19 ++++----------
 .../harmony/unpack200/bytecode/CodeAttribute.java  | 30 +++++-----------------
 11 files changed, 53 insertions(+), 95 deletions(-)

diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/CpBands.java b/src/main/java/org/apache/commons/compress/harmony/pack200/CpBands.java
index 7804b297..8c982cea 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/CpBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/CpBands.java
@@ -362,14 +362,14 @@ public class CpBands extends BandSet {
     }
 
     private void removeSignaturesFromCpUTF8() {
-        for (final CPSignature signature : cp_Signature) {
+        cp_Signature.forEach(signature -> {
             final String sigStr = signature.getUnderlyingString();
             final CPUTF8 utf8 = signature.getSignatureForm();
             final String form = utf8.getUnderlyingString();
             if (!sigStr.equals(form)) {
                 removeCpUtf8(sigStr);
             }
-        }
+        });
     }
 
 	private void addIndices() {
@@ -382,7 +382,7 @@ public class CpBands extends BandSet {
 			}
 		}
 		final Map<CPClass, Integer> classNameToIndex = new HashMap<>();
-		for (final CPMethodOrField mOrF : cp_Field) {
+		cp_Field.forEach(mOrF -> {
 			final CPClass cpClassName = mOrF.getClassName();
 			final Integer index = classNameToIndex.get(cpClassName);
 			if (index == null) {
@@ -393,10 +393,10 @@ public class CpBands extends BandSet {
 				mOrF.setIndexInClass(theIndex);
 				classNameToIndex.put(cpClassName, Integer.valueOf(theIndex + 1));
 			}
-		}
+		});
 		classNameToIndex.clear();
 		final Map<CPClass, Integer> classNameToConstructorIndex = new HashMap<>();
-		for (final CPMethodOrField mOrF : cp_Method) {
+		cp_Method.forEach(mOrF -> {
 			final CPClass cpClassName = mOrF.getClassName();
 			final Integer index = classNameToIndex.get(cpClassName);
 			if (index == null) {
@@ -418,7 +418,7 @@ public class CpBands extends BandSet {
 					classNameToConstructorIndex.put(cpClassName, Integer.valueOf(theIndex + 1));
 				}
 			}
-		}
+		});
 	}
 
     private void removeCpUtf8(final String string) {
diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/MetadataBandGroup.java b/src/main/java/org/apache/commons/compress/harmony/pack200/MetadataBandGroup.java
index 38e7056d..95a1efa6 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/MetadataBandGroup.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/MetadataBandGroup.java
@@ -266,21 +266,18 @@ public class MetadataBandGroup extends BandSet {
 			}
 			// do nothing here for [ or @ (handled below)
 		}
-		for (Object element : caseArrayN) {
-			final int arraySize = ((Integer) element).intValue();
+		for (Integer element : caseArrayN) {
+			final int arraySize = element.intValue();
 			casearray_N.add(arraySize);
 			numBackwardsCalls += arraySize;
 		}
-		for (Object element : nestTypeRS) {
-			final String type = (String) element;
+		for (String type : nestTypeRS) {
 			nesttype_RS.add(cpBands.getCPSignature(type));
 		}
-		for (Object element : nestNameRU) {
-			final String name = (String) element;
+		for (String name : nestNameRU) {
 			nestname_RU.add(cpBands.getCPUtf8(name));
 		}
-		for (Object element : nestPairN) {
-			final Integer numPairs = (Integer) element;
+		for (Integer numPairs : nestPairN) {
 			nestpair_N.add(numPairs.intValue());
 			numBackwardsCalls += numPairs.intValue();
 		}
@@ -337,21 +334,21 @@ public class MetadataBandGroup extends BandSet {
 			}
 			// do nothing here for [ or @ (handled below)
 		}
-		for (Object element : caseArrayN) {
-			final int arraySize = ((Integer) element).intValue();
+		for (Integer element : caseArrayN) {
+			final int arraySize = element.intValue();
 			casearray_N.add(arraySize);
 			numBackwardsCalls += arraySize;
 		}
-		for (Object element : nestTypeRS) {
-			final String type = (String) element;
+		for (String element : nestTypeRS) {
+			final String type = element;
 			nesttype_RS.add(cpBands.getCPSignature(type));
 		}
-		for (Object element : nestNameRU) {
-			final String name = (String) element;
+		for (String element : nestNameRU) {
+			final String name = element;
 			nestname_RU.add(cpBands.getCPUtf8(name));
 		}
-		for (Object element : nestPairN) {
-			final Integer numPairs = (Integer) element;
+		for (Integer element : nestPairN) {
+			final Integer numPairs = element;
 			nestpair_N.add(numPairs.intValue());
 			numBackwardsCalls += numPairs.intValue();
 		}
diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/NewAttributeBands.java b/src/main/java/org/apache/commons/compress/harmony/pack200/NewAttributeBands.java
index b091b78b..effe6029 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/NewAttributeBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/NewAttributeBands.java
@@ -108,8 +108,7 @@ public class NewAttributeBands extends BandSet {
             if (element instanceof Callable) {
                 final Callable callable = (Callable) element;
                 final List<LayoutElement> body = callable.body; // Look for calls in the body
-                for (LayoutElement element2 : body) {
-                    final LayoutElement layoutElement = element2;
+                for (LayoutElement layoutElement : body) {
                     // Set the callable for each call
                     resolveCallsForElement(i, callable, layoutElement);
                 }
@@ -533,8 +532,8 @@ public class NewAttributeBands extends BandSet {
                 }
             }
             if (defaultCase) {
-                for (LayoutElement element2 : defaultCaseBody) {
-                    element2.addAttributeToBand(attribute, inputStream);
+                for (LayoutElement layoutElement : defaultCaseBody) {
+                    layoutElement.addAttributeToBand(attribute, inputStream);
                 }
             }
         }
diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/Segment.java b/src/main/java/org/apache/commons/compress/harmony/pack200/Segment.java
index 6a7d4b75..1c8d95c7 100644
--- a/src/main/java/org/apache/commons/compress/harmony/pack200/Segment.java
+++ b/src/main/java/org/apache/commons/compress/harmony/pack200/Segment.java
@@ -150,8 +150,7 @@ public class Segment extends ClassVisitor {
 
     private void processClasses(final SegmentUnit segmentUnit, final Attribute[] attributes) throws Pack200Exception {
         segmentHeader.setClass_count(segmentUnit.classListSize());
-        for (Object element : segmentUnit.getClassList()) {
-            final Pack200ClassReader classReader = (Pack200ClassReader) element;
+        for (Pack200ClassReader classReader : segmentUnit.getClassList()) {
             currentClassReader = classReader;
             int flags = 0;
             if (stripDebug) {
@@ -167,8 +166,7 @@ public class Segment extends ClassVisitor {
                 options.addPassFile(name);
                 cpBands.addCPUtf8(name);
                 boolean found = false;
-                for (Object element2 : segmentUnit.getFileList()) {
-                    final PackingFile file = (PackingFile) element2;
+                for (PackingFile file : segmentUnit.getFileList()) {
                     if (file.getName().equals(name)) {
                         found = true;
                         file.setContents(classReader.b);
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/AttributeLayoutMap.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/AttributeLayoutMap.java
index a8579ab0..4c2d6ed4 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/AttributeLayoutMap.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/AttributeLayoutMap.java
@@ -133,8 +133,7 @@ public class AttributeLayoutMap {
     private final Map<AttributeLayout, NewAttributeBands> layoutsToBands = new HashMap<>();
 
     public AttributeLayoutMap() throws Pack200Exception {
-        final AttributeLayout[] defaultAttributeLayouts = getDefaultAttributeLayouts();
-        for (AttributeLayout defaultAttributeLayout : defaultAttributeLayouts) {
+        for (AttributeLayout defaultAttributeLayout : getDefaultAttributeLayouts()) {
             add(defaultAttributeLayout);
         }
     }
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/BcBands.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/BcBands.java
index 1a962562..3aa1e373 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/BcBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/BcBands.java
@@ -426,8 +426,7 @@ public class BcBands extends BandSet {
                     } else {
                         currentAttributes = Collections.EMPTY_LIST;
                     }
-                    for (Object currentAttribute2 : currentAttributes) {
-                        final Attribute currentAttribute = (Attribute) currentAttribute2;
+                    for (Attribute currentAttribute : currentAttributes) {
                         codeAttr.addAttribute(currentAttribute);
                         // Fix up the line numbers if needed
                         if (currentAttribute.hasBCIRenumbering()) {
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/NewAttributeBands.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/NewAttributeBands.java
index c4fa952e..2f1a505e 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/NewAttributeBands.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/NewAttributeBands.java
@@ -456,9 +456,8 @@ public class NewAttributeBands extends BandSet {
             for (int i = 0; i < count; i++) {
                 arrayCount += countElement.getValue(i);
             }
-            for (Object layoutElement : layoutElements) {
-                final LayoutElement element = (LayoutElement) layoutElement;
-                element.readBands(in, arrayCount);
+            for (LayoutElement layoutElement : layoutElements) {
+                layoutElement.readBands(in, arrayCount);
             }
         }
 
@@ -474,9 +473,8 @@ public class NewAttributeBands extends BandSet {
             }
             final long numElements = countElement.getValue(index);
             for (int i = offset; i < offset + numElements; i++) {
-                for (Object layoutElement : layoutElements) {
-                    final LayoutElement element = (LayoutElement) layoutElement;
-                    element.addToAttribute(i, attribute);
+                for (LayoutElement layoutElement : layoutElements) {
+                    layoutElement.addToAttribute(i, attribute);
                 }
             }
         }
@@ -525,8 +523,7 @@ public class NewAttributeBands extends BandSet {
             // Count number of default cases then read the default bands
             for (int value : values) {
                 boolean found = false;
-                for (Object element : unionCases) {
-                    final UnionCase unionCase = (UnionCase) element;
+                for (UnionCase unionCase : unionCases) {
                     if (unionCase.hasTag(value)) {
                         found = true;
                     }
@@ -549,16 +546,15 @@ public class NewAttributeBands extends BandSet {
             final int[] tagBand = unionTag.band;
             final int tag = unionTag.getValue(n);
             boolean defaultCase = true;
-            for (Object element2 : unionCases) {
-                final UnionCase element = (UnionCase) element2;
-                if (element.hasTag(tag)) {
+            for (UnionCase unionCase : unionCases) {
+                if (unionCase.hasTag(tag)) {
                     defaultCase = false;
                     for (int j = 0; j < n; j++) {
-                        if (element.hasTag(tagBand[j])) {
+                        if (unionCase.hasTag(tagBand[j])) {
                             offset++;
                         }
                     }
-                    element.addToAttribute(offset, attribute);
+                    unionCase.addToAttribute(offset, attribute);
                 }
             }
             if (defaultCase) {
@@ -566,9 +562,8 @@ public class NewAttributeBands extends BandSet {
                 int defaultOffset = 0;
                 for (int j = 0; j < n; j++) {
                     boolean found = false;
-                    for (Object element2 : unionCases) {
-                        final UnionCase element = (UnionCase) element2;
-                        if (element.hasTag(tagBand[j])) {
+                    for (UnionCase unionCase : unionCases) {
+                        if (unionCase.hasTag(tagBand[j])) {
                             found = true;
                         }
                     }
@@ -994,8 +989,7 @@ public class NewAttributeBands extends BandSet {
     public void setBackwardsCalls(final int[] backwardsCalls) throws IOException {
         int index = 0;
         parseLayout();
-        for (Object attributeLayoutElement : attributeLayoutElements) {
-            final AttributeLayoutElement element = (AttributeLayoutElement) attributeLayoutElement;
+        for (AttributeLayoutElement element : attributeLayoutElements) {
             if (element instanceof Callable && ((Callable) element).isBackwardsCallable()) {
                 ((Callable) element).addCount(backwardsCalls[index]);
                 index++;
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java
index faadb980..09e77a96 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java
@@ -210,8 +210,8 @@ public class SegmentConstantPool {
             return -1;
         }
 
-        for (Object element : indexList) {
-            final int arrayIndex = ((Integer) element).intValue();
+        for (Integer element : indexList) {
+            final int arrayIndex = element.intValue();
             if (regexMatches(secondaryCompareRegex, secondaryArray[arrayIndex])) {
                 instanceCount++;
                 if (instanceCount == desiredIndex) {
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMember.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMember.java
index 64616067..5eb14fb8 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMember.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CPMember.java
@@ -67,10 +67,7 @@ public class CPMember extends ClassFileEntry {
         super.resolve(pool);
         nameIndex = pool.indexOf(name);
         descriptorIndex = pool.indexOf(descriptor);
-        for (Object attribute2 : attributes) {
-            final Attribute attribute = (Attribute) attribute2;
-            attribute.resolve(pool);
-        }
+        attributes.forEach(attribute -> attribute.resolve(pool));
     }
 
     @Override
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ClassConstantPool.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ClassConstantPool.java
index 9b43ce85..23712b2a 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ClassConstantPool.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/ClassConstantPool.java
@@ -140,14 +140,8 @@ public class ClassConstantPool {
 
         resolved = true;
 
-        for (ClassFileEntry entry : entries) {
-            entry.resolve(this);
-        }
-
-        for (ClassFileEntry other : others) {
-            other.resolve(this);
-        }
-
+        entries.forEach(entry -> entry.resolve(this));
+        others.forEach(entry -> entry.resolve(this));
     }
 
     private void initialSort() {
@@ -206,8 +200,7 @@ public class ClassConstantPool {
 
         entries.clear();
 
-        for (Object element : startOfPool) {
-            final ClassFileEntry entry = (ClassFileEntry) element;
+        for (ClassFileEntry entry : startOfPool) {
             indexCache.put(entry, Integer.valueOf(index));
 
             if (entry instanceof CPLong || entry instanceof CPDouble) {
@@ -220,8 +213,7 @@ public class ClassConstantPool {
             }
         }
 
-        for (Object element : finalSort) {
-            final ClassFileEntry entry = (ClassFileEntry) element;
+        for (ClassFileEntry entry : finalSort) {
             indexCache.put(entry, Integer.valueOf(index));
 
             if (entry instanceof CPLong || entry instanceof CPDouble) {
@@ -238,8 +230,7 @@ public class ClassConstantPool {
 
     public ClassFileEntry addWithNestedEntries(final ClassFileEntry entry) {
         add(entry);
-        final ClassFileEntry[] nestedEntries = entry.getNestedClassFileEntries();
-        for (ClassFileEntry nestedEntry : nestedEntries) {
+        for (ClassFileEntry nestedEntry : entry.getNestedClassFileEntries()) {
             addWithNestedEntries(nestedEntry);
         }
         return entry;
diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CodeAttribute.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CodeAttribute.java
index 72be6986..763311f9 100644
--- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CodeAttribute.java
+++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/CodeAttribute.java
@@ -86,8 +86,7 @@ public class CodeAttribute extends BCIRenumberedAttribute {
     @Override
     protected int getLength() {
         int attributesSize = 0;
-        for (Object attribute2 : attributes) {
-            final Attribute attribute = (Attribute) attribute2;
+        for (Attribute attribute : attributes) {
             attributesSize += attribute.getLengthIncludingHeader();
         }
         return 2 + 2 + 4 + codeLength + 2 + exceptionTable.size() * (2 + 2 + 2 + 2) + 2 + attributesSize;
@@ -117,20 +116,9 @@ public class CodeAttribute extends BCIRenumberedAttribute {
     @Override
     protected void resolve(final ClassConstantPool pool) {
         super.resolve(pool);
-        for (Object attribute2 : attributes) {
-            final Attribute attribute = (Attribute) attribute2;
-            attribute.resolve(pool);
-        }
-
-        for (Object byteCode2 : byteCodes) {
-            final ByteCode byteCode = (ByteCode) byteCode2;
-            byteCode.resolve(pool);
-        }
-
-        for (Object element : exceptionTable) {
-            final ExceptionTableEntry entry = (ExceptionTableEntry) element;
-            entry.resolve(pool);
-        }
+        attributes.forEach(attribute -> attribute.resolve(pool));
+        byteCodes.forEach(byteCode -> byteCode.resolve(pool));
+        exceptionTable.forEach(byteCode -> byteCode.resolve(pool));
     }
 
     @Override
@@ -149,14 +137,12 @@ public class CodeAttribute extends BCIRenumberedAttribute {
         }
 
         dos.writeShort(exceptionTable.size());
-        for (Object element : exceptionTable) {
-            final ExceptionTableEntry entry = (ExceptionTableEntry) element;
+        for (ExceptionTableEntry entry : exceptionTable) {
             entry.write(dos);
         }
 
         dos.writeShort(attributes.size());
-        for (Object attribute2 : attributes) {
-            final Attribute attribute = (Attribute) attribute2;
+        for (Attribute attribute : attributes) {
             attribute.write(dos);
         }
     }
@@ -179,9 +165,7 @@ public class CodeAttribute extends BCIRenumberedAttribute {
 
     @Override
     public void renumber(final List<Integer> byteCodeOffsets) {
-        for (ExceptionTableEntry entry : exceptionTable) {
-            entry.renumber(byteCodeOffsets);
-        }
+        exceptionTable.forEach(entry -> entry.renumber(byteCodeOffsets));
     }
 
     public static void setAttributeName(final CPUTF8 attributeName) {