[proguard] 01/02: Imported Upstream version 3.7

Emmanuel Bourg ebourg-guest at moszumanska.debian.org
Thu Apr 10 09:00:34 UTC 2014


This is an automated email from the git hooks/post-receive script.

ebourg-guest pushed a commit to annotated tag debian/3.7-1
in repository proguard.

commit e6956036a59db15140ed458eeea70d62c158c485
Author: Sam Clegg <samo at debian.org>
Date:   Thu Apr 10 10:41:54 2014 +0200

    Imported Upstream version 3.7
---
 README                                             |   6 +-
 docs/FAQ.html                                      |  29 +-
 docs/GPL_exception.html                            |  24 +-
 docs/acknowledgements.html                         |  37 +-
 docs/alternatives.html                             | 235 +++++---
 docs/downloads.html                                | 142 ++++-
 docs/favicon.ico                                   | Bin 0 -> 7406 bytes
 docs/feedback.html                                 |  15 +-
 docs/index.html                                    |  18 +
 docs/license.html                                  |   6 +-
 docs/main.html                                     |   9 +-
 docs/manual/ant.html                               |   7 +-
 docs/manual/examples.html                          | 439 +++++++++++----
 docs/manual/gui.html                               |  11 +-
 docs/manual/index.html                             |   2 +-
 docs/manual/introduction.html                      |   2 +-
 docs/manual/limitations.html                       |  10 +-
 docs/manual/refcard.html                           | 121 ++--
 docs/manual/retrace/examples.html                  |   2 +-
 docs/manual/retrace/index.html                     |   2 +-
 docs/manual/retrace/introduction.html              |   2 +-
 docs/manual/retrace/usage.html                     |   2 +-
 docs/manual/style.css                              |   5 +
 docs/manual/troubleshooting.html                   | 141 +++--
 docs/manual/usage.html                             |  66 ++-
 docs/manual/wtk.html                               |   2 +-
 docs/quality.html                                  |   8 +-
 docs/results.html                                  |   4 +-
 docs/screenshots.html                              |   2 +-
 docs/style.css                                     |  17 +
 docs/testimonials.html                             |  36 +-
 docs/title.html                                    |   2 +-
 examples/ant/applets.xml                           |   8 +-
 examples/ant/applications1.xml                     |   2 +-
 examples/ant/applications2.xml                     |   5 +-
 examples/ant/applications3.xml                     |   8 +-
 examples/ant/library.xml                           |   8 +-
 examples/ant/servlets.xml                          |   8 +-
 examples/applets.pro                               |   6 +-
 examples/applications.pro                          |   6 +-
 examples/library.pro                               |   6 +-
 examples/servlets.pro                              |   6 +-
 src/proguard/ArgumentWordReader.java               |   4 +-
 src/proguard/ClassMemberSpecification.java         |   4 +-
 src/proguard/ClassPath.java                        |   4 +-
 src/proguard/ClassPathEntry.java                   |   4 +-
 src/proguard/ClassSpecification.java               |  26 +-
 src/proguard/ClassSpecificationVisitorFactory.java |   6 +-
 src/proguard/Configuration.java                    |   9 +-
 src/proguard/ConfigurationConstants.java           |   3 +-
 src/proguard/ConfigurationParser.java              |  10 +-
 src/proguard/ConfigurationWriter.java              |  13 +-
 src/proguard/DataEntryReaderFactory.java           |   4 +-
 src/proguard/DataEntryWriterFactory.java           |   4 +-
 ...Cleaner.java => DuplicateClassFilePrinter.java} |  31 +-
 src/proguard/FileWordReader.java                   |   4 +-
 src/proguard/GPL.java                              |  27 +-
 src/proguard/Initializer.java                      | 240 ++++++++
 src/proguard/InputReader.java                      | 208 +++++++
 src/proguard/OutputWriter.java                     | 174 ++++++
 src/proguard/ParseException.java                   |   4 +-
 src/proguard/ProGuard.java                         | 402 +------------
 src/proguard/SubclassedClassFileFilter.java        |   4 +-
 src/proguard/WordReader.java                       |   4 +-
 .../ant/ClassMemberSpecificationElement.java       |   4 +-
 src/proguard/ant/ClassPathElement.java             |  19 +-
 src/proguard/ant/ClassSpecificationElement.java    |   4 +-
 src/proguard/ant/ConfigurationElement.java         |   4 +-
 src/proguard/ant/ConfigurationTask.java            |   4 +-
 src/proguard/ant/KeepAttributeElement.java         |   4 +-
 src/proguard/ant/ProGuardTask.java                 |  10 +-
 src/proguard/classfile/ClassConstants.java         |   6 +-
 src/proguard/classfile/ClassCpInfo.java            |   4 +-
 src/proguard/classfile/ClassFile.java              |   4 +-
 src/proguard/classfile/ClassPool.java              |  48 +-
 src/proguard/classfile/CpInfo.java                 |   4 +-
 src/proguard/classfile/DoubleCpInfo.java           |   6 +-
 src/proguard/classfile/FieldInfo.java              |   4 +-
 src/proguard/classfile/FieldrefCpInfo.java         |   4 +-
 src/proguard/classfile/FloatCpInfo.java            |   4 +-
 src/proguard/classfile/IntegerCpInfo.java          |   4 +-
 .../classfile/InterfaceMethodrefCpInfo.java        |   4 +-
 src/proguard/classfile/LibraryClassFile.java       |   4 +-
 src/proguard/classfile/LibraryFieldInfo.java       |  20 +-
 src/proguard/classfile/LibraryMemberInfo.java      |   4 +-
 src/proguard/classfile/LibraryMethodInfo.java      |  26 +-
 src/proguard/classfile/LongCpInfo.java             |   6 +-
 src/proguard/classfile/MemberInfo.java             |  12 +-
 src/proguard/classfile/MethodInfo.java             |   4 +-
 src/proguard/classfile/MethodrefCpInfo.java        |   4 +-
 src/proguard/classfile/NameAndTypeCpInfo.java      |   4 +-
 src/proguard/classfile/ProgramClassFile.java       |   4 +-
 src/proguard/classfile/ProgramFieldInfo.java       |   6 +-
 src/proguard/classfile/ProgramMemberInfo.java      |  11 +-
 src/proguard/classfile/ProgramMethodInfo.java      |   6 +-
 src/proguard/classfile/RefCpInfo.java              |   4 +-
 src/proguard/classfile/StringCpInfo.java           |   4 +-
 src/proguard/classfile/Utf8CpInfo.java             |   4 +-
 src/proguard/classfile/VisitorAccepter.java        |   4 +-
 src/proguard/classfile/attribute/AttrInfo.java     |   4 +-
 .../classfile/attribute/AttrInfoVisitor.java       |   4 +-
 src/proguard/classfile/attribute/CodeAttrInfo.java |   4 +-
 .../classfile/attribute/DeprecatedAttrInfo.java    |   4 +-
 .../attribute/EnclosingMethodAttrInfo.java         |   4 +-
 .../classfile/attribute/ExceptionInfo.java         |   4 +-
 .../classfile/attribute/ExceptionInfoVisitor.java  |   4 +-
 .../classfile/attribute/ExceptionsAttrInfo.java    |   4 +-
 .../classfile/attribute/InnerClassesAttrInfo.java  |   4 +-
 .../classfile/attribute/InnerClassesInfo.java      |   4 +-
 .../attribute/InnerClassesInfoVisitor.java         |   4 +-
 .../classfile/attribute/LibraryAttrInfo.java       |   4 +-
 .../classfile/attribute/LineNumberInfo.java        |   4 +-
 .../attribute/LineNumberTableAttrInfo.java         |   4 +-
 .../classfile/attribute/LocalVariableInfo.java     |   4 +-
 .../attribute/LocalVariableInfoVisitor.java        |   4 +-
 .../attribute/LocalVariableTableAttrInfo.java      |   4 +-
 .../classfile/attribute/LocalVariableTypeInfo.java |   4 +-
 .../attribute/LocalVariableTypeInfoVisitor.java    |   4 +-
 .../attribute/LocalVariableTypeTableAttrInfo.java  |   4 +-
 .../classfile/attribute/MultiAttrInfoVisitor.java  |   4 +-
 .../classfile/attribute/SignatureAttrInfo.java     |  24 +-
 .../classfile/attribute/SourceDirAttrInfo.java     |   4 +-
 .../classfile/attribute/SourceFileAttrInfo.java    |   4 +-
 .../classfile/attribute/SyntheticAttrInfo.java     |   4 +-
 .../classfile/attribute/UnknownAttrInfo.java       |   4 +-
 .../classfile/attribute/annotation/Annotation.java |  41 +-
 .../annotation/AnnotationDefaultAttrInfo.java      |   4 +-
 .../annotation/AnnotationElementValue.java         |   4 +-
 .../attribute/annotation/AnnotationVisitor.java    |   4 +-
 .../attribute/annotation/ArrayElementValue.java    |   4 +-
 .../attribute/annotation/ClassElementValue.java    |  24 +-
 .../attribute/annotation/ConstantElementValue.java |   4 +-
 .../attribute/annotation/ElementValue.java         |  25 +-
 .../attribute/annotation/ElementValueVisitor.java  |   4 +-
 .../annotation/EnumConstantElementValue.java       |   4 +-
 .../annotation/RuntimeAnnotationsAttrInfo.java     |   4 +-
 .../RuntimeInvisibleAnnotationsAttrInfo.java       |   4 +-
 ...ntimeInvisibleParameterAnnotationsAttrInfo.java |   4 +-
 .../RuntimeParameterAnnotationsAttrInfo.java       |   4 +-
 .../RuntimeVisibleAnnotationsAttrInfo.java         |   4 +-
 ...RuntimeVisibleParameterAnnotationsAttrInfo.java |   4 +-
 .../classfile/editor/ClassFileReferenceFixer.java  |  51 +-
 .../classfile/editor/CodeAttrInfoEditor.java       | 419 ++++++++------
 .../editor/CodeAttrInfoEditorResetter.java         |   4 +-
 .../classfile/editor/ComparableCpInfo.java         |   4 +-
 .../classfile/editor/ConstantPoolEditor.java       |   4 +-
 .../classfile/editor/ConstantPoolRemapper.java     |   4 +-
 .../classfile/editor/ConstantPoolSorter.java       |   4 +-
 .../classfile/editor/InstructionWriter.java        | 299 ++++++++++
 .../classfile/editor/MemberReferenceFixer.java     |  23 +-
 .../classfile/editor/MethodInvocationFixer.java    |  20 +-
 .../classfile/editor/StackSizeUpdater.java         |   4 +-
 src/proguard/classfile/editor/VariableEditor.java  |   8 +-
 .../classfile/editor/VariableRemapper.java         |   4 +-
 .../classfile/instruction/BranchInstruction.java   |  43 +-
 .../classfile/instruction/CpInstruction.java       |  46 +-
 .../classfile/instruction/Instruction.java         |  13 +-
 .../classfile/instruction/InstructionCounter.java  |  28 +-
 .../classfile/instruction/InstructionFactory.java  |   4 +-
 .../classfile/instruction/InstructionVisitor.java  |   4 +-
 .../instruction/LookUpSwitchInstruction.java       |   4 +-
 .../instruction/MultiInstructionVisitor.java       |   4 +-
 .../classfile/instruction/SimpleInstruction.java   |  60 +-
 .../instruction/TableSwitchInstruction.java        |   4 +-
 .../classfile/instruction/VariableInstruction.java |  71 ++-
 src/proguard/classfile/util/AccessUtil.java        |   4 +-
 .../ClassFileClassForNameReferenceInitializer.java |  68 +--
 .../util/ClassFileHierarchyInitializer.java        |  60 +-
 .../util/ClassFileReferenceInitializer.java        | 106 ++--
 .../classfile/util/ClassForNameChecker.java        |   4 +-
 .../classfile/util/ClassNewInstanceChecker.java    |   4 +-
 src/proguard/classfile/util/ClassUtil.java         |  42 +-
 .../classfile/util/DescriptorClassEnumeration.java |   4 +-
 .../classfile/util/ExternalTypeEnumeration.java    |   4 +-
 .../classfile/util/InternalTypeEnumeration.java    |   4 +-
 src/proguard/classfile/util/MemberFinder.java      |  61 +-
 src/proguard/classfile/util/MethodInfoLinker.java  |  95 ++--
 src/proguard/classfile/util/WarningPrinter.java    |  77 +++
 .../classfile/visitor/AllClassFileVisitor.java     |   4 +-
 .../classfile/visitor/AllCpInfoVisitor.java        |   4 +-
 .../classfile/visitor/AllFieldVisitor.java         |   4 +-
 .../classfile/visitor/AllMemberInfoVisitor.java    |   4 +-
 .../classfile/visitor/AllMethodVisitor.java        |   4 +-
 .../classfile/visitor/BottomClassFileFilter.java   |   4 +-
 src/proguard/classfile/visitor/ClassCounter.java   |  18 +-
 .../classfile/visitor/ClassFileAccessFilter.java   |   4 +-
 .../classfile/visitor/ClassFileCleaner.java        |   4 +-
 .../visitor/ClassFileHierarchyTraveler.java        |   4 +-
 .../visitor/ClassFileMemberInfoVisitor.java        |   4 +-
 .../classfile/visitor/ClassFileNameFilter.java     |   4 +-
 .../classfile/visitor/ClassFilePresenceFilter.java |  95 ++++
 .../classfile/visitor/ClassFilePrinter.java        |   7 +-
 .../classfile/visitor/ClassFileVersionCounter.java |  79 +++
 .../classfile/visitor/ClassFileVisitor.java        |   4 +-
 ...itor.java => ClassForNameClassFileVisitor.java} |  80 +--
 .../classfile/visitor/ClassPoolFiller.java         |  28 +-
 .../classfile/visitor/ClassPoolVisitor.java        |   4 +-
 .../visitor/ConcreteClassFileDownTraveler.java     |   4 +-
 src/proguard/classfile/visitor/CpInfoVisitor.java  |   4 +-
 .../visitor/DotClassClassFileVisitor.java          |  99 ++++
 .../classfile/visitor/LibraryClassFileFilter.java  |   4 +-
 .../classfile/visitor/LibraryMemberInfoFilter.java |   4 +-
 .../classfile/visitor/LineNumberInfoVisitor.java   |   4 +-
 src/proguard/classfile/visitor/MemberCounter.java  |  22 +-
 .../classfile/visitor/MemberInfoAccessFilter.java  |   4 +-
 .../visitor/MemberInfoClassFileAccessFilter.java   | 106 ++++
 .../visitor/MemberInfoDescriptorFilter.java        |   4 +-
 .../classfile/visitor/MemberInfoNameFilter.java    |   4 +-
 .../classfile/visitor/MemberInfoVisitor.java       |   4 +-
 .../visitor/MethodImplementationFilter.java        |   4 +-
 .../visitor/MethodImplementationTraveler.java      |   4 +-
 .../classfile/visitor/MultiClassFileVisitor.java   |   4 +-
 .../classfile/visitor/MultiMemberInfoVisitor.java  |   4 +-
 .../classfile/visitor/NamedClassFileVisitor.java   |   4 +-
 .../classfile/visitor/NamedFieldVisitor.java       |   4 +-
 .../classfile/visitor/NamedMethodVisitor.java      |   4 +-
 .../classfile/visitor/ProgramClassFileFilter.java  |   4 +-
 .../classfile/visitor/ProgramMemberInfoFilter.java |   4 +-
 .../visitor/ReferencedClassFileVisitor.java        | 223 +++++++-
 .../classfile/visitor/SimpleClassFilePrinter.java  |   4 +-
 .../visitor/VariableClassFileVisitor.java          |   4 +-
 .../visitor/VariableMemberInfoVisitor.java         |   4 +-
 .../gui/ClassMemberSpecificationDialog.java        |   4 +-
 .../gui/ClassMemberSpecificationsPanel.java        |   4 +-
 src/proguard/gui/ClassPathPanel.java               |   4 +-
 src/proguard/gui/ClassSpecificationDialog.java     |   4 +-
 src/proguard/gui/ClassSpecificationsPanel.java     |   4 +-
 src/proguard/gui/ExtensionFileFilter.java          |   4 +-
 src/proguard/gui/FilterDialog.java                 |   4 +-
 src/proguard/gui/GUIResources.java                 |   4 +-
 src/proguard/gui/GUIResources.properties           |   9 +-
 src/proguard/gui/ListPanel.java                    |   4 +-
 src/proguard/gui/MessageDialogRunnable.java        |   4 +-
 src/proguard/gui/ProGuardGUI.java                  |  44 +-
 src/proguard/gui/ProGuardRunnable.java             |   4 +-
 src/proguard/gui/ReTraceRunnable.java              |   4 +-
 src/proguard/gui/SwingUtil.java                    |   4 +-
 src/proguard/gui/TabbedPane.java                   |   4 +-
 src/proguard/gui/TextAreaOutputStream.java         |   4 +-
 src/proguard/gui/boilerplate.pro                   |  16 +-
 src/proguard/gui/default.pro                       |  16 +-
 src/proguard/gui/splash/BufferedSprite.java        |   4 +-
 src/proguard/gui/splash/CircleSprite.java          |   4 +-
 src/proguard/gui/splash/ClipSprite.java            |   4 +-
 src/proguard/gui/splash/CompositeSprite.java       |   4 +-
 src/proguard/gui/splash/ImageSprite.java           |   4 +-
 src/proguard/gui/splash/LinearColor.java           |   4 +-
 src/proguard/gui/splash/LinearDouble.java          |   4 +-
 src/proguard/gui/splash/LinearInt.java             |   4 +-
 src/proguard/gui/splash/LinearTiming.java          |   4 +-
 src/proguard/gui/splash/OverrideGraphics2D.java    |   4 +-
 src/proguard/gui/splash/RectangleSprite.java       |   4 +-
 src/proguard/gui/splash/SawToothTiming.java        |   4 +-
 src/proguard/gui/splash/ShadowedSprite.java        |   4 +-
 src/proguard/gui/splash/SineTiming.java            |   4 +-
 src/proguard/gui/splash/SmoothTiming.java          |   4 +-
 src/proguard/gui/splash/SplashPanel.java           |   4 +-
 src/proguard/gui/splash/Sprite.java                |   4 +-
 src/proguard/gui/splash/TextSprite.java            |   4 +-
 src/proguard/gui/splash/TimeSwitchSprite.java      |   4 +-
 src/proguard/gui/splash/Timing.java                |   4 +-
 src/proguard/gui/splash/TypeWriterString.java      |   4 +-
 src/proguard/gui/splash/VariableColor.java         |   4 +-
 src/proguard/gui/splash/VariableDouble.java        |   4 +-
 src/proguard/gui/splash/VariableFont.java          |   4 +-
 src/proguard/gui/splash/VariableInt.java           |   4 +-
 src/proguard/gui/splash/VariableSizeFont.java      |   4 +-
 src/proguard/gui/splash/VariableString.java        |   4 +-
 src/proguard/io/CascadingDataEntryWriter.java      |   4 +-
 src/proguard/io/ClassFileFilter.java               |   4 +-
 src/proguard/io/ClassFileReader.java               |  18 +-
 src/proguard/io/ClassFileRewriter.java             |   4 +-
 src/proguard/io/DataEntry.java                     |   4 +-
 src/proguard/io/DataEntryCopier.java               |   4 +-
 src/proguard/io/DataEntryPump.java                 |   4 +-
 src/proguard/io/DataEntryReader.java               |   4 +-
 src/proguard/io/DataEntryWriter.java               |   4 +-
 src/proguard/io/DirectoryPump.java                 |   6 +-
 src/proguard/io/DirectoryWriter.java               |   4 +-
 src/proguard/io/FileDataEntry.java                 |   4 +-
 src/proguard/io/FilteredDataEntryReader.java       |  22 +-
 src/proguard/io/FilteredDataEntryWriter.java       |   4 +-
 src/proguard/io/Finisher.java                      |   4 +-
 src/proguard/io/JarReader.java                     |   4 +-
 src/proguard/io/JarWriter.java                     |   4 +-
 src/proguard/io/ParentDataEntryWriter.java         |   4 +-
 src/proguard/io/RenamedDataEntry.java              |   4 +-
 src/proguard/io/ZipDataEntry.java                  |   4 +-
 src/proguard/obfuscate/AttributeShrinker.java      |   4 +-
 src/proguard/obfuscate/AttributeUsageMarker.java   |   4 +-
 src/proguard/obfuscate/ClassFileObfuscator.java    |   4 +-
 src/proguard/obfuscate/ClassFileOpener.java        |   4 +-
 src/proguard/obfuscate/ClassFileRenamer.java       |   4 +-
 src/proguard/obfuscate/DictionaryNameFactory.java  |   4 +-
 src/proguard/obfuscate/MapCleaner.java             |   4 +-
 src/proguard/obfuscate/MappingKeeper.java          |  72 ++-
 src/proguard/obfuscate/MappingPrinter.java         |   4 +-
 src/proguard/obfuscate/MappingProcessor.java       |   4 +-
 src/proguard/obfuscate/MappingReader.java          |   4 +-
 src/proguard/obfuscate/MemberInfoNameCleaner.java  |   4 +-
 .../obfuscate/MemberInfoNameCollector.java         |  19 +-
 .../obfuscate/MemberInfoNameConflictFilter.java    |   5 +-
 src/proguard/obfuscate/MemberInfoObfuscator.java   | 102 ++--
 .../obfuscate/MemberInfoSpecialNameFilter.java     |   4 +-
 src/proguard/obfuscate/MultiMappingProcessor.java  |   4 +-
 src/proguard/obfuscate/NameAndTypeShrinker.java    |   4 +-
 src/proguard/obfuscate/NameAndTypeUsageMarker.java |   4 +-
 src/proguard/obfuscate/NameFactory.java            |   4 +-
 src/proguard/obfuscate/NameFactoryResetter.java    |   4 +-
 src/proguard/obfuscate/NameMarker.java             |  10 +-
 src/proguard/obfuscate/Obfuscator.java             | 220 +++++---
 src/proguard/obfuscate/SimpleNameFactory.java      |   4 +-
 src/proguard/obfuscate/SourceFileRenamer.java      |   4 +-
 src/proguard/obfuscate/SpecialNameFactory.java     |   4 +-
 src/proguard/obfuscate/Utf8Shrinker.java           |   4 +-
 src/proguard/obfuscate/Utf8UsageMarker.java        |   4 +-
 src/proguard/optimize/ChangedCodePrinter.java      |   4 +-
 src/proguard/optimize/KeepMarker.java              |  25 +-
 src/proguard/optimize/MethodOptimizationInfo.java  |   8 +-
 .../optimize/MethodOptimizationInfoSetter.java     |   4 +-
 .../optimize/NoSideEffectMethodMarker.java         |  22 +-
 src/proguard/optimize/NonPrivateMethodMarker.java  |   4 +-
 src/proguard/optimize/Optimizer.java               |  20 +-
 src/proguard/optimize/ParameterShrinker.java       |   4 +-
 src/proguard/optimize/ParameterUsageMarker.java    |   4 +-
 .../optimize/SideEffectInstructionChecker.java     |  52 +-
 src/proguard/optimize/SideEffectMethodMarker.java  |   4 +-
 src/proguard/optimize/VariableUsageMarker.java     |   4 +-
 src/proguard/optimize/WriteOnlyFieldFilter.java    |   4 +-
 src/proguard/optimize/WriteOnlyFieldMarker.java    |   4 +-
 src/proguard/optimize/evaluation/BranchUnit.java   |   4 +-
 .../optimize/evaluation/EvaluationSimplifier.java  | 626 ++++++++++++---------
 .../optimize/evaluation/PartialEvaluator.java      | 328 +++++++----
 src/proguard/optimize/evaluation/Processor.java    |  16 +-
 src/proguard/optimize/evaluation/Stack.java        |   4 +-
 .../optimize/evaluation/TracedBranchUnit.java      |   4 +-
 src/proguard/optimize/evaluation/TracedStack.java  |   4 +-
 .../optimize/evaluation/TracedVariables.java       |   4 +-
 .../evaluation/UnusedParameterCleaner.java         |   6 +-
 src/proguard/optimize/evaluation/Variables.java    |   4 +-
 .../optimize/evaluation/value/Category1Value.java  |   4 +-
 .../optimize/evaluation/value/Category2Value.java  |   4 +-
 .../optimize/evaluation/value/DoubleValue.java     |   4 +-
 .../evaluation/value/DoubleValueFactory.java       |   4 +-
 .../optimize/evaluation/value/FloatValue.java      |   4 +-
 .../evaluation/value/FloatValueFactory.java        |   4 +-
 .../evaluation/value/InstructionOffsetValue.java   |   4 +-
 .../value/InstructionOffsetValueFactory.java       |   4 +-
 .../optimize/evaluation/value/IntegerValue.java    |   4 +-
 .../evaluation/value/IntegerValueFactory.java      |   4 +-
 .../optimize/evaluation/value/LongValue.java       |   4 +-
 .../evaluation/value/LongValueFactory.java         |   4 +-
 .../optimize/evaluation/value/ReferenceValue.java  |   4 +-
 .../evaluation/value/ReferenceValueFactory.java    |   4 +-
 .../value/SpecificArrayReferenceValue.java         |   4 +-
 .../evaluation/value/SpecificDoubleValue.java      |   4 +-
 .../evaluation/value/SpecificFloatValue.java       |   4 +-
 .../evaluation/value/SpecificIntegerValue.java     |   8 +-
 .../evaluation/value/SpecificLongValue.java        |   4 +-
 .../evaluation/value/SpecificReferenceValue.java   |   4 +-
 src/proguard/optimize/evaluation/value/Value.java  |   4 +-
 .../optimize/evaluation/value/ValueFactory.java    |   4 +-
 .../optimize/peephole/BranchTargetFinder.java      | 114 +++-
 .../optimize/peephole/ClassFileFinalizer.java      |   6 +-
 .../optimize/peephole/GetterSetterInliner.java     |   6 +-
 .../optimize/peephole/GotoCommonCodeReplacer.java  |  67 ++-
 .../optimize/peephole/GotoGotoReplacer.java        |   6 +-
 .../optimize/peephole/GotoReturnReplacer.java      |   6 +-
 .../optimize/peephole/LoadStoreRemover.java        |   6 +-
 .../optimize/peephole/MethodPrivatizer.java        |  10 +-
 src/proguard/optimize/peephole/NopRemover.java     |   6 +-
 src/proguard/optimize/peephole/PushPopRemover.java |   6 +-
 .../peephole/SingleImplementationFixer.java        |   4 +-
 .../peephole/SingleImplementationInliner.java      |   4 +-
 .../peephole/SingleImplementationMarker.java       |   6 +-
 .../optimize/peephole/StoreLoadReplacer.java       |   6 +-
 src/proguard/retrace/ReTrace.java                  |   4 +-
 src/proguard/retrace/StackTrace.java               |   4 +-
 src/proguard/retrace/StackTraceItem.java           |   4 +-
 src/proguard/shrink/ClassFileShrinker.java         |   4 +-
 src/proguard/shrink/InnerUsageMarker.java          |   4 +-
 src/proguard/shrink/InterfaceUsageMarker.java      |   4 +-
 src/proguard/shrink/ShortestUsageMark.java         |   4 +-
 src/proguard/shrink/ShortestUsageMarker.java       |   4 +-
 src/proguard/shrink/ShortestUsagePrinter.java      |   4 +-
 src/proguard/shrink/Shrinker.java                  |   8 +-
 src/proguard/shrink/UsageMarker.java               |  41 +-
 src/proguard/shrink/UsagePrinter.java              |   4 +-
 src/proguard/shrink/UsedClassFileFilter.java       |   4 +-
 src/proguard/util/BasicListMatcher.java            |   5 +-
 src/proguard/util/BasicMatcher.java                |   3 +-
 src/proguard/util/ClassNameListMatcher.java        |   3 +-
 src/proguard/util/ClassNameMatcher.java            |  10 +-
 src/proguard/util/ExtensionMatcher.java            |   7 +-
 src/proguard/util/FileNameListMatcher.java         |   3 +-
 src/proguard/util/FileNameMatcher.java             |   4 +-
 src/proguard/util/ListUtil.java                    |   4 +-
 src/proguard/wtk/ProGuardObfuscator.java           |   4 +-
 398 files changed, 5515 insertions(+), 2757 deletions(-)

diff --git a/README b/README
index b1e8fb5..1eb1a01 100644
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
-ProGuard, Java class file shrinker and obfuscator
-=================================================
+ProGuard, Java class file shrinker, optimizer, and obfuscator
+=============================================================
 
 This distribution contains the following directories:
 
@@ -51,4 +51,4 @@ Enjoy!
 
 http://proguard.sourceforge.net/
 
-Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
diff --git a/docs/FAQ.html b/docs/FAQ.html
index 2574a68..2b9d6f4 100644
--- a/docs/FAQ.html
+++ b/docs/FAQ.html
@@ -19,7 +19,8 @@
     support?</a>
 <li><a href="#commercial">Can I use <b>ProGuard</b> to process my commercial
     application?</a>
-<li><a href="#jdk1.4">Does <b>ProGuard</b> work with JDK1.4? JDK5.0?</a>
+<li><a href="#jdk1.4">Does <b>ProGuard</b> work with JDK1.4? JDK5.0?
+    JDK6.0?</a>
 <li><a href="#j2me">Does <b>ProGuard</b> work with J2ME?</a>
 <li><a href="#ant">Does <b>ProGuard</b> have support for Ant?</a>
 <li><a href="#gui">Does <b>ProGuard</b> come with a GUI?</a>
@@ -85,8 +86,13 @@ the virtual machine on which the code is executed. Simple virtual machines may
 benefit more than advanced virtual machines with sophisticated JIT compilers.
 At the very least, your bytecode may become a bit smaller.
 <p>
-A notable optimization that isn't supported yet is the inlining of constant
-fields that are not marked as final.
+Some notable optimizations that aren't supported yet:
+<ul>
+<li>Inlining of constant fields that are not marked as final.
+<li>Inlining of other methods than getters and setters.
+<li>Moving constant expressions out of loops.
+<li>Optimizations that require escape analysis.
+</ul>
 
 <a name="commercial"> </a>
 <h3>Can I use <b>ProGuard</b> to process my commercial application?</h3>
@@ -95,12 +101,15 @@ doesn't affect the programs that you process. Your code remains yours, and
 its license can remain the same.
 
 <a name="jdk1.4"> </a>
-<h3>Does <b>ProGuard</b> work with JDK1.4? JDK5.0?</h3>
-Yes. Class files compiled with JDK1.4 are targeted at JRE1.2 by default. Class
-files compiled with JDK5.0 may have additional attributes for supporting
-generics and annotations. The compiled class files have slightly different
-structures from older class files. <b>ProGuard</b> handles all versions
-correctly.
+<h3>Does <b>ProGuard</b> work with JDK1.4? JDK5.0? JDK6.0?</h3>
+Yes, <b>ProGuard</b> supports all JDKs up to and including 6.0. Class files
+compiled with JDK1.4 are targeted at JRE1.2 by default. Class files compiled
+with JDK5.0 may have additional attributes for generics and annotations. The
+compiled class files have slightly different structures from older class
+files. <b>ProGuard</b> handles all versions correctly.
+<p>
+The upcoming <b>ProGuard 4.0</b> supports preverification, which improves the
+start-up performance in JDK6.0.
 
 <a name="j2me"> </a>
 <h3>Does <b>ProGuard</b> work with J2ME?</h3>
@@ -196,7 +205,7 @@ Manual</a> for more details.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/GPL_exception.html b/docs/GPL_exception.html
index 4c53f2a..88cbe60 100644
--- a/docs/GPL_exception.html
+++ b/docs/GPL_exception.html
@@ -7,7 +7,7 @@
 <H1>Special Exception to the GNU General Public License</H1>
 
 <P>
-Copyright © 2002-2005 Eric Lafortune
+Copyright © 2002-2006 Eric Lafortune
 </P>
 
 <P>
@@ -31,14 +31,20 @@ Place, Suite 330, Boston, MA 02111-1307 USA
 
 <P>
 In addition, as a special exception, Eric Lafortune gives permission to link
-the code of this program with the following stand-alone applications: Apache
-Ant, the Eclipse IDE, the Sun NetBeans IDE, the Sun J2ME Wireless Toolkit, and
-the Javaground Tools, and distribute linked combinations including the two.
-You must obey the GNU General Public License in all respects for all of the
-code used other than these programs. If you modify this file, you may extend
-this exception to your version of the file, but you are not obligated to do
-so. If you do not wish to do so, delete this exception statement from your
-version.
+the code of this program with the following stand-alone applications:
+<ul>
+<li>Apache Ant,
+<li>Apache Maven,
+<li>the Eclipse IDE,
+<li>the Sun NetBeans IDE,
+<li>the Sun J2ME Wireless Toolkit, and
+<li>the Javaground Tools,
+</ul>
+and distribute linked combinations including the two. You must obey the GNU
+General Public License in all respects for all of the code used other than
+these programs. If you modify this file, you may extend this exception to your
+version of the file, but you are not obligated to do so. If you do not wish to
+do so, delete this exception statement from your version.
 </P>
 
 </BODY>
diff --git a/docs/acknowledgements.html b/docs/acknowledgements.html
index f89f418..12e089b 100644
--- a/docs/acknowledgements.html
+++ b/docs/acknowledgements.html
@@ -1,3 +1,4 @@
+
 <!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
 <html>
 <head>
@@ -18,9 +19,20 @@ shrinker, optimizer, and obfuscator. At this point, both programs have little
 code in common.
 <p>
 
-Dirk Schnelle has generously contributed and maintained the first versions of
-the Ant task. I have rewritten the implementation for version 3.0, but the
-XML schema is still based on his work.
+Dirk Schnelle has contributed and maintained the first versions of the Ant
+task. I have rewritten the implementation for version 3.0, but the XML schema
+is still based on his work.
+<p>
+
+Since its first public release, many people have expressed their enthusiasm and
+have chimed in with interesting ideas, bug reports, and bug fixes: Thorsten
+Heit, Oliver Retzl, Jonathan Knudsen, Tarcisio Camara, Bob Drury, Dave Jarvis,
+Marc Chapman, Dave Morehouse, Richard Osbaldeston, Peter Hawkins, Mark
+Sherington, David Sitsky, James Manning, Ptolemy Oberin, Frank-Michael Moser,
+QZ Shines, Thomas Singer, Michele Puccini, Roman Bednarek, Natalia Pujol,
+Daniel Sjöblom, Jan Filipsky, Charles Smith, Gerrit Telkamp, Noel
+Grandin, Torbjörn Söderstedt, Clemens Eisserer, Clark Bassett,
+and many others. Thanks! Your feedback has been invaluable.
 <p>
 
 I am developing ProGuard in my spare time, in part on equipment that my
@@ -29,28 +41,21 @@ allowing me to use.
 <p>
 
 <a href="http://sourceforge.net/forum/projects/proguard/"
-target="other">SourceForge</a> is graciously providing the resources for
+target="other">SourceForge</a> is generously providing the resources for
 hosting this project and many other projects.
 <p>
 
-My colleagues at Luciad have been very patient trying early versions of the
-code. Since the first public release, others have chimed in with interesting
-ideas, bug reports, and bug fixes: Thorsten Heit, Oliver Retzl, Jonathan
-Knudsen, Bob Drury, Dave Jarvis, Marc Chapman, Dave Morehouse, Richard
-Osbaldeston, Peter Hawkins, Mark Sherington, David Sitsky, James Manning,
-Ptolemy Oberin, Frank-Michael Moser, QZ Shines, Thomas Singer, Michele
-Puccini, Roman Bednarek, Natalia Pujol, Daniel Sjöblom, Jan Filipsky,
-Charles Smith, and Gerrit Telkamp.
-Thanks! Your feedback has been invaluable.
+JetBrains is kindly providing a license for its IntelliJ IDEA development
+environment.
 <p>
 
-The code and these web pages were written using Sun's JDKs, IBM Eclipse, Linux,
-GNU emacs, bash, sed, awk, and a whole host of other free tools which continue
+The code and these web pages were written using Sun's JDKs, Linux, IntelliJ
+IDEA, GNU emacs, bash, sed, awk, and a whole host of other tools that continue
 to make programming interesting.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 
diff --git a/docs/alternatives.html b/docs/alternatives.html
index 379b211..f2f594d 100644
--- a/docs/alternatives.html
+++ b/docs/alternatives.html
@@ -11,8 +11,8 @@
 <h2>Alternatives</h2>
 
 There are quite a few Java class file shrinkers, optimizers, and obfuscators
-out there. Users of <b>ProGuard</b> tell me it compares with the best of them.
-However, you may want to check that out yourself.
+out there. Users of <b>ProGuard</b> tell me it easily compares with the best
+of them. However, you may want to check that out yourself.
 <p>
 This is a list of the programs of which I'm aware. Obviously, I've never
 personally tested all of them. Many programs, even commercial ones, have been
@@ -34,7 +34,7 @@ incorrect.
 
 <tr>
 <td><a target="other" href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a></td>
-<td><a target="other" href="http://proguard.sourceforge.net/">ProGuard</a></td>
+<td><a target="_top" href="http://proguard.sourceforge.net/">ProGuard</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -43,7 +43,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.informatik.uni-oldenburg.de/leute/hoenicke.html">Jochen Hoenicke</a></td>
-<td><a target="other" rel="nofollow" href="http://jode.sourceforge.net/">Jode</a></td>
+<td><a target="other" href="http://jode.sourceforge.net/">Jode</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -52,7 +52,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.nq4.de/">NQ4</a></td>
-<td><a target="other" rel="nofollow" href="http://www.nq4.de/">Joga</a></td>
+<td><a target="other" href="http://www.nq4.de/">Joga</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -60,8 +60,17 @@ incorrect.
 </tr>
 
 <tr>
+<td><a target="other" rel="nofollow" href="http://www.cs.cornell.edu/nystrom/">Nate Nystrom</a></td>
+<td><a target="other" href="http://www.cs.purdue.edu/homes/hosking/bloat/">Bloat</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><br></td>
+<td>Free</td>
+</tr>
+
+<tr>
 <td><a target="other" rel="nofollow" href="http://sourceforge.net/users/hchacha/">Hidetoshi Ohuchi</a></td>
-<td><a target="other" rel="nofollow" href="http://jarg.sourceforge.net/">Jarg</a></td>
+<td><a target="other" href="http://jarg.sourceforge.net/">Jarg</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -70,7 +79,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.geocities.com/CapeCanaveral/Hall/2334/resume.html">Alexander Shvets</a></td>
-<td><a target="other" rel="nofollow" href="http://www.geocities.com/CapeCanaveral/Hall/2334/Programs/cafebabe.html">CafeBabe</a></td>
+<td><a target="other" href="http://www.geocities.com/CapeCanaveral/Hall/2334/Programs/cafebabe.html">CafeBabe</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -78,17 +87,26 @@ incorrect.
 </tr>
 
 <tr>
-<td><a target="other" rel="nofollow" href="http://www.cs.cornell.edu/nystrom/">Nate Nystrom</a></td>
-<td><a target="other" rel="nofollow" href="http://www.cs.purdue.edu/homes/hosking/bloat/">Bloat</a></td>
+<td><a target="other" rel="nofollow" href="http://www.yworks.com/">yWorks</a></td>
+<td><a target="other" href="http://www.yworks.com/en/products_yguard_about.htm">yGuard</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td>Free (no source)</td>
+</tr>
+
+<tr>
+<td><a target="other" rel="nofollow" href="http://donquixote.cafebabe.jp/">Haruaki Tamada</a></td>
+<td><a target="other" href="http://donquixote.cafebabe.jp/">DonQuixote</a></td>
 <td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td>Free</td>
 </tr>
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.cs.purdue.edu/homes/grothoff/">Christian Grothoff</a></td>
-<td><a target="other" rel="nofollow" href="http://www.ovmj.org/jamit/">Jamit</a></td>
+<td><a target="other" href="http://www.ovmj.org/jamit/">Jamit</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
@@ -97,7 +115,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.riggshill.com/">RiggsHill Software</a></td>
-<td><a target="other" rel="nofollow" href="http://genjar.sourceforge.net/">GenJar</a></td>
+<td><a target="other" href="http://genjar.sourceforge.net/">GenJar</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
@@ -106,7 +124,16 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://sadun-util.sourceforge.net/">Cristiano Sadun</a></td>
-<td><a target="other" rel="nofollow" href="http://sadun-util.sourceforge.net/pack.html">Pack</a></td>
+<td><a target="other" href="http://sadun-util.sourceforge.net/pack.html">Pack</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><br></td>
+<td align="center"><br></td>
+<td>Free (LGPL)</td>
+</tr>
+
+<tr>
+<td><a target="other" rel="nofollow" href="http://darcs.brianweb.net/">Brian Alliet</a></td>
+<td><a target="other" href="http://darcs.brianweb.net/gcclass/">Gcclass</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
@@ -115,7 +142,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.sable.mcgill.ca/">Sable</a></td>
-<td><a target="other" rel="nofollow" href="http://www.sable.mcgill.ca/soot/">Soot</a></td>
+<td><a target="other" href="http://www.sable.mcgill.ca/soot/">Soot</a></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
@@ -123,17 +150,17 @@ incorrect.
 </tr>
 
 <tr>
-<td><a target="other" rel="nofollow" href="http://www.utdallas.edu/~gxz014000/">Bajie</a></td>
-<td><a target="other" rel="nofollow" href="http://www.utdallas.edu/~gxz014000/jcmp/">JCMP</a></td>
+<td><a target="other" rel="nofollow" href="http://www.garret.ru/~knizhnik/">Konstantin Knizhnik</a></td>
+<td><a target="other" href="http://www.garret.ru/~knizhnik/javago/ReadMe.htm">JavaGO</a></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><br></td>
 <td>Free</td>
 </tr>
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://sourceforge.net/users/glurk/">Thorsten Heit</a></td>
-<td><a target="other" rel="nofollow" href="http://sourceforge.net/projects/javaguard/">JavaGuard</a></td>
+<td><a target="other" href="http://sourceforge.net/projects/javaguard/">JavaGuard</a></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -142,7 +169,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://mwobfu.sourceforge.net/">Patrick Mueller</a></td>
-<td><a target="other" rel="nofollow" href="http://mwobfu.sourceforge.net/">Mwobfu</a></td>
+<td><a target="other" href="http://mwobfu.sourceforge.net/">Mwobfu</a></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -150,8 +177,8 @@ incorrect.
 </tr>
 
 <tr>
-<td><a target="other" rel="nofollow" href="http://www.yworks.com/">yWorks</a></td>
-<td><a target="other" rel="nofollow" href="http://www.yworks.com/en/products_yguard_about.htm">yGuard</a></td>
+<td><a target="other" rel="nofollow" href="http://www.elegant-software.com/">Elegant Software</a></td>
+<td><a target="other" href="http://www.elegant-software.com/software/jmangle/">JMangle</a></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -159,8 +186,17 @@ incorrect.
 </tr>
 
 <tr>
+<td><a target="other" rel="nofollow" href="http://www.bebbosoft.de/">BebboSoft</a></td>
+<td><a target="other" href="http://www.bebbosoft.de/index.html#java/mug/index.html">Bb_mug</a></td>
+<td align="center"><br></td>
+<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td>Free (no source)</td>
+</tr>
+
+<tr>
 <td><a target="other" rel="nofollow" href="http://www.drjava.de/">Dr. Java</a></td>
-<td><a target="other" rel="nofollow" href="http://www.drjava.de/obfuscator/">Marvin Obfuscator</a></td>
+<td><a target="other" href="http://www.drjava.de/obfuscator/">Marvin Obfuscator</a></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -168,8 +204,8 @@ incorrect.
 </tr>
 
 <tr>
-<td><a target="other" rel="nofollow" href="http://www.alphaworks.ibm.com/">IBM AlphaWorks</a></td>
-<td><a target="other" rel="nofollow" href="http://www.alphaworks.ibm.com/tech/jax/">JAX</a></td>
+<td><a target="other" rel="nofollow" href="http://www.ibm.com/">IBM</a></td>
+<td><a target="other" href="http://www-306.ibm.com/software/wireless/wsdd/">WSDD</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -178,7 +214,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.preemptive.com/">PreEmptive</a></td>
-<td><a target="other" rel="nofollow" href="http://www.preemptive.com/products.html">DashOPro</a></td>
+<td><a target="other" href="http://www.preemptive.com/products/dasho/index.html">DashOPro</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -187,7 +223,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.zelix.com/">Zelix</a></td>
-<td><a target="other" rel="nofollow" href="http://www.zelix.com/klassmaster/index.html">KlassMaster</a></td>
+<td><a target="other" href="http://www.zelix.com/klassmaster/index.html">KlassMaster</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -196,7 +232,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.s5systems.com/">S5 Systems</a></td>
-<td><a target="other" rel="nofollow" href="http://www.s5systems.com/jPresto.htm">jPresto</a></td>
+<td><a target="other" href="http://www.s5systems.com/jPresto.htm">jPresto</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -205,7 +241,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.retrologic.com/">RetroLogic</a></td>
-<td><a target="other" rel="nofollow" href="http://www.retrologic.com/">RetroGuard</a></td>
+<td><a target="other" href="http://www.retrologic.com/">RetroGuard</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -214,7 +250,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.codingart.com/">CodingArt</a></td>
-<td><a target="other" rel="nofollow" href="http://www.codingart.com/codeshield.html">CodeShield</a></td>
+<td><a target="other" href="http://www.codingart.com/codeshield.html">CodeShield</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -223,7 +259,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.e-t.com/">Eastridge Technology</a></td>
-<td><a target="other" rel="nofollow" href="http://www.e-t.com/jshrink.html">Jshrink</a></td>
+<td><a target="other" href="http://www.e-t.com/jshrink.html">Jshrink</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -232,7 +268,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.helseth.com/">Helseth</a></td>
-<td><a target="other" rel="nofollow" href="http://www.helseth.com/HJO.htm">JObfuscator</a></td>
+<td><a target="other" href="http://www.helseth.com/HJO.htm">JObfuscator</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -241,7 +277,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.leesw.com/">LeeSoftware</a></td>
-<td><a target="other" rel="nofollow" href="http://www.leesw.com/">Smokescreen Obfuscator</a></td>
+<td><a target="other" href="http://www.leesw.com/">Smokescreen Obfuscator</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -250,7 +286,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.vegatech.com/">Vega Technologies</a></td>
-<td><a target="other" rel="nofollow" href="http://www.vegatech.com/jzipper/">JZipper</a></td>
+<td><a target="other" href="http://www.vegatech.com/jzipper/">JZipper</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -258,8 +294,8 @@ incorrect.
 </tr>
 
 <tr>
-<td><a target="other" rel="nofollow" href="http://www.uni-vologda.ac.ru/~c3c/">Sergey Sverdlov</a></td>
-<td><a target="other" rel="nofollow" href="http://www.uni-vologda.ac.ru/~c3c/jco/">J.Class Optimizer</a></td>
+<td><a target="other" rel="nofollow" href="http://www.innaworks.com/">Innaworks</a></td>
+<td><a target="other" href="http://www.innaworks.com/">mBooster</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><br></td>
@@ -267,35 +303,35 @@ incorrect.
 </tr>
 
 <tr>
-<td><a target="other" rel="nofollow" href="http://cs.arizona.edu/">U. of Arizona</a></td>
-<td><a target="other" rel="nofollow" href="http://sandmark.cs.arizona.edu/">SandMark</a></td>
-<td align="center"><br></td>
+<td><a target="other" rel="nofollow" href="http://www.uni-vologda.ac.ru/~c3c/">Sergey Sverdlov</a></td>
+<td><a target="other" href="http://www.uni-vologda.ac.ru/~c3c/jco/">J.Class Optimizer</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><br></td>
 <td>Commercial</td>
 </tr>
 
 <tr>
-<td><a target="other" rel="nofollow" href="http://www.force5.com/">Force 5</a></td>
-<td><a target="other" rel="nofollow" href="http://www.force5.com/">JCloak</a></td>
-<td align="center"><br></td>
+<td><a target="other" rel="nofollow" href="http://www.smardec.com/">Smardec</a></td>
+<td><a target="other" href="//www.allatori.com/">Allatori</a></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td>Commercial</td>
 </tr>
 
 <tr>
-<td><a target="other" rel="nofollow" href="http://www.wingsoft.com/">WingSoft</a></td>
-<td><a target="other" rel="nofollow" href="http://www.wingsoft.com/wingguard.html">WingGuard</a></td>
-<td align="center"><br></td>
+<td><a target="other" rel="nofollow" href="http://cs.arizona.edu/">U. of Arizona</a></td>
+<td><a target="other" href="http://sandmark.cs.arizona.edu/">SandMark</a></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td>Commercial</td>
 </tr>
 
 <tr>
-<td><a target="other" rel="nofollow" href="http://www.jammconsulting.com/">JAMM Consulting</a></td>
-<td><a target="other" rel="nofollow" href="http://www.jammconsulting.com/jamm/servlet/com.jammconsulting.servlet.JAMMServlet?pageId=ObfuscateProPage">ObfuscatePro</a></td>
+<td><a target="other" rel="nofollow" href="http://www.force5.com/">Force 5</a></td>
+<td><a target="other" href="http://www.force5.com/">JCloak</a></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -303,8 +339,8 @@ incorrect.
 </tr>
 
 <tr>
-<td><a target="other" rel="nofollow" href="http://www.2lkit.com/">2LKit</a></td>
-<td><a target="other" rel="nofollow" href="http://www.2lkit.com/products/2LKitObf/index.htm">2LKit Obfuscator</a></td>
+<td><a target="other" rel="nofollow" href="http://www.semdesigns.com/">Semantic Designs</a></td>
+<td><a target="other" href="http://www.semdesigns.com/Products/Obfuscators/JavaObfuscator.html">Obfuscator</a></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -313,7 +349,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.duckware.com/">Duckware</a></td>
-<td><a target="other" rel="nofollow" href="http://www.duckware.com/jobfuscate/">Jobfuscate</a></td>
+<td><a target="other" href="http://www.duckware.com/jobfuscate/">Jobfuscate</a></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -322,16 +358,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.jproof.com/">JProof</a></td>
-<td><a target="other" rel="nofollow" href="http://www.jproof.com/">JProof</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td>Commercial</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://www.4fang.net/">4Fang</a></td>
-<td><a target="other" rel="nofollow" href="http://www.4fang.net/jmix/">JMix</a></td>
+<td><a target="other" href="http://www.jproof.com/">JProof</a></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -340,16 +367,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.solutia.ro/">GITS</a></td>
-<td><a target="other" rel="nofollow" href="http://www.solutia.ro/pages/javadc/">Blurfuscator</a></td>
-<td align="center"><br></td>
-<td align="center"><br></td>
-<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
-<td>Commercial</td>
-</tr>
-
-<tr>
-<td><a target="other" rel="nofollow" href="http://www.jdevelop.com/">JDevelop</a></td>
-<td><a target="other" rel="nofollow" href="http://www.jdevelop.com/best-java-obfuscator.html">JSCO</a></td>
+<td><a target="other" href="http://www.solutia.ro/pages/javadc/">Blurfuscator</a></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -358,7 +376,7 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://sourceforge.net/projects/flmobf/">Alain Moran</a></td>
-<td><a target="other" rel="nofollow" href="http://sourceforge.net/projects/flmobf/">flmObf</a></td>
+<td><a target="other" href="http://sourceforge.net/projects/flmobf/">flmObf</a></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -367,14 +385,23 @@ incorrect.
 
 <tr>
 <td><a target="other" rel="nofollow" href="http://www.chez.com/vasile/">Vasile Calmatui</a></td>
-<td><a target="other" rel="nofollow" href="http://www.chez.com/vasile/obfu/VasObfuLite.html">VasObfuLite</a></td>
+<td><a target="other" href="http://www.chez.com/vasile/obfu/VasObfuLite.html">VasObfuLite</a></td>
 <td align="center"><br></td>
 <td align="center"><br></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
 <td>Free</td>
 </tr>
 
-<tr>
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.alphaworks.ibm.com/">IBM AlphaWorks</a></td>
+<td><a target="other" href="http://www.research.ibm.com/jax/">JAX</a></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td>(discontinued)</td>
+</tr>
+
+<tr class="disappeared">
 <td><a target="other" rel="nofollow" href="http://www-i2.informatik.rwth-aachen.de/~markusj/">Markus Jansen</a></td>
 <td><a target="other" rel="nofollow" href="http://www-i2.informatik.rwth-aachen.de/~markusj/jopt/">Jopt</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -383,7 +410,7 @@ incorrect.
 <td>(disappeared?)</td>
 </tr>
 
-<tr>
+<tr class="disappeared">
 <td><a target="other" rel="nofollow" href="http://www.primenet.com/~ej">Eron Jokipii</a></td>
 <td><a target="other" rel="nofollow" href="http://www.primenet.com/~ej">Jobe</a></td>
 <td align="center"><br></td>
@@ -392,7 +419,7 @@ incorrect.
 <td>(disappeared?)</td>
 </tr>
 
-<tr>
+<tr class="disappeared">
 <td><a target="other" rel="nofollow" href="http://jrc.krdl.org.sg/">JRC</a></td>
 <td><a target="other" rel="nofollow" href="http://jrc.krdl.org.sg/decaf/">DeCaf</a></td>
 <td align="center"><br></td>
@@ -401,7 +428,16 @@ incorrect.
 <td>(disappeared?)</td>
 </tr>
 
-<tr>
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.utdallas.edu/~gxz014000/">Bajie</a></td>
+<td><a target="other" rel="nofollow" href="http://www.utdallas.edu/~gxz014000/jcmp/">JCMP</a></td>
+<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td>(disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
 <td><a target="other" rel="nofollow" href="http://www.plumbdesign.com/">Plumb Design</a></td>
 <td><a target="other" rel="nofollow" href="http://www.condensity.com/">Condensity</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -410,7 +446,16 @@ incorrect.
 <td>Commercial (discontinued)</td>
 </tr>
 
-<tr>
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.jammconsulting.com/">JAMM Consulting</a></td>
+<td><a target="other" rel="nofollow" href="http://www.jammconsulting.com/jamm/servlet/com.jammconsulting.servlet.JAMMServlet?pageId=ObfuscateProPage">ObfuscatePro</a></td>
+<td align="center"><br></td>
+<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td>Commercial (discontinued?)</td>
+</tr>
+
+<tr class="disappeared">
 <td><a target="other" rel="nofollow" href="http://www.4thpass.com/">4th Pass</a></td>
 <td><a target="other" rel="nofollow" href="http://www.4thpass.com/">SourceGuard</a></td>
 <td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
@@ -419,7 +464,43 @@ incorrect.
 <td>Commercial (discontinued?)</td>
 </tr>
 
-<tr>
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.jdevelop.com/">JDevelop</a></td>
+<td><a target="other" rel="nofollow" href="http://www.jdevelop.com/best-java-obfuscator.html">JSCO</a></td>
+<td align="center"><br></td>
+<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td>Commercial (discontinued?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.4fang.net/">4Fang</a></td>
+<td><a target="other" rel="nofollow" href="http://www.4fang.net/jmix/">JMix</a></td>
+<td align="center"><br></td>
+<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td>Commercial (discontinued?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.2lkit.com/">2LKit</a></td>
+<td><a target="other" rel="nofollow" href="http://www.2lkit.com/products/2LKitObf/index.htm">2LKit Obfuscator</a></td>
+<td align="center"><br></td>
+<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td>Commercial (disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
+<td><a target="other" rel="nofollow" href="http://www.wingsoft.com/">WingSoft</a></td>
+<td><a target="other" rel="nofollow" href="http://www.wingsoft.com/wingguard.html">WingGuard</a></td>
+<td align="center"><br></td>
+<td align="center"><br></td>
+<td align="center"><img src="checkmark.gif" width="11" height="11" alt="x"></td>
+<td>Commercial (disappeared?)</td>
+</tr>
+
+<tr class="disappeared">
 <td><a target="other" rel="nofollow" href="http://www.sbktech.org/">HashJava</a></td>
 <td><a target="other" rel="nofollow" href="http://www.sbktech.org/">HashJava</a></td>
 <td align="center"><br></td>
@@ -434,7 +515,7 @@ All trademarks are property of their respective holders.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 
diff --git a/docs/downloads.html b/docs/downloads.html
index b548248..b6340f1 100644
--- a/docs/downloads.html
+++ b/docs/downloads.html
@@ -1,3 +1,4 @@
+
 <!doctype html PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
 <html>
 <head>
@@ -11,12 +12,12 @@
 <h2>Downloads</h2>
 
 <b>ProGuard</b> is distributed under the GNU General Public License.
-Please refer to the <a href="license.html">license page</a> for more details.
+Please consult the <a href="license.html">license page</a> for more details.
 <p>
 <b>ProGuard</b> is written in Java. It requires a Java 2 runtime environment.
 <p>
 You can download the latest release (containing the program jar, the
-documentation you're reading now, examples, and source code) from this
+documentation you're reading now, examples, and the source code) from this
 location:
 <p>
 <center><a href="http://sourceforge.net/project/showfiles.php?group_id=54750"
@@ -29,16 +30,109 @@ If you're still working with an older version of <b>ProGuard</b>, check out
 the summary of changes below, to see if you're missing something essential.
 Better look at the up-to-date <a
 href="http://proguard.sourceforge.net/downloads.html">on-line version</a> if
-you're reading a local copy of this page. The download section may also contain
-updates with sub-minor version numbers. These versions are typically released
-shortly after their parent versions, for applying emergency fixes.
+you're reading a local copy of this page.
+<p>
+The download section may also contain updates with sub-minor version numbers.
+These versions are typically released shortly after their parent versions, for
+applying emergency fixes. Please make sure to look at those if you are
+encountering any problems with recent releases.
+<p>
+Finally, there may be beta versions of upcoming releases. They may be of
+interest too, because they typically contain any less urgent bug fixes
+collected since the previous release.
 <p>
 
-<h3>Version 3.4</h3>
+<font color="darkgrey">
+<h3><div>In alpha</div> Version 4.0</h3>
+<ul>
+<li>Added preverifier for Java 6 and Java Micro Edition, with new option
+    <code>-dontpreverify</code>.
+<li>Added new option <code>-target</code> to modify java version of processed
+    class files.
+<li>Made <code>-keep</code> options more orthogonal and flexible, with option
+    modifiers <code>allowshrinking</code>, <code>allowoptimization</code>, and
+    <code>allowobfuscation</code>.
+<li>Added support for configuration by means of annotations.
+<li>Improved shrinking of unused annotations.
+<li>Added check on modification times of input and output, to avoid unnecessary
+    processing, with new option <code>-forceprocessing</code>.
+<li>Added new options <code>-flattenpackagehierarchy</code> and
+    <code>-repackageclasses</code> (replacing <code>-defaultpackage</code>) to
+    control obfuscation of packages names.
+<li>Now respecting naming rule for nested class names
+    (<code>EnclosingClass$InnerClass</code>) in obfuscation step, if
+    <code>InnerClasses</code> attributes or <code>EnclosingMethod</code>
+    attributes are being kept.
+<li>Added new inter-procedural optimizations: method inlining and propagation
+    of constant fields, constant arguments, and constant return values.
+<li>Added optimized local variable allocation.
+<li>Added many new peephole optimizations.
+<li>Improved making classes and class members public or protected.
+<li>Now printing notes on suspiciously unkept classes in parameters of
+    specified methods.
+<li>Now printing notes for class names that don't seem to be fully qualified.
+<li>Added support for uppercase filename extensions.
+<li>Rewritten class file I/O code.
+<li>TODO: Update documentation and examples.
+</ul>
+</font>
+
+<h3><div>Dec 2006</div> Version 3.7</h3>
+<ul>
+<li>Now accepting Java 6 class files.
+<li>Fixed shrinking of partially used annotations.
+<li>Improved incremental obfuscation, with new option
+    <code>-useuniqueclassmembernames</code>.
+<li>Printing more information in case of conflicting configuration and input.
+<li>Fixed optimization of repeated array length instruction.
+<li>Fixed optimization of subsequent try/catch/finally blocks with return
+    statements.
+<li>Fixed optimization of complex stack operations.
+<li>Fixed optimization of simple infinite loops.
+<li>Fixed optimization of expressions with constant doubles.
+<li>Tuned optimization to improve size reduction after preverification.
+<li>Fixed overflows of offsets in long code blocks.
+<li>Now allowing class names containing dashes.
+<li>Updated documentation and examples.
+</ul>
+
+<h3><div>May 2006</div> Version 3.6</h3>
+<ul>
+<li>No longer automatically keeping classes in parameters of specified methods
+    from obfuscation and optimization (introduced in version 3.4).
+<li>Fixed inlining of interfaces that are used in .class constructs.
+<li>Fixed removal of busy-waiting loops reading volatile fields.
+<li>Fixed optimization of comparisons of known integers.
+<li>Fixed optimization of known branches.
+<li>Fixed optimization of method calls on arrays of interfaces.
+<li>Fixed optimization of method calls without side-effects.
+<li>Fixed optimization of nested try/catch/finally blocks with return
+    statements.
+<li>Fixed initialization of library classes that only appear in descriptors.
+<li>Fixed matching of primitive type wildcards in configuration.
+<li>Fixed the boilerplate specification for enumerations in the GUI.
+<li>Updated documentation and examples.
+</ul>
+
+<h3><div>Jan 2006</div> Version 3.5</h3>
+<ul>
+<li>Fixed obfuscation of class members with complex visibility.
+<li>Fixed optimization bugs causing stack verification errors.
+<li>Fixed optimization bug causing overridden methods to be finalized.
+<li>Fixed optimization bug causing abstract method errors for retro-fitted
+    library methods.
+<li>Fixed optimization bug evaluating code with constant long values.
+<li>Fixed bug in updating of optional local variable table attributes and local
+    variable type table attributes after optimization.
+<li>Fixed interpretation of comma-separated class names without wildcards.
+<li>Updated documentation and examples.
+</ul>
+
+<h3><div>Oct 2005</div> Version 3.4</h3>
 <ul>
 <li>Extended optimizations: removing duplicate code within methods.
 <li>Extended regular expressions for class names to comma-separated lists.
-<li>Now automatically keeping arguments of specified methods.
+<li>Now automatically keeping classes in descriptors of kept class members.
 <li>Added verbose statistics for optimizations.
 <li>Added boilerplate Number optimizations in GUI.
 <li>Fixed <code>Class.forName</code> detection.
@@ -50,7 +144,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 3.3</h3>
+<h3><div>Jun 2005</div> Version 3.3</h3>
 <ul>
 <li>Extended optimizations: making methods private and static when possible,
     making classes static when possible, removing unused parameters.
@@ -72,7 +166,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 3.2</h3>
+<h3><div>Dec 2004</div> Version 3.2</h3>
 <ul>
 <li>Fixed JDK5.0 processing bugs.
 <li>Fixed optimization bugs.
@@ -81,7 +175,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 3.1</h3>
+<h3><div>Nov 2004</div> Version 3.1</h3>
 <ul>
 <li>Improved obfuscation and shrinking of private class members.
 <li>Added inlining of interfaces with single implementations.
@@ -94,7 +188,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 3.0</h3>
+<h3><div>Aug 2004</div> Version 3.0</h3>
 <ul>
 <li>Added bytecode optimization step, between shrinking step and obfuscation
     step.
@@ -125,7 +219,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 2.1</h3>
+<h3><div>Mar 2004</div> Version 2.1</h3>
 <ul>
 <li>Added support for JDK1.5 classes.
 <li>Added additional wildcard for matching primitive types.
@@ -136,7 +230,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 2.0</h3>
+<h3><div>Dec 2003</div> Version 2.0</h3>
 <ul>
 <li>Added a graphical user interface for ProGuard and ReTrace.
 <li>Added <code>-applymapping</code> option for incremental obfuscation.
@@ -151,7 +245,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 1.7</h3>
+<h3><div>Aug 2003</div> Version 1.7</h3>
 <ul>
 <li>Fixed various Ant task bugs.
 <li>Fixed ClassCastException due to explicitly used abstract classes with
@@ -165,7 +259,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 1.6</h3>
+<h3><div>May 2003</div> Version 1.6</h3>
 <ul>
 <li>Added support for Ant.
 <li>Added support for the J2ME Wireless Toolkit.
@@ -180,7 +274,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 1.5</h3>
+<h3><div>Jan 2003</div> Version 1.5</h3>
 <ul>
 <li>Fixed processing of retrofitted library interfaces.
 <li>Fixed processing of <code>.class</code> constructs in internal classes
@@ -190,7 +284,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 1.4</h3>
+<h3><div>Nov 2002</div> Version 1.4</h3>
 <ul>
 <li>Now copying resource files over from the input jars to the output jar.
 <li>Added option to obfuscate using lower-case class names only.
@@ -201,20 +295,20 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 1.3</h3>
+<h3><div>Sep 2002</div> Version 1.3</h3>
 <ul>
 <li>Added support for wildcards in class names.
 <li>Added tool to de-obfuscate stack traces.
 <li>Added options to print processing information to files.
 <li>Added option to rename source file attributes.
-<li>Fixed processing of implicitly used interfaces targeted at JRE1.2 (the
-    default in JDK1.4)
+<li>Fixed proce/home/eric/ProGuard/sf.htmlssing of implicitly used interfaces
+    targeted at JRE1.2 (the default in JDK1.4)
 <li>Fixed processing of configurations with negated access modifiers.
 <li>Fixed duplicate class entry bug.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 1.2</h3>
+<h3><div>Aug 2002</div> Version 1.2</h3>
 <ul>
 <li>Improved speed.
 <li>Fixed processing of classes targeted at JRE1.2 (the default in JDK1.4)
@@ -225,7 +319,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation.
 </ul>
 
-<h3>Version 1.1</h3>
+<h3><div>Jul 2002</div> Version 1.1</h3>
 <ul>
 <li>Added automatic detection of <code>Class.forName("MyClass")</code>,
     <code>MyClass.class</code>, and
@@ -244,7 +338,7 @@ shortly after their parent versions, for applying emergency fixes.
 <li>Updated documentation and examples.
 </ul>
 
-<h3>Version 1.0</h3>
+<h3><div>Jun 2002</div> Version 1.0</h3>
 <ul>
 <li>First public release, based on class parsing code from Mark Welsh's
     <b>RetroGuard</b>.
@@ -252,7 +346,7 @@ shortly after their parent versions, for applying emergency fixes.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 
diff --git a/docs/favicon.ico b/docs/favicon.ico
new file mode 100644
index 0000000..3923ec1
Binary files /dev/null and b/docs/favicon.ico differ
diff --git a/docs/feedback.html b/docs/feedback.html
index d8b1a5f..9979f6f 100644
--- a/docs/feedback.html
+++ b/docs/feedback.html
@@ -58,9 +58,8 @@ ahead:
     href="http://software.freshmeat.net/">FreshMeat</a>.
     <p>
 
-<li>If you have detailed bug reports with attachments, or just some
-    encouragements, or if <b>ProGuard</b> is useful to you and you want to
-    support it with software or hardware, you can mail me directly at
+<li>For anything that doesn't fall in the above categories, you can mail me
+    directly at
 
 <script type="text/javascript" language="JavaScript">
 <!--
@@ -97,14 +96,14 @@ I can't promise a swift answer, or any answer at all, for that matter, but I'd
 love to see your responses.
 <p>
 
-This isn't a typical open source project in the sense that I am not looking
-for code contributions. Developing ProGuard on my own allows me to do things
-my way, without the overhead of project management and the compromises
-associated with larger projects.
+<b>ProGuard</b> isn't a typical open source project, in the sense that I am
+<em>not</em> looking for code contributions. Developing on my own allows me to
+do things my way, without the overhead of project management and the
+compromises associated with larger projects.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 
diff --git a/docs/index.html b/docs/index.html
index 802be28..1682eac 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -4,7 +4,11 @@
 <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="content-script-type" content="text/javascript">
 <meta http-equiv="content-style-type" content="text/css">
+<meta name="author" content="Eric Lafortune">
+<meta name="description" content="ProGuard: java shrinker, optimizer, and obfuscator">
+<meta name="keywords" content="java obfuscator, optimizer, shrinker">
 <link rel="stylesheet" type="text/css" href="style.css">
+<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
 <title>ProGuard</title>
 </head>
 <frameset
@@ -46,9 +50,23 @@
 
 <noframes>
 <body>
+<p class="intro">
+<b>ProGuard</b> is a free Java class file shrinker, optimizer, and obfuscator.
+It can detect and remove unused classes, fields, methods, and attributes. It
+can then optimize bytecode and remove unused instructions. Finally, it can
+rename the remaining classes, fields, and methods using short meaningless
+names. The resulting jars are smaller and harder to reverse-engineer.
+</p>
+<p>
 Your browser doesn't support frames, but that's cool.
 <p>
 You can go straight to the <a href="main.html">main page</a>.
+
+<hr>
+<address>
+Copyright © 2002-2006
+<a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
+</address>
 </body>
 </noframes>
 </html>
diff --git a/docs/license.html b/docs/license.html
index 141704b..395cc42 100644
--- a/docs/license.html
+++ b/docs/license.html
@@ -29,8 +29,8 @@ under the GPL. I am granting a <a href="GPL_exception.html">special
 exception</a> to the latter clause (in wording suggested by the <a
 href="http://www.gnu.org/copyleft/gpl-faq.html#GPLIncompatibleLibs"
 target="other">FSF</a>), for combinations with the following stand-alone
-applications: Apache Ant, the Eclipse IDE, the Sun NetBeans IDE, the Sun J2ME
-Wireless Toolkit, and the Javaground Tools.
+applications: Apache Ant, Apache Maven, the Eclipse IDE, the Sun NetBeans IDE,
+the Sun J2ME Wireless Toolkit, and the Javaground Tools.
 
 <p>
 The <b>ProGuard user documentation</b> represents an important part of this
@@ -39,7 +39,7 @@ version of the code.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/main.html b/docs/main.html
index 633d2c3..7cc7c75 100644
--- a/docs/main.html
+++ b/docs/main.html
@@ -3,6 +3,9 @@
 <head>
 <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
 <meta http-equiv="content-style-type" content="text/css">
+<meta name="author" content="Eric Lafortune">
+<meta name="description" content="ProGuard: java shrinker, optimizer, and obfuscator">
+<meta name="keywords" content="java obfuscator, optimizer, shrinker">
 <link rel="stylesheet" type="text/css" href="style.css">
 <title>ProGuard Main</title>
 </head>
@@ -66,13 +69,13 @@ The following sections provide more detailed information:
     learn from others on our forums.
 <li><a href="acknowledgements.html">Acknowledgements</a>: people who have been
     helpful.
-<li><a href="alternatives.html">Alternatives</a>: other Java obfuscators and
-    shrinking programs.
+<li><a href="alternatives.html">Alternatives</a>: other Java obfuscators,
+    optimizers, and shrinkers.
 </ul>
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/ant.html b/docs/manual/ant.html
index 21ea393..1e9db68 100644
--- a/docs/manual/ant.html
+++ b/docs/manual/ant.html
@@ -168,6 +168,11 @@ elements:
     (default = false)</dt>
 <dd>Apply aggressive overloading while obfuscating.</dd>
 
+<dt><code><b>useuniqueclassmembernames</b></code> = "<i>boolean</i>"
+    (default = false)</dt>
+<dd>Ensure uniform obfuscated class member names for subsequent incremental
+    obfuscation.</dd>
+
 <dt><code><b>defaultpackage</b></code> = "<i>package_name</i>"</dt>
 <dd>Repackage all class files that are renamed into the single given
     package.</dd>
@@ -420,7 +425,7 @@ attributes:
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/examples.html b/docs/manual/examples.html
index 7a57cd1..3be5854 100644
--- a/docs/manual/examples.html
+++ b/docs/manual/examples.html
@@ -23,9 +23,14 @@ Some typical useful configurations:
 <li><a href="#native">Processing native methods</a>
 <li><a href="#serializable">Processing serializable classes</a>
 <li><a href="#beans">Processing bean classes</a>
+<li><a href="#enumerations">Processing enumeration classes</a>
 <li><a href="#annotations">Processing annotations</a>
+<li><a href="#database">Processing database drivers</a>
+<li><a href="#componentui">Processing ComponentUI classes</a>
 <li><a href="#rmi">Processing RMI code</a>
 <li><a href="#stacktrace">Producing useful obfuscated stack traces</a>
+<li><a href="#restructuring">Restructuring the output archives</a>
+<li><a href="#filtering">Filtering the input and the output</a>
 <li><a href="#multiple">Processing multiple applications at once</a>
 <li><a href="#incremental">Incremental obfuscation</a>
 <li><a href="#deadcode">Finding dead code</a>
@@ -69,22 +74,25 @@ The access modifiers <code>public</code> and <code>static</code> are not
 really required in this case, since we know a priori that the specified class
 and method have the proper access flags. It just looks more familiar this way.
 <p>
-We're using the <code>-overloadaggressively</code>,
-<code>-defaultpackage</code>, and <code>-allowaccessmodification</code>
+We're using the <a
+href="usage.html#overloadaggressively"><code>-overloadaggressively</code></a>,
+<a href="usage.html#defaultpackage"><code>-defaultpackage</code></a>, and <a
+href="usage.html#allowaccessmodification"><code>-allowaccessmodification</code></a>
 options to shave off some extra bytes, but we could leave them out as well.
-The <code>-defaultpackage</code> directive moves all classes to the given
-package, in this case the root package. Only <code>proguard.ProGuard</code>
-keeps its original name.
+The <a href="usage.html#defaultpackage"><code>-defaultpackage</code></a>
+directive moves all classes to the given package, in this case the root
+package. Only <code>proguard.ProGuard</code> keeps its original name.
 <p>
-We're writing out an obfuscation mapping file with <code>-printmapping</code>,
-for de-obfuscating any stack traces later on, or for incremental obfuscation of
+We're writing out an obfuscation mapping file with <a
+href="usage.html#printmapping"><code>-printmapping</code></a>, for
+de-obfuscating any stack traces later on, or for incremental obfuscation of
 extensions.
 <p>
 In general, you might need a few additional directives for processing <a
-href="#native">native methods</a>, <a href="#serializable">serializable
-classes</a>, <a href="#beans">bean classes</a>, or <a
-href="#annotations">annotations</a>. For processing 'simple' applications like
-ProGuard, that is not required.
+href="#native">native methods</a>, <a href="#enumerations">enumerations</a>,
+<a href="#serializable">serializable classes</a>, or <a href="#beans">bean
+classes</a>. For processing 'simple' applications like ProGuard, that is not
+required.
 
 <a name="applet"> </a>
 <h3>A typical applet</h3>
@@ -103,9 +111,9 @@ The typical applet methods will be preserved automatically, since
 class in the library <code>rt.jar</code>.
 <p>
 If applicable, you should add directives for processing <a
-href="#native">native methods</a>, <a href="#serializable">serializable
-classes</a>, <a href="#beans">bean classes</a>, or <a
-href="#annotations">annotations</a>.
+href="#native">native methods</a>, <a href="#enumerations">enumerations</a>,
+<a href="#serializable">serializable classes</a>, or <a href="#beans">bean
+classes</a>.
 
 <a name="midlet"> </a>
 <h3>A typical midlet</h3>
@@ -133,13 +141,14 @@ The typical midlet methods will be preserved automatically, since
 class in the library <code>midpapi20.jar</code>.
 <p>
 If applicable, you should add directives for processing <a
-href="#native">native methods</a>, <a href="#serializable">serializable
-classes</a>, <a href="#beans">bean classes</a>, or <a
-href="#annotations">annotations</a>.
+href="#native">native methods</a>, <a href="#enumerations">enumerations</a>,
+<a href="#serializable">serializable classes</a>, or <a href="#beans">bean
+classes</a>.
 <p>
 You must preverify your midlets <i>after</i> having processed them, using
 J2ME's <code>preverify</code> tool. Because this tool unpacks your processed
-jars, you should use ProGuard's <code>-dontusemixedcaseclassnames</code>
+jars, you should use ProGuard's <a
+href="usage.html#dontusemixedcaseclassnames"><code>-dontusemixedcaseclassnames</code></a>
 option on platforms with case-insensitive filing systems, such as Windows.
 <p>
 Please note the in-depth article <a
@@ -162,16 +171,19 @@ These options shrink, optimize, and obfuscate all public applications in
 }
 </pre>
 <p>
-Note the use of <code>-keepclasseswithmembers</code>. We don't want to preserve
-all classes, just all classes that have main methods, and those methods.
+Note the use of <a
+href="usage.html#keepclasseswithmembers"><code>-keepclasseswithmembers</code></a>.
+We don't want to preserve all classes, just all classes that have main
+methods, and those methods.
 <p>
-The <code>-printseeds</code> option prints out which classes exactly will
-be preserved, so we know for sure we're getting what we want.
+The <a href="usage.html#printseeds"><code>-printseeds</code></a> option prints
+out which classes exactly will be preserved, so we know for sure we're getting
+what we want.
 <p>
 If applicable, you should add directives for processing <a
-href="#native">native methods</a>, <a href="#serializable">serializable
-classes</a>, <a href="#beans">bean classes</a>, or <a
-href="#annotations">annotations</a>.
+href="#native">native methods</a>, <a href="#enumerations">enumerations</a>,
+<a href="#serializable">serializable classes</a>, or <a href="#beans">bean
+classes</a>.
 
 <a name="applets"> </a>
 <h3>All possible applets in the input jars</h3>
@@ -188,13 +200,13 @@ These options shrink, optimize, and obfuscate all public applets in
 <p>
 We're simply keeping all classes that extend the <code>Applet</code> class.
 <p>
-Again, the <code>-printseeds</code> option prints out which applets exactly
-will be preserved.
+Again, the <a href="usage.html#printseeds"><code>-printseeds</code></a> option
+prints out which applets exactly will be preserved.
 <p>
 If applicable, you should add directives for processing <a
-href="#native">native methods</a>, <a href="#serializable">serializable
-classes</a>, <a href="#beans">bean classes</a>, or <a
-href="#annotations">annotations</a>.
+href="#native">native methods</a>, <a href="#enumerations">enumerations</a>,
+<a href="#serializable">serializable classes</a>, or <a href="#beans">bean
+classes</a>.
 
 <a name="midlets"> </a>
 <h3>All possible midlets in the input jars</h3>
@@ -215,17 +227,18 @@ These options shrink, optimize, and obfuscate all public J2ME midlets in
 <p>
 We're simply keeping all classes that extend the <code>MIDlet</code> class.
 <p>
-And again, the <code>-printseeds</code> option prints out which midlets exactly
-will be preserved.
+And again, the <a href="usage.html#printseeds"><code>-printseeds</code></a>
+option prints out which midlets exactly will be preserved.
 <p>
 If applicable, you should add directives for processing <a
-href="#native">native methods</a>, <a href="#serializable">serializable
-classes</a>, <a href="#beans">bean classes</a>, or <a
-href="#annotations">annotations</a>.
+href="#native">native methods</a>, <a href="#enumerations">enumerations</a>,
+<a href="#serializable">serializable classes</a>, or <a href="#beans">bean
+classes</a>.
 <p>
 You must preverify your midlets <i>after</i> having processed them, using
 J2ME's <code>preverify</code> tool. Because this tool unpacks your processed
-jars, you should use ProGuard's <code>-dontusemixedcaseclassnames</code>
+jars, you should use ProGuard's <a
+href="usage.html#dontusemixedcaseclassnames"><code>-dontusemixedcaseclassnames</code></a>
 option on platforms with case-insensitive filing systems, such as Windows.
 
 <a name="servlets"> </a>
@@ -251,13 +264,13 @@ interface. We're using the <code>implements</code> keyword because it looks
 more familiar in this context, but it is equivalent to <code>extends</code>,
 as far as ProGuard is concerned.
 <p>
-And again, the <code>-printseeds</code> option prints out which servlets
-exactly will be preserved.
+And again, the <a href="usage.html#printseeds"><code>-printseeds</code></a>
+option prints out which servlets exactly will be preserved.
 <p>
 If applicable, you should add directives for processing <a
-href="#native">native methods</a>, <a href="#serializable">serializable
-classes</a>, <a href="#beans">bean classes</a>, or <a
-href="#annotations">annotations</a>.
+href="#native">native methods</a>, <a href="#enumerations">enumerations</a>,
+<a href="#serializable">serializable classes</a>, or <a href="#beans">bean
+classes</a>.
 
 <a name="library"> </a>
 <h3>Processing a library</h3>
@@ -287,6 +300,11 @@ serialization code:
     native <methods>;
 }
 
+-keepclassmembers class * extends java.lang.Enum {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
 -keepclassmembers class * implements java.io.Serializable {
     static final long serialVersionUID;
     private void writeObject(java.io.ObjectOutputStream);
@@ -294,31 +312,30 @@ serialization code:
     java.lang.Object writeReplace();
     java.lang.Object readResolve();
 }
-
--keepclassmembers class * extends java.lang.Enum {
-    public **[] values();
-}
 </pre>
 <p>
 This configuration should preserve everything we'll ever want to access in the
 library. Only if there are any other non-public classes or methods that are
-invoked dynamically, they should be specified using additional
-<code>-keep</code> directives.
-<p>
-The <code>-keepclassmembernames</code> directive for the <code>class$</code>
-methods is not strictly necessary. These methods are inserted by the
-<code>javac</code> compiler and the <code>jikes</code> compiler respectively,
-to implement the <code>.class</code> construct. ProGuard will automatically
-detect them and deal with them, even when their names have been obfuscated.
-However, older versions of ProGuard and other obfuscators may rely on the
-original method names. It may therefore be helpful to preserve them, in case
-these other obfuscators are ever used for further obfuscation of the library.
-<p>
-We've added some directives for keeping the "Deprecated" attribute, for <a
-href="#stacktrace">useful stack traces</a>, for <a href="#native">native
-methods</a>, <a href="#serializable">serializable classes</a>, and for <a
-href="#annotations">annotations</a> (possibly with enumerations), which are
-all discussed in their respective examples.
+invoked dynamically, they should be specified using additional <a
+href="usage.html#keep"><code>-keep</code></a> directives.
+<p>
+The <a
+href="usage.html#keepclassmembernames"><code>-keepclassmembernames</code></a>
+directive for the <code>class$</code> methods is not strictly necessary. These
+methods are inserted by the <code>javac</code> compiler and the
+<code>jikes</code> compiler respectively, to implement the <code>.class</code>
+construct. ProGuard will automatically detect them and deal with them, even
+when their names have been obfuscated. However, older versions of ProGuard and
+other obfuscators may rely on the original method names. It may therefore be
+helpful to preserve them, in case these other obfuscators are ever used for
+further obfuscation of the library.
+<p>
+We've added some directives for keeping the "Deprecated" attribute, for
+producing <a href="#stacktrace">useful stack traces</a>, and for processing <a
+href="#native">native methods</a>, <a href="#enumerations">enumerations</a>,
+<a href="#serializable">serializable classes</a>, and <a
+href="#annotations">annotations</a>, which are all discussed in their
+respective examples.
 <p>
 The "InnerClasses" attribute (or more precisely, its source name part) has to
 be preserved as well, for any inner classes that can be referenced from
@@ -340,14 +357,32 @@ ensure that:
 }
 </pre>
 <p>
-Note the use of <code>-keepclasseswithmembernames</code>. We don't want to
-preserve all classes or all native methods; we just want to keep the relevant
-names from being obfuscated.
+Note the use of <a
+href="usage.html#keepclasseswithmembernames"><code>-keepclasseswithmembernames</code></a>.
+We don't want to preserve all classes or all native methods; we just want to
+keep the relevant names from being obfuscated.
 <p>
 ProGuard doesn't have your native code, so it can't automatically preserve the
 classes or class members that are invoked by the native code. These are entry
 points, which you'll have to specify explicitly.
 
+<a name="enumerations"> </a>
+<h3>Processing enumeration classes</h3>
+If your application, applet, servlet, library, etc., contains enumeration
+classes, you'll have to preserve some special methods. Enumerations were
+introduced in JDK 5.0. The java compiler translates enumerations into classes
+with a special structure. Notably, the classes contain implementations of some
+static methods that the run-time environment accesses by introspection (Isn't
+that just grand? Introspection is the self-modifying code of a new
+generation). You have to specify these explicitly, to make sure they aren't
+removed or obfuscated:
+<pre>
+-keepclassmembers class * extends java.lang.Enum {
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+</pre>
+
 <a name="serializable"> </a>
 <h3>Processing serializable classes</h3>
 More complex applications, applets, servlets, libraries, etc., may contain
@@ -369,11 +404,12 @@ may require special attention:
 </pre>
 <p>
 
-    The <code>-keepclassmembers</code> option makes sure that any
-    serialization methods are kept. By using this directive instead of the
-    basic <code>-keep</code> directive, we're not forcing preservation of
-    <i>all</i> serializable classes, just preservation of the listed members
-    of classes that are actually used.
+    The <a
+    href="usage.html#keepclassmembers"><code>-keepclassmembers</code></a>
+    option makes sure that any serialization methods are kept. By using this
+    directive instead of the basic <code>-keep</code> directive, we're not
+    forcing preservation of <i>all</i> serializable classes, just preservation
+    of the listed members of classes that are actually used.
     <p>
 
 <li>Sometimes, the serialized data are stored, and read back later into newer
@@ -444,8 +480,8 @@ may require special attention:
 Note that the above directives may preserve more classes and class members
 than strictly necessary. For instance, a large number of classes may implement
 the <code>Serialization</code> interface, yet only a small number may actually
-ever be serialized. Knowing your application and tuning the configuration will
-often produce more compact results.
+ever be serialized. Knowing your application and tuning the configuration
+often produces more compact results.
 
 <a name="beans"> </a>
 <h3>Processing bean classes</h3>
@@ -499,10 +535,6 @@ treats annotation attributes as optional, and removes them in the obfuscation
 step. If they are required, you'll have to specify this explicitly:
 <pre>
 -keepattributes *Annotation*
-
--keepclassmembers class * extends java.lang.Enum {
-    public static **[] values();
-}
 </pre>
 <p>
 For brevity, we're specifying a wildcarded attribute name, which will match
@@ -514,18 +546,42 @@ For brevity, we're specifying a wildcarded attribute name, which will match
 code, you could refine this selection, for instance not keeping the run-time
 invisible annotations (which are only used at compile-time).
 <p>
-If your annotations contain enumeration classes, you'll have to preserve the
-<code>values()</code> method in these classes. The run-time environment
-accesses this method by introspection (Isn't that just grand? Introspection is
-the self-modifying code of a new generation).
-<p>
 Some code may make further use of introspection to figure out the enclosing
 methods of anonymous inner classes. In that case, the corresponding attribute
-will have to be preserved as well:
+has to be preserved as well:
 <pre>
 -keepattributes EnclosingMethod
 </pre>
 
+<a name="database"> </a>
+<h3>Processing database drivers</h3>
+Database drivers are implementations of the <code>Driver</code> interface.
+Since they are often created dynamically, you may want to preserve any
+implementations that you are processing as entry points:
+<pre>
+-keep class * implements java.sql.Driver
+</pre>
+<p>
+This directive also gets rid of the note that ProGuard prints out about
+<code>(java.sql.Driver)Class.forName</code> constructs, if you are
+instantiating a driver in your code (without necessarily implementing any
+drivers yourself).
+
+<a name="componentui"> </a>
+<h3>Processing ComponentUI classes</h3>
+Swing UI look and feels are implemented as extensions of the
+<code>ComponentUI</code> class. For some reason, these have to contain a
+static method <code>createUI</code>, which the Swing API invokes using
+introspection. You should therefore always preserve the method as an entry
+point, for instance like this:
+<pre>
+-keep class * extends javax.swing.plaf.ComponentUI {
+    public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent);
+}
+</pre>
+<p>
+This directive also keeps the classes themselves.
+
 <a name="rmi"> </a>
 <h3>Processing RMI code</h3>
 Reportedly, the easiest way to handle RMI code is to process the code with
@@ -571,11 +627,142 @@ their original names, so we're saving the mapping to a file
 <code>out.map</code>. The information can then be used by the <a
 href="retrace/index.html">ReTrace</a> tool to restore the original stack trace.
 
+<a name="restructuring"> </a>
+<h3>Restructuring the output archives</h3>
+In simple applications, all output classes and resources files are merged into
+a single jar. For example:
+<pre>
+-injars  classes
+-injars  in1.jar
+-injars  in2.jar
+-injars  in3.jar
+-outjars out.jar
+</pre>
+<p>
+This configuration merges the processed versions of the files in the
+<code>classes</code> directory and the three jars into a single output jar
+<code>out.jar</code>.
+<p>
+If you want to preserve the structure of your input jars (and/or wars, ears,
+zips, or directories), you can specify an output directory (or a war, an ear,
+or a zip). For example:
+<pre>
+-injars  in1.jar
+-injars  in2.jar
+-injars  in3.jar
+-outjars out
+</pre>
+<p>
+The input jars will then be reconstructed in the directory <code>out</code>,
+with their original names.
+<p>
+You can also combine archives into higher level archives. For example:
+<pre>
+-injars  in1.jar
+-injars  in2.jar
+-injars  in3.jar
+-outjars out.war
+</pre>
+<p>
+The other way around, you can flatten the archives inside higher level
+archives into simple archives:
+<pre>
+-injars  in.war
+-outjars out.jar
+</pre>
+<p>
+This configuration puts the processed contents of all jars inside
+<code>in.war</code> (plus any other contents of <code>in.war</code>) into
+<code>out.jar</code>.
+<p>
+If you want to combine input jars (and/or wars, ears, zips, or directories)
+into output jars (and/or wars, ears, zips, or directories), you can group the
+<a href="usage.html#injars"><code>-injars</code></a> and <a
+href="usage.html#outjars"><code>-outjars</code></a> options. For example:
+<pre>
+-injars base_in1.jar
+-injars base_in2.jar
+-injars base_in3.jar
+-outjars base_out.jar
+
+-injars  extra_in.jar
+-outjars extra_out.jar
+</pre>
+<p>
+This configuration puts the processed results of all <code>base_in*.jar</code>
+jars into <code>base_out.jar</code>, and the processed results of the
+<code>extra_in.jar</code> into <code>extra_out.jar</code>. Note that only the
+order of the options matters; the additional whitespace is just for clarity.
+<p>
+This grouping, archiving, and flattening can be arbitrarily complex. ProGuard
+always tries to package output archives in a sensible way, reconstructing the
+input entries as much as required.
+
+<a name="filtering"> </a>
+<h3>Filtering the input and the output</h3>
+
+If you want even greater control, you can add filters to the input and the
+output, filtering out zips, ears, wars, jars, and/or ordinary files. For
+example, if you want to disregard certain files from an input jar:
+<pre>
+-injars  in.jar(!images/**)
+-outjars out.jar
+</pre>
+<p>
+This configuration removes any files in the <code>images</code> directory and
+its subdirectories.
+<p>
+Such filters can be convenient for avoiding warnings about duplicate files in
+the output. For example, only keeping the manifest file from a first input jar:
+<pre>
+-injars  in1.jar
+-injars  in2.jar(!META-INF/MANIFEST.MF)
+-injars  in3.jar(!META-INF/MANIFEST.MF)
+-outjars out.jar
+</pre>
+<p>
+Another useful application is speeding up the processing by ProGuard, by
+disregarding a large number of irrelevant classes in the runtime library jar:
+<pre>
+-libraryjars <java.home>/lib/rt.jar(java/**,javax/**)
+</pre>
+<p>
+The filter makes ProGuard disregard <code>com.sun.**</code> classes, for
+instance , which don't affect the processing of ordinary applications.
+<p>
+It is also possible to filter the jars (and/or wars, ears, zips) themselves,
+based on their names. For example:
+<pre>
+-injars  in(**/acme_*.jar;)
+-outjars out.jar
+</pre>
+<p>
+Note the semi-colon in the filter; the filter in front of it applies to jar
+names. In this case, only <code>acme_*.jar</code> jars are read from the
+directory <code>in</code> and its subdirectories. Filters for war names, ear
+names, and zip names can be prefixed with additional semi-colons. All types of
+filters can be combined. They are orthogonal.
+<p>
+On the other hand, you can also filter the output, in order to control what
+content goes where. For example:
+<pre>
+-injars  in.jar
+-outjars code_out.jar(**.class)
+-outjars resources_out.jar
+</pre>
+<p>
+This configuration splits the processed output, sending <code>**.class</code>
+files to <code>code_out.jar</code>, and all remaining files to
+<code>resources_out.jar</code>.
+<p>
+Again, the filtering can be arbitrarily complex, especially when combined with
+the grouping of input and output.
+
 <a name="multiple"> </a>
 <h3>Processing multiple applications at once</h3>
-You can process several independent applications (or applets, midlets,...) in
-one go, in order to save time and effort. ProGuard's input and output handling
-offers various ways to keep the output nicely structured.
+You can process several dependent or independent applications (or applets,
+midlets,...) in one go, in order to save time and effort. ProGuard's input and
+output handling offers various ways to keep the output nicely structured.
 <p>
 The easiest way is to specify your input jars (and/or wars, ears, zips, and
 directories) and a single output directory. ProGuard will then reconstruct the
@@ -585,34 +772,11 @@ just the input and output options:
 -injars  application1.jar
 -injars  application2.jar
 -injars  application3.jar
--injars  application.war
 -outjars processed_applications
 </pre>
 <p>
 After processing, the directory <code>processed_applications</code> will
-contain the processed application jars and war, with their original names.
-<p>
-If you want explicit control over the output names, or if you want to combine
-input jars (and/or wars, ears, zips, or directories) into output jars (and/or
-wars, ears, zips, or directories), you can group the <code>-injars</code> and
-<code>-outjars</code> options. For example:
-<pre>
--injars  application1.jar
--injars  application2.jar
--injars  application3.jar
--outjars application_out1.war
-
--injars  application.war
--outjars application_out2.war
-</pre>
-<p>
-This configuration creates two wars: one containing all processed application
-jars, and one containing the processed contents of the input war.
-<p>
-Note that ProGuard will try to package output archives in a sensible way,
-reconstructing the input entries as much as required. If you want even greater
-control, you can add filters to the input and the output, filtering out zips,
-ears, wars, jars, and/or ordinary files.
+contain the processed application jars, with their original names.
 
 <a name="incremental"> </a>
 <h3>Incremental obfuscation</h3>
@@ -622,8 +786,9 @@ depend on it, e.g. the ProGuard GUI:
 <pre>
 -injars       proguardgui.jar
 -outjars      proguardgui_out.jar
+-injars       proguard.jar
+-outjars      proguard_out.jar
 -libraryjars  <java.home>/lib/rt.jar
--libraryjars  proguard.jar
 -applymapping proguard.map
 
 -keep public class proguard.gui.ProGuardGUI {
@@ -631,15 +796,38 @@ depend on it, e.g. the ProGuard GUI:
 }
 </pre>
 <p>
-We're reading both unprocessed jars: the new one as the input jar, and the old
-one as a library jar. The <code>-applymapping</code> option then makes sure
-the ProGuard part of the code gets the previously produced obfuscation
-mapping. The final application will consist of the obfuscated ProGuard jar and
-the additional obfuscated GUI jar.
+We're reading both unprocessed jars as input. Their processed contents will go
+to the respective output jars. The <a
+href="usage.html#applymapping"><code>-applymapping</code></a> option then
+makes sure the ProGuard part of the code gets the previously produced
+obfuscation mapping. The final application will consist of the obfuscated
+ProGuard jar and the additional obfuscated GUI jar.
+<p>
+The added code in this example is straightforward; it doesn't affect the
+original code. The <code>proguard_out.jar</code> will be identical to the one
+produced in the initial processing step. If you foresee adding more complex
+extensions to your code, you should specify the options <a
+href="usage.html#useuniqueclassmembernames"><code>-useuniqueclassmembernames</code></a>,
+<a href="usage.html#dontshrink"><code>-dontshrink</code></a>, and <a
+href="usage.html#dontoptimize"><code>-dontoptimize</code></a> <i>in the
+original processing step</i>. These options ensure that the obfuscated base
+jar will always remain usable without changes. You can then specify the base
+jar as a library jar:
+<pre>
+-injars       proguardgui.jar
+-outjars      proguardgui_out.jar
+-libraryjars  proguard.jar
+-libraryjars  <java.home>/lib/rt.jar
+-applymapping proguard.map
+
+-keep public class proguard.gui.ProGuardGUI {
+    public static void main(java.lang.String[]);
+}
+</pre>
 
 <a name="deadcode"> </a>
 <h3>Finding dead code</h3>
-These options list unused fields and methods in the application
+These options list unused classes, fields, and methods in the application
 <code>mypackage.MyApplication</code>:
 <pre>
 -injars      in.jar
@@ -653,10 +841,21 @@ These options list unused fields and methods in the application
 }
 </pre>
 <p>
-We're not specifying an output jar, just printing out some results.
-<p>
-We're saving a little bit of time by skipping the optimization and obfuscation
+We're not specifying an output jar, just printing out some results. We're
+saving some processing time by skipping the optimization and obfuscation
 steps.
+<p>
+The java compiler inlines primitive constants (primitive <code>static
+final</code> fields). ProGuard would therefore list such fields as not being
+used in the class files that it analyzes, even if they <i>are</i> used in the
+source files. We can add a <a
+href="usage.html#keepclassmembers"><code>-keepclassmembers</code></a> option
+that keeps those fields a priori, in order to avoid listing them:
+<pre>
+-keepclassmembers class * {
+    static final % *;
+}
+</pre>
 
 <a name="structure"> </a>
 <h3>Printing out the internal structure of class files</h3>
@@ -676,7 +875,7 @@ processing the input jar at all.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/gui.html b/docs/manual/gui.html
index 2d918c8..49b208c 100644
--- a/docs/manual/gui.html
+++ b/docs/manual/gui.html
@@ -23,7 +23,7 @@ edit the configuration and execute ProGuard through a few tabs:
 
 <table cellspacing="5" cellpadding="5">
 <tr><td class="button"><a href="#proguard">ProGuard</a></td>
-    <td>Load an existing configuration file.</td></tr>
+    <td>Optionally load an existing configuration file.</td></tr>
 <tr><td class="button"><a href="#inputoutput">Input/Output</a></td>
     <td>Specify the program jars and library jars.</td></tr>
 <tr><td class="button"><a href="#shrinking">Shrinking</a></td>
@@ -251,7 +251,7 @@ fields to keep.
     fields, based on their access modifiers.
 
 <li>The <b>Return type</b> text field takes the fully-qualified type of the
-    field or fields. The type can contain wild-cards if it is a class name.
+    field or fields. The type can contain wildcards.
 
 <li>The <b>Name</b> text field takes the name of the field or fields. The field
     name can contain wildcards.
@@ -266,14 +266,14 @@ and constraining methods to keep.
 <li>The <b>Access</b> selections allows to specify constraints on the method or
     methods, based on their access modifiers.
 
-<li>The <b>Return type</b> text field takes the fully-qualified type of the         method or methods. The type can contain wild-cards if it is a class name.
+<li>The <b>Return type</b> text field takes the fully-qualified type of the         method or methods. The type can contain wildcards.
 
 <li>The <b>Name</b> text field takes the name of the method or methods. The
     method name can contain wildcards.
 
 <li>The <b>Arguments</b> text field takes the comma-separated list of
     fully-qualified method arguments. Each of these arguments can contain
-    wildcards, if it is a class name.
+    wildcards.
 </ul>
 <p>
 
@@ -307,6 +307,7 @@ Corresponding configuration options:
 <li>-<a href="usage.html#applymapping">applymapping</a>
 <li>-<a href="usage.html#obfuscationdictionary">obfuscationdictionary</a>
 <li>-<a href="usage.html#overloadaggressively">overloadaggressively</a>
+<li>-<a href="usage.html#useuniqueclassmembernames">useuniqueclassmembernames</a>
 <li>-<a href="usage.html#defaultpackage">defaultpackage</a>
 <li>-<a href="usage.html#dontusemixedcaseclassnames">dontusemixedcaseclassnames</a>
 <li>-<a href="usage.html#keepattributes">keepattributes</a>
@@ -415,7 +416,7 @@ There are two buttons at the bottom:
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/index.html b/docs/manual/index.html
index 8f8e630..8da5de6 100644
--- a/docs/manual/index.html
+++ b/docs/manual/index.html
@@ -32,7 +32,7 @@
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/introduction.html b/docs/manual/introduction.html
index 0a71f9b..6b43054 100644
--- a/docs/manual/introduction.html
+++ b/docs/manual/introduction.html
@@ -111,7 +111,7 @@ accordingly.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/limitations.html b/docs/manual/limitations.html
index 2d0f8fd..0718be2 100644
--- a/docs/manual/limitations.html
+++ b/docs/manual/limitations.html
@@ -52,7 +52,9 @@ easily avoided or resolved:
     <p>
 
 <li>ProGuard's optimization algorithms also remove all <b>empty busy-waiting
-    loops</b>. You should avoid these, or otherwise, you'll have to switch off
+    loops</b>, unless they test on fields that are marked as
+    <code>volatile</code>. You should always mark tested fields as
+    <code>volatile</code>, or otherwise, you'll have to switch off
     optimization using the <code>-dontoptimize</code> option.
     <p>
 
@@ -85,8 +87,8 @@ easily avoided or resolved:
     <p>
 
 <li>ProGuard's obfuscation process currently doesn't follow the <b>naming
-    rule</b> specifying that internal classes must be named as
-    <code>ExternalClass$InternalClass</code>, for instance (cfr. <a href=
+    rule</b> specifying that nested classes must be named as
+    <code>EnclosingClass$InnerClass</code>, for instance (cfr. <a href=
     "http://java.sun.com/docs/books/jls/second_edition/html/j.title.doc.html"
     >The Java Language Specification, Second Edition</a>, <a href=
     "http://java.sun.com/docs/books/jls/second_edition/html/binaryComp.doc.html#59892"
@@ -103,7 +105,7 @@ easily avoided or resolved:
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/refcard.html b/docs/manual/refcard.html
index 42594ab..4443881 100644
--- a/docs/manual/refcard.html
+++ b/docs/manual/refcard.html
@@ -24,173 +24,189 @@
 <table cellspacing="10">
 
 <tr>
-<td valign="top"><code><b>@</b></code><i>filename</i></td>
+<td valign="top"><a href="usage.html#at"><code><b>@</b></code></a><a href="usage.html#filename"><i>filename</i></a></td>
 
 <td>Short for '<code>-include</code> <i>filename</i>'.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-include</b></code> <i>filename</i></td>
+<td valign="top"><a href="usage.html#include"><code><b>-include</b></code></a>
+                 <a href="usage.html#filename"><i>filename</i></a></td>
 
 <td>Read configuration options from the given file.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-basedirectory</b></code> <i>directoryname</i></td>
+<td valign="top"><a href="usage.html#basedirectory"><code><b>-basedirectory</b></code></a>
+                 <a href="usage.html#filename"><i>directoryname</i></a></td>
 
 <td>Specifies the base directory for subsequent relative file names.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-injars</b></code> <i>class_path</i></td>
+<td valign="top"><a href="usage.html#injars"><code><b>-injars</b></code></a>
+                 <a href="usage.html#classpath"><i>class_path</i></a></td>
 <td>Specifies the program jars (or wars, ears, zips, or directories).</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-outjars</b></code> <i>class_path</i></td>
+<td valign="top"><a href="usage.html#outjars"><code><b>-outjars</b></code></a>
+                 <a href="usage.html#classpath"><i>class_path</i></a></td>
 <td>Specifies the name of the output jars (or wars, ears, zips, or
     directories).</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-libraryjars</b></code> <i>class_path</i></td>
+<td valign="top"><a href="usage.html#libraryjars"><code><b>-libraryjars</b></code></a>
+                 <a href="usage.html#classpath"><i>class_path</i></a></td>
 <td>Specifies the library jars (or wars, ears, zips, or directories).</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-dontskipnonpubliclibraryclasses</b></code></td>
+<td valign="top"><a href="usage.html#dontskipnonpubliclibraryclasses"><code><b>-dontskipnonpubliclibraryclasses</b></code></a></td>
 <td>Don't ignore non-public library classes.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-dontskipnonpubliclibraryclassmembers</b></code></td>
+<td valign="top"><a href="usage.html#dontskipnonpubliclibraryclassmembers"><code><b>-dontskipnonpubliclibraryclassmembers</b></code></a></td>
 <td>Don't ignore package visible library class members.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-keep</b></code> <i>class_specification</i></td>
+<td valign="top"><a href="usage.html#keep"><code><b>-keep</b></code></a>
+                 <a href="usage.html#classspecification"><i>class_specification</i></a></td>
 <td>Preserve the specified classes <i>and</i> class members.</td>
 
 </tr>
 <tr>
-<td valign="top"><code><b>-keepclassmembers</b></code>
-    <i>class_specification</i></td>
+<td valign="top"><a href="usage.html#keepclassmembers"><code><b>-keepclassmembers</b></code></a>
+                 <a href="usage.html#classspecification"><i>class_specification</i></a></td>
 <td>Preserve the specified class members, if their classes are preserved as
     well.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-keepclasseswithmembers</b></code>
-    <i>class_specification</i></td>
+<td valign="top"><a href="usage.html#keepclasseswithmembers"><code><b>-keepclasseswithmembers</b></code></a>
+                 <a href="usage.html#classspecification"><i>class_specification</i></a></td>
 <td>Preserve the specified classes <i>and</i> class members, if all of the
     specified class members are present.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-keepnames</b></code>
-    <i>class_specification</i></td>
+<td valign="top"><a href="usage.html#keepnames"><code><b>-keepnames</b></code></a>
+                 <a href="usage.html#classspecification"><i>class_specification</i></a></td>
 <td>Preserve the names of the specified classes <i>and</i> class members (if
     they aren't removed in the shrinking step).</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-keepclassmembernames</b></code>
-    <i>class_specification</i></td>
+<td valign="top"><a href="usage.html#keepclassmembernames"><code><b>-keepclassmembernames</b></code></a>
+                 <a href="usage.html#classspecification"><i>class_specification</i></a></td>
 <td>Preserve the names of the specified class members (if they aren't removed
     in the shrinking step).</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-keepclasseswithmembernames</b></code>
-    <i>class_specification</i></td>
+<td valign="top"><a href="usage.html#keepclasseswithmembernames"><code><b>-keepclasseswithmembernames</b></code></a>
+                 <a href="usage.html#classspecification"><i>class_specification</i></a></td>
 <td>Preserve the names of the specified classes <i>and</i> class members, if
     all of the specified class members are present (after the shrinking
     step).</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-printseeds</b></code> [<i>filename</i>]</td>
+<td valign="top"><a href="usage.html#printseeds"><code><b>-printseeds</b></code></a>
+                 [<a href="usage.html#filename"><i>filename</i></a>]</td>
 <td>List classes and class members matched by the various <code>-keep</code>
     options, to the standard output or to the given file.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-dontshrink</b></code></td>
+<td valign="top"><a href="usage.html#dontshrink"><code><b>-dontshrink</b></code></a></td>
 <td>Don't shrink the input class files.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-printusage</b></code> [<i>filename</i>]</td>
+<td valign="top"><a href="usage.html#printusage"><code><b>-printusage</b></code></a>
+                 [<a href="usage.html#filename"><i>filename</i></a>]</td>
 <td>List dead code of the input class files, to the standard output or to the
     given file.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-whyareyoukeeping</b></code>
-    <i>class_specification</i></td>
+<td valign="top"><a href="usage.html#whyareyoukeeping"><code><b>-whyareyoukeeping</b></code></a>
+                 <a href="usage.html#classspecification"><i>class_specification</i></a></td>
 <td>Print details on why the given classes and class members are being kept in
     the shrinking step.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-dontoptimize</b></code></td>
+<td valign="top"><a href="usage.html#dontoptimize"><code><b>-dontoptimize</b></code></a></td>
 <td>Don't optimize the input class files.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-assumenosideeffects</b></code>
-    <i>class_specification</i></td>
+<td valign="top"><a href="usage.html#assumenosideeffects"><code><b>-assumenosideeffects</b></code></a>
+                 <a href="usage.html#classspecification"><i>class_specification</i></a></td>
 <td>Assume that the specified methods don't have any side effects, while
     optimizing.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-allowaccessmodification</b></code></td>
+<td valign="top"><a href="usage.html#allowaccessmodification"><code><b>-allowaccessmodification</b></code></a></td>
 <td>Allow the access modifiers of classes and class members to be modified,
     while optimizing.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-dontobfuscate</b></code></td>
+<td valign="top"><a href="usage.html#dontobfuscate"><code><b>-dontobfuscate</b></code></a></td>
 <td>Don't obfuscate the input class files.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-printmapping</b></code> [<i>filename</i>]</td>
+<td valign="top"><a href="usage.html#printmapping"><code><b>-printmapping</b></code></a>
+                 [<a href="usage.html#filename"><i>filename</i></a>]</td>
 <td>Print the mapping from old names to new names for classes and class members
     that have been renamed, to the standard output or to the given file.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-applymapping</b></code> <i>filename</i></td>
+<td valign="top"><a href="usage.html#applymapping"><code><b>-applymapping</b></code></a>
+                 <a href="usage.html#filename"><i>filename</i></a></td>
 <td>Reuse the given mapping, for incremental obfuscation.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-obfuscationdictionary</b></code>
-    <i>filename</i></td>
+<td valign="top"><a href="usage.html#obfuscationdictionary"><code><b>-obfuscationdictionary</b></code></a>
+                 <a href="usage.html#filename"><i>filename</i></a></td>
 <td>Use the words in the given text file as obfuscated method names.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-overloadaggressively</b></code></td>
+<td valign="top"><a href="usage.html#overloadaggressively"><code><b>-overloadaggressively</b></code></a></td>
 <td>Apply aggressive overloading while obfuscating.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-defaultpackage</b></code> [<i>package_name</i>]</td>
+<td valign="top"><a href="usage.html#useuniqueclassmembernames"><code><b>-useuniqueclassmembernames</b></code></a></td>
+<td>Ensure uniform obfuscated class member names for subsequent incremental
+    obfuscation.</td> </tr>
+
+<tr>
+<td valign="top"><a href="usage.html#defaultpackage"><code><b>-defaultpackage</b></code></a>
+                 [<i>package_name</i>]</td>
 <td>Repackage all class files that are renamed into the single given
     package.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-dontusemixedcaseclassnames</b></code></td>
+<td valign="top"><a href="usage.html#dontusemixedcaseclassnames"><code><b>-dontusemixedcaseclassnames</b></code></a></td>
 <td>Don't generate mixed-case class names while obfuscating.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-keepattributes</b></code>
-    [<i>attribute_name<b>,</b>...</i>]</td>
+<td valign="top"><a href="usage.html#keepattributes"><code><b>-keepattributes</b></code></a>
+                 [<i>attribute_name<b>,</b>...</i>]</td>
 <td>Preserve the given optional attributes; typically
     <code>LineNumberTable</code>, <code>LocalVariableTable</code>,
     <code>SourceFile</code>, <code>Deprecated</code>, <code>Synthetic</code>,
@@ -198,36 +214,37 @@
 </tr>
 
 <tr>
-<td valign="top"><code><b>-renamesourcefileattribute</b></code>
-    [<i>string</i>]</td>
+<td valign="top"><a href="usage.html#renamesourcefileattribute"><code><b>-renamesourcefileattribute</b></code></a>
+                 [<i>string</i>]</td>
 <td>Put the given constant string in the <code>SourceFile</code>
     attributes.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-verbose</b></code></td>
+<td valign="top"><a href="usage.html#verbose"><code><b>-verbose</b></code></a></td>
 <td>Write out some more information during processing.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-dontnote</b></code></td>
+<td valign="top"><a href="usage.html#dontnote"><code><b>-dontnote</b></code></a></td>
 <td>Don't print notes about class casts of variable dynamically created
     objects.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-dontwarn</b></code></td>
+<td valign="top"><a href="usage.html#dontwarn"><code><b>-dontwarn</b></code></a></td>
 <td>Don't warn about unresolved references at all.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-ignorewarnings</b></code></td>
+<td valign="top"><a href="usage.html#ignorewarnings"><code><b>-ignorewarnings</b></code></a></td>
 <td>Print warnings about unresolved references, but continue processing
     anyhow.</td>
 </tr>
 
 <tr>
-<td valign="top"><code><b>-dump</b></code> [<i>filename</i>]</td>
+<td valign="top"><a href="usage.html#dump"><code><b>-dump</b></code></a>
+                 [<a href="usage.html#filename"><i>filename</i></a>]</td>
 <td>Write out the internal structure of the processed class files, to the
     standard output or to the given file.</td>
 </tr>
@@ -258,20 +275,20 @@ Notes:
 
 <tr>
 <td>Classes and class members</td>
-<td bgcolor="#E0E0E0"><code>-keep</code></td>
-<td bgcolor="#E0E0E0"><code>-keepnames</code></td>
+<td bgcolor="#E0E0E0"><a href="usage.html#keep"><code>-keep</code></a></td>
+<td bgcolor="#E0E0E0"><a href="usage.html#keepnames"><code>-keepnames</code></a></td>
 </tr>
 
 <tr>
 <td>Class members only</td>
-<td bgcolor="#E0E0E0"><code>-keepclassmembers</code></td>
-<td bgcolor="#E0E0E0"><code>-keepclassmembernames</code></td>
+<td bgcolor="#E0E0E0"><a href="usage.html#keepclassmembers"><code>-keepclassmembers</code></a></td>
+<td bgcolor="#E0E0E0"><a href="usage.html#keepclassmembernames"><code>-keepclassmembernames</code></a></td>
 </tr>
 
 <tr>
 <td>Classes and class members, if class members present</td>
-<td bgcolor="#E0E0E0"><code>-keepclasseswithmembers</code></td>
-<td bgcolor="#E0E0E0"><code>-keepclasseswithmembernames</code></td>
+<td bgcolor="#E0E0E0"><a href="usage.html#keepclasseswithmembers"><code>-keepclasseswithmembers</code></a></td>
+<td bgcolor="#E0E0E0"><a href="usage.html#keepclasseswithmembernames"><code>-keepclasseswithmembernames</code></a></td>
 </tr>
 
 </table>
@@ -311,7 +328,7 @@ Notes:
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/retrace/examples.html b/docs/manual/retrace/examples.html
index f5657c5..f77fb38 100644
--- a/docs/manual/retrace/examples.html
+++ b/docs/manual/retrace/examples.html
@@ -328,7 +328,7 @@ Exception in thread "main" java.lang.Error: Random exception
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/retrace/index.html b/docs/manual/retrace/index.html
index 6f586ab..5e0c7e1 100644
--- a/docs/manual/retrace/index.html
+++ b/docs/manual/retrace/index.html
@@ -18,7 +18,7 @@
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/retrace/introduction.html b/docs/manual/retrace/introduction.html
index 40495fc..274a9a7 100644
--- a/docs/manual/retrace/introduction.html
+++ b/docs/manual/retrace/introduction.html
@@ -58,7 +58,7 @@ original class names and class member names to their obfuscated names.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/retrace/usage.html b/docs/manual/retrace/usage.html
index c67eba1..e1a3426 100644
--- a/docs/manual/retrace/usage.html
+++ b/docs/manual/retrace/usage.html
@@ -74,7 +74,7 @@ will be left unchanged.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/style.css b/docs/manual/style.css
index 1b0cc55..778e10f 100644
--- a/docs/manual/style.css
+++ b/docs/manual/style.css
@@ -28,6 +28,11 @@ pre {
   background: #E0E0E0;
 }
 
+a
+{
+  text-decoration: none;
+}
+
 /* Settings for variable width code. */
 
 p.code {
diff --git a/docs/manual/troubleshooting.html b/docs/manual/troubleshooting.html
index 634dc84..3a41349 100644
--- a/docs/manual/troubleshooting.html
+++ b/docs/manual/troubleshooting.html
@@ -44,17 +44,6 @@ ProGuard may print out some notes and non-fatal warnings:
     switch off these notes by specifying the <code>-dontnote</code>
     option.</dd>
 
-<dt><a name="unexpectedclass"><b>Note: class file ... unexpectedly contains class ...</b></a></dt>
-
-<dd>The given class file contains a definition for the given class, but the
-    directory name of the file doesn't correspond to the package name of the
-    class. ProGuard will accept the class definition, but the current
-    implementation will not write out the processed version. Please make sure
-    your input classes are packaged correctly. Notably, class files that are
-    in the <code>WEB-INF/classes</code> directory in a war should be packaged
-    in a jar and put in the <code>WEB-INF/lib</code> directory. You can switch
-    off these notes by specifying the <code>-dontnote</code> option.</dd>
-
 <dt><a name="duplicatezipentry"><b>Warning: can't write resource ... Duplicate zip entry</b></a></dt>
 
 <dd>Your input jars contain multiple resource files with the same name.
@@ -85,10 +74,7 @@ some more serious warnings:
     <code>java.util.zip.ZipConstants</code>, which is used as an interface
     class in some public classes, even though it is only package visible (in
     this case, the warning could also be ignored, because the class is not a
-    fundamental part of the class hierarchNotably,
-    class files that are in the <code>WEB-INF/classes</code> directory in a
-    war should be packaged in a jar and put in the <code>WEB-INF/lib</code>
-    directory.y).
+    fundamental part of the class hierarchy).
     <p>
     If you're missing a library and you're absolutely sure it isn't used
     anyway, you can try your luck with the <code>-ignorewarnings</code>
@@ -115,6 +101,56 @@ some more serious warnings:
     and refer to their package visible class members, then you should specify
     the <code>-dontskipnonpubliclibraryclassmembers</code> option.</dd>
 
+<dt><a name="unresolvedenclosingmethod"><b>Warning: can't find enclosing class/method</b></a></dt>
+
+<dd>If there are unresolved references to classes that are defined inside
+    methods in your input, once more, your class files are most likely
+    inconsistent. Possibly, some class file didn't get recompiled properly, or
+    some class file was left behind after its source file was removed. Try
+    removing all class files, recompiling them, zipping them up, and running
+    ProGuard again.</dd>
+
+<dt><a name="unexpectedclass"><b>Warning: class file ... unexpectedly contains class ...</b></a></dt>
+
+<dd>The given class file contains a definition for the given class, but the
+    directory name of the file doesn't correspond to the package name of the
+    class. ProGuard will accept the class definition, but the current
+    implementation will not write out the processed version. Please make sure
+    your input classes are packaged correctly. Notably, class files that are
+    in the <code>WEB-INF/classes</code> directory in a war should be packaged
+    in a jar and put in the <code>WEB-INF/lib</code> directory. If you don't
+    mind these classes not being written to the output, you can specify the
+    <code>-ignorewarnings</code> option, or even the <code>-dontwarn</code>
+    option.</dd>
+
+<dt><a name="mappingconflict1"><b>Warning: ... is not being kept as ..., but remapped to ...</b></a></dt>
+
+<dd>There is a conflict between a <code>-keep</code> option in the
+    configuration, and the mapping file, in the obfuscation step. The given
+    class name or class member name can't be kept by its original name, as
+    specified in the configuration, but it has to be mapped to the other given
+    name, as specified in the mapping file. You should adapt your
+    configuration or your mapping file to remove the conflict. Alternatively,
+    if you're sure the renaming won't hurt, you can specify the
+    <code>-ignorewarnings</code> option, or even the <code>-dontwarn</code>
+    option.</dd>
+
+<dt><a name="mappingconflict2"><b>Warning: field/method ... can't be mapped to ...</b></a></dt>
+
+<dd>There is a conflict between some new program code and the mapping file, in
+    the obfuscation step. The given class member can't be mapped to the given
+    name, because it would conflict with another class member that is already
+    being mapped to the same name. This can happen if you are performing
+    incremental obfuscation, applying an obfuscation mapping file from an
+    initial obfuscation step. For instance, some new class may have been added
+    that extends two existing classes, introducing a conflict in the name
+    space of its class members. If you're sure the class member receiving
+    another name than the one specified won't hurt, you can specify the
+    <code>-ignorewarnings</code> option, or even the <code>-dontwarn</code>
+    option. Note that you should always use the
+    <code>-useuniqueclassmembernames</code> option in the initial obfuscation
+    step, in order to reduce the risk of conflicts.</dd>
+
 <dt><a name="keep"><b>Error: You have to specify '-keep' options</b></a></dt>
 
 <dd>You either forgot to specify <code>-keep</code> options, or you mistyped
@@ -123,6 +159,14 @@ some more serious warnings:
     these. Without the proper seed specifications, ProGuard would shrink,
     optimize, or obfuscate all class files away.</dd>
 
+
+<dt><a name="macosx"><b>Error: Can't read [</b>...<b>/lib/rt.jar] (No such file or directory)</b> (in MacOS X)</a></dt>
+
+<dd>In MacOS X, the run-time classes may be in a different place than on most
+    other platforms. You'll then have to adapt your configuration, replacing
+    the path <code><java.home>/lib/rt.jar</code> by
+    <code><java.home>/../Classes/classes.jar</code>.</dd>
+
 </dl>
 <p>
 
@@ -140,11 +184,16 @@ Should ProGuard crash while processing your application:
 
 <dt><a name="stackoverflowerror"><b>StackOverflowError</b></a></dt>
 
-<dd>You can try increasing the stack size of the Java virtual machine (with
-    the usual <code>-Xss</code> option). This error also seems to occur
-    occasionally when optimizing complex methods on Windows (surprisingly, not
-    on Linux). You can then work around it by using ProGuard's
-    <code>-dontoptimize</code> option.</dd>
+<dd>This error may occur when optimizing very complex methods on Windows
+    (surprisingly, not so easily on Linux). You can always work around it by
+    using ProGuard's <code>-dontoptimize</code> option. In theory, increasing
+    the stack size of the Java virtual machine (with the usual
+    <code>-Xss</code> option) should help too. In practice however, the
+    <code>-Xss</code> setting doesn't have any effect on the main thread, due
+    to <a
+    href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4362291">Sun Bug
+    #4362291</a>. As a result, this solution will only work when running
+    ProGuard in a different thread, e.g. from its GUI.</dd>
 
 <dt><a name="otherwise"><b>Otherwise...</b></a></dt>
 
@@ -171,7 +220,14 @@ errors, it's usually for a single reason:
     <code>preverify</code> tool always unpacks the jars, so class files with
     similar lower-case and upper-case names overwrite each other. You can use
     ProGuard's <code>-dontusemixedcaseclassnames</code> option to work around
-    this problem.</dd>
+    this problem.
+    <p>
+    If the above doesn't help, there is probably a bug in the optimization step
+    of ProGuard. Make sure you are using the latest version. You should be able
+    to work around the problem by using the <code>-dontoptimize</code> option.
+    You can check the bug database to see if it is a known problem (often with
+    a fix). Otherwise, please report it, preferably with the simplest example
+    on which you can find ProGuard to fail.</dd>
 
 </dl>
 <p>
@@ -210,6 +266,16 @@ might be several reasons:
     <code>-printseeds</code> option to see which elements are being kept
     exactly.</dd>
 
+<dt><a name="notobfuscated"><b>Variable names not being obfuscated</b></a></dt>
+
+<dd>If the names of the local variables and parameters in your obfuscated code
+    don't look obfuscated, because they suspiciously resemble the names of
+    their types, it's probably because the decompiler that you are using is
+    coming up with those names. ProGuard's obfuscation step does remove the
+    original names entirely, unless you explicitly keep the
+    <code>LocalVariableTable</code> or <code>LocalVariableTypeTable</code>
+    attributes.</dd>
+
 <dt><a name="stacktraces"><b>Stack traces without class names or line numbers</b></a></dt>
 
 <dd>If your stack traces don't contain any class names or lines numbers,
@@ -240,7 +306,8 @@ might be several reasons:
     method in using the <code>-keep</code> option, e.g. "<code>-keep class
     mypackage.MyClass { void myMethod(); }</code>".</dd>
 
-<dt><a name="nullpointerexception"><b>NullPointerException</b> (or missing resources, icons, sounds,...)</a></dt>
+<dt><a name="missingresourceexception"><b>MissingResourceException</b> or
+    <b>NullPointerException</b></a></dt>
 
 <dd>Your processed code may be unable to find some resource files. ProGuard
     currently simply copies resource files over from the input jars to the
@@ -248,7 +315,8 @@ might be several reasons:
     <code>-defaultpackage</code> option, the package names of some classes may
     have changed, and along with them, the directory in which they look for
     their resource files. It's better not to use this option in these
-    circumstances.</dd>
+    circumstances. Also note that directory entries in jar files aren't copied
+    at all.</dd>
 
 <dt><a name="invalidclassexception2"><b>InvalidClassException</b>,
     <b>class loading error</b>, or
@@ -272,15 +340,21 @@ might be several reasons:
 <dd>You may have forgotten to sign your program jar <i>after</i> having
     processed it with ProGuard.</dd>
 
-<dt><a name="arraystoreexception"><b>ArrayStoreException: sun.reflect.annotation.EnumConstantNotPresentExceptionProxy</b></a></dt>
+<dt><a name="classcastexception"><b>ClassCastException: class not an enum</b></a></dt>
 
-<dd>You are probably processing annotations involving enumerations. You should
-    then preserve the <code>values()</code> method of the enumeration type, as
-    shown in the examples.</dd>
+<dd>You are probably processing enumeration types and calling
+    <code>EnumSet.allOf</code>. You should then make sure you're preserving
+    the <code>values()</code> method of the enumeration type, as shown in the
+    examples.</dd>
+
+<dt><a name="arraystoreexception"><b>ArrayStoreException: sun.reflect.annotation.EnumConstantNotPresentExceptionProxy</b></a></dt>
 
+<dd>You are probably processing annotations involving enumerations. Again, you
+    should make sure you're preserving the <code>values()</code> method of the
+    enumeration type, as shown in the examples.</dd>
 
 <dt><a name="nosuchfieldormethod"><b>Error: No Such Field or Method</b>,
-    <b>Error verifying method</b> (in J2ME emulator)</a></dt>
+    <b>Error verifying method</b> (in a J2ME emulator)</a></dt>
 
 <dd>If you get such a message in a Motorola or Sony Ericsson J2ME phone
     emulator, it's because these emulators don't like packageless classes
@@ -319,20 +393,21 @@ might be several reasons:
     please report it, preferably with the simplest example on which you can
     find ProGuard to fail.</dd>
 
-<dt><a name="verifyerror"><b>VerifyError: Unable to pop operand off an empty
-    stack</b></a></dt>
+<dt><a name="verifyerror"><b>VerifyError</b></a></dt>
 
 <dd>Verification errors when executing a program are almost certainly the
     result of a bug in the optimization step of ProGuard. Make sure you are
     using the latest version. You should be able to work around the problem by
-    using the <code>-dontoptimize</code> option. Please report it, preferably
-    with the simplest example on which you can find ProGuard to fail.</dd>
+    using the <code>-dontoptimize</code> option. You can check the bug database
+    to see if it is a known problem (often with a fix). Otherwise, please
+    report it, preferably with the simplest example on which you can find
+    ProGuard to fail.</dd>
 
 </dl>
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/usage.html b/docs/manual/usage.html
index 09e91ae..e4095c5 100644
--- a/docs/manual/usage.html
+++ b/docs/manual/usage.html
@@ -62,7 +62,7 @@ The sections below provide more details:
 <h2>Input/Output Options</h2>
 
 <dl>
-<dt><code><b>@</b></code><a href="#filename"><i>filename</i></a></dt>
+<dt><a name="at"><code><b>@</b></code></a><a href="#filename"><i>filename</i></a></dt>
 
 <dd>Short for '<code>-include</code> <i>filename</i>'.</dd>
 
@@ -301,7 +301,7 @@ The sections below provide more details:
 <dt><a name="allowaccessmodification"><code><b>-allowaccessmodification</b></code></a></dt>
 
 <dd>Specifies that the access modifiers of classes and class members may be
-    modified during processing. This can improve the results of the
+    broadened during processing. This can improve the results of the
     optimization step. For instance, when inlining a public getter, it may be
     necessary to make the accessed field public too. Although Java's binary
     compatibility specifications (cfr. <a href=
@@ -347,7 +347,10 @@ The sections below provide more details:
     mapping may refer to input classes as well as library classes. This option
     can be useful for <a href="examples.html#incremental">incremental
     obfuscation</a>, i.e. processing add-ons or small patches to an existing
-    piece of code. Only applicable when obfuscating.</dd>
+    piece of code. In such cases, you should consider whether you also need
+    the option <a
+    href="#useuniqueclassmembernames"><code><b>-useuniqueclassmembernames</b></code></a>.
+    Only applicable when obfuscating.</dd>
 
 <dt><a name="obfuscationdictionary"><code><b>-obfuscationdictionary</b></code></a>
     <a href="#filename"><i>filename</i></a></dt>
@@ -388,13 +391,42 @@ The sections below provide more details:
     "http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#40898"
     >Section 8.3</a> and <a href=
     "http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#227768"
-    >Section 8.4.7</a>). Still, some tools have problems with it. Notably,
-    Sun's JREs 1.4 and later fail to serialize objects with overloaded
-    primitive fields. Also, Sun's JDK 1.2.2 javac compiler produces an
-    exception when compiling with such a library (cfr. <a href=
-    "http://developer.java.sun.com/developer/bugParade/bugs/4216736.html">Bug
-    #4216736</a>). You therefore probably shouldn't use this option for
-    processing libraries.</dd>
+    >Section 8.4.7</a>). Still, some tools have problems with it. Notably:
+    <ul>
+    <li>Sun's JDK 1.2.2 <code>javac</code> compiler produces an exception when
+        compiling with such a library (cfr. <a href=
+        "http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4216736">Bug
+        #4216736</a>). You probably shouldn't use this option for processing
+        libraries.
+    <li>Sun's JRE 1.4 and later fail to serialize objects with overloaded
+        primitive fields.
+    <li>Sun's JRE 1.5 <code>pack200</code> tool reportedly has problems with
+        overloaded class members.
+    </ul></dd>
+
+<dt><a name="useuniqueclassmembernames"><code><b>-useuniqueclassmembernames</b></code></a></dt>
+
+<dd>Specifies to assign the same obfuscated names to class members that have
+    the same names, and different obfuscated names to class members that have
+    different names (for each given class member signature). Without the
+    option, more class members can be mapped to the same short names like 'a',
+    'b', etc. The option therefore increases the size of the resulting code
+    slightly, but it ensures that the saved obfuscation name mapping can
+    always be respected in subsequent incremental obfuscation steps.
+    <p>
+    For instance, consider two distinct interfaces containing methods with the
+    same name and signature. Without this option, these methods may get
+    different obfuscated names in a first obfuscation step. If a patch is then
+    added containing a class that implements both interfaces, ProGuard will
+    have to enforce the same method name for both methods in an incremental
+    obfuscation step. The original obfuscated code is changed, in order to
+    keep the resulting code consistent. With this option <i>in the initial
+    obfuscation step</i>, such renaming will never be necessary.
+    <p>
+    This option is only applicable when obfuscating. In fact, if you are
+    planning on performing incremental obfuscation, you probably want to avoid
+    shrinking and optimization altogether, since these step could remove or
+    modify parts of your code that are essential for later additions.</dd>
 
 <dt><a name="defaultpackage"><code><b>-defaultpackage</b></code></a>
     [<i>package_name</i>]</dt>
@@ -675,20 +707,20 @@ following table summarizes how they are related:
 
 <tr>
 <td>Classes and class members</td>
-<td bgcolor="#E0E0E0"><code>-keep</code></td>
-<td bgcolor="#E0E0E0"><code>-keepnames</code></td>
+<td bgcolor="#E0E0E0"><a href="#keep"><code>-keep</code></a></td>
+<td bgcolor="#E0E0E0"><a href="#keepnames"><code>-keepnames</code></a></td>
 </tr>
 
 <tr>
 <td>Class members only</td>
-<td bgcolor="#E0E0E0"><code>-keepclassmembers</code></td>
-<td bgcolor="#E0E0E0"><code>-keepclassmembernames</code></td>
+<td bgcolor="#E0E0E0"><a href="#keepclassmembers"><code>-keepclassmembers</code></a></td>
+<td bgcolor="#E0E0E0"><a href="#keepclassmembernames"><code>-keepclassmembernames</code></a></td>
 </tr>
 
 <tr>
 <td>Classes and class members, if class members present</td>
-<td bgcolor="#E0E0E0"><code>-keepclasseswithmembers</code></td>
-<td bgcolor="#E0E0E0"><code>-keepclasseswithmembernames</code></td>
+<td bgcolor="#E0E0E0"><a href="#keepclasseswithmembers"><code>-keepclasseswithmembers</code></a></td>
+<td bgcolor="#E0E0E0"><a href="#keepclasseswithmembernames"><code>-keepclasseswithmembernames</code></a></td>
 </tr>
 
 </table>
@@ -879,7 +911,7 @@ files.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/manual/wtk.html b/docs/manual/wtk.html
index ca5c36d..1cf4915 100644
--- a/docs/manual/wtk.html
+++ b/docs/manual/wtk.html
@@ -51,7 +51,7 @@ that's inside the <code>proguard.jar</code>.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/quality.html b/docs/quality.html
index 2ba1dd6..baae1bd 100644
--- a/docs/quality.html
+++ b/docs/quality.html
@@ -31,13 +31,13 @@ full-screen size.
 <p>
 
 In addition, <b>ProGuard</b> is tested against a constantly growing test suite
-(over 160 tests at this time of writing). These small programs contain a wide
-range of common and uncommon constructs, in order to detect any problems as
-soon as possible.
+(over 250 tests at this time of writing). These small programs contain a wide
+range of common and uncommon constructs, in order to detect any regression
+problems as soon as possible.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/results.html b/docs/results.html
index d185032..264c40b 100644
--- a/docs/results.html
+++ b/docs/results.html
@@ -11,7 +11,7 @@
 <h2>Results</h2>
 
 <b>ProGuard</b> shrinks, optimizes, and obfuscates jars quickly and
-effectively. The benefits obviously depend on the original code. The table
+effectively. The improvements obviously depend on the original code. The table
 below presents some typical results:
 <p>
 
@@ -126,7 +126,7 @@ library jars and program jars.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 
diff --git a/docs/screenshots.html b/docs/screenshots.html
index 94cd3ba..2f99b91 100644
--- a/docs/screenshots.html
+++ b/docs/screenshots.html
@@ -49,7 +49,7 @@ You can click on the image to see the full-size version.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 </body>
diff --git a/docs/style.css b/docs/style.css
index 40a12d0..c9798db 100644
--- a/docs/style.css
+++ b/docs/style.css
@@ -24,6 +24,13 @@ h3
   padding: 10px;
 }
 
+h3 div
+{
+  font-weight: normal;
+  font-size: 80%;
+  float: right;
+}
+
 table
 {
   width: 100%;
@@ -34,12 +41,22 @@ th
   padding: 4px;
 }
 
+tr.disappeared td
+{
+  background: #EEEEEE;
+}
+
 td
 {
   background: #EEEEFF;
   padding: 8px;
 }
 
+a
+{
+  text-decoration: none;
+}
+
 img
 {
   border: none;
diff --git a/docs/testimonials.html b/docs/testimonials.html
index 558ac3c..7fea5ca 100644
--- a/docs/testimonials.html
+++ b/docs/testimonials.html
@@ -12,11 +12,11 @@
 
 And now for some shameless self-glorification and name-dropping...
 <p>
-Since its first public release, <b>ProGuard</b> has been welcomed with general
-enthusiasm. It is already being used by developers at companies and
-organizations like Sun, IBM, Siemens, Nokia, and NATO. Although the quotes
-below probably don't represent official views of any kind, encouragements like
-these do keep me happy.
+<b>ProGuard</b> is probably the most popular free obfuscator and shrinker. It
+is already being used by developers at companies and organizations like Sun,
+IBM, HP, Siemens, Nokia, and NATO. Although the quotes below probably don't
+represent official views of any kind, encouragements like these do keep me
+happy.
 <p>
 
 <center><table class="note">
@@ -30,6 +30,30 @@ ProGuard is <b>the</b> ultimate java obfuscator!
 </tr></table></center>
 <p>
 
+Also:
+<center><table class="note">
+<tr><td class="note"><p class="note"><cite>
+ProGuard is pure quality - powerful and trouble-free.
+</cite></p>
+<p class="author">M.B., Statestep</p></td>
+<td class="shadow8"><img src="drop2.gif" width="8" height="100"></td></tr><tr>
+<td class="shadow400"><img src="drop1.gif" width="400" height="8"></td>
+<td class="shadow8"><img src="drop3.gif" width="8" height="8"></td>
+</tr></table></center>
+<p>
+
+And:
+<center><table class="note">
+<tr><td class="note"><p class="note"><cite>
+It is the simplest and most robust obfuscator we have ever used.
+</cite></p>
+<p class="author">I.I., Hewlett-Packard</p></td>
+<td class="shadow8"><img src="drop2.gif" width="8" height="100"></td></tr><tr>
+<td class="shadow400"><img src="drop1.gif" width="400" height="8"></td>
+<td class="shadow8"><img src="drop3.gif" width="8" height="8"></td>
+</tr></table></center>
+<p>
+
 And indeed:
 <center><table class="note">
 <tr><td class="note"><p class="note"><cite>
@@ -90,7 +114,7 @@ You could've been rich.
 
 <hr>
 <address>
-Copyright © 2002-2005
+Copyright © 2002-2006
 <a href="http://www.graphics.cornell.edu/~eric/">Eric Lafortune</a>.
 </address>
 
diff --git a/docs/title.html b/docs/title.html
index 9e5751a..031331b 100644
--- a/docs/title.html
+++ b/docs/title.html
@@ -10,7 +10,7 @@
 
 <div class="title">
 <h1><img src="title.gif" width="154" height="29" alt="ProGuard"></h1>
-<div>Version 3.4</div>
+<div>Version 3.7</div>
 </div>
 
 </body>
diff --git a/examples/ant/applets.xml b/examples/ant/applets.xml
index a02dd3d..820a4f2 100644
--- a/examples/ant/applets.xml
+++ b/examples/ant/applets.xml
@@ -30,13 +30,17 @@
       <method access="native" />
     </keepclasseswithmembernames>
     
-    <!-- Preserve a method that is required in all enumeration classes. -->
+    <!-- Preserve the methods that are required in all enumeration classes. -->
     
     <keepclassmembers extends="java.lang.Enum">
-      <method access="public"
+      <method access="public static"
               type="**[]"
               name="values"
               parameters="" />
+      <method access="public static"
+              type="**"
+              name="valueOf"
+              parameters="java.lang.String" />
     </keepclassmembers>
 
     <!-- Explicitly preserve all serialization members. The Serializable
diff --git a/examples/ant/applications1.xml b/examples/ant/applications1.xml
index 12cf838..7a3d473 100644
--- a/examples/ant/applications1.xml
+++ b/examples/ant/applications1.xml
@@ -8,7 +8,7 @@
   <taskdef resource="proguard/ant/task.properties"
            classpath="lib/proguard.jar" />
 
-  <proguard configuration="../applications.pro" />
+  <proguard configuration="examples/applications.pro" />
 
 </target>
 
diff --git a/examples/ant/applications2.xml b/examples/ant/applications2.xml
index f887581..54947d8 100644
--- a/examples/ant/applications2.xml
+++ b/examples/ant/applications2.xml
@@ -37,10 +37,11 @@
         native <methods>;
     }
 
-    <!-- Preserve a method that is required in all enumeration classes. -->
+    <!-- Preserve the methods that are required in all enumeration classes. -->
 
     -keepclassmembers class * extends java.lang.Enum {
-        public **[] values();
+        public static **[] values();
+        public static ** valueOf(java.lang.String);
     }
 
     <!-- Explicitly preserve all serialization members. The Serializable
diff --git a/examples/ant/applications3.xml b/examples/ant/applications3.xml
index 9edc8db..5a7cb80 100644
--- a/examples/ant/applications3.xml
+++ b/examples/ant/applications3.xml
@@ -41,13 +41,17 @@
       <method access="native" />
     </keepclasseswithmembernames>
 
-    <!-- Preserve a method that is required in all enumeration classes. -->
+    <!-- Preserve the methods that are required in all enumeration classes. -->
 
     <keepclassmembers extends="java.lang.Enum">
-      <method access="public"
+      <method access="public static"
               type="**[]"
               name="values"
               parameters="" />
+      <method access="public static"
+              type="**"
+              name="valueOf"
+              parameters="java.lang.String" />
     </keepclassmembers>
 
     <!-- Explicitly preserve all serialization members. The Serializable
diff --git a/examples/ant/library.xml b/examples/ant/library.xml
index cb88e03..5a8320a 100644
--- a/examples/ant/library.xml
+++ b/examples/ant/library.xml
@@ -51,13 +51,17 @@
       <method access="native" />
     </keepclasseswithmembernames>
     
-    <!-- Preserve a method that is required in all enumeration classes. -->
+    <!-- Preserve the methods that are required in all enumeration classes. -->
     
     <keepclassmembers extends="java.lang.Enum">
-      <method access="public"
+      <method access="public static"
               type="**[]"
               name="values"
               parameters="" />
+      <method access="public static"
+              type="**"
+              name="valueOf"
+              parameters="java.lang.String" />
     </keepclassmembers>
 
     <!-- Explicitly preserve all serialization members. The Serializable
diff --git a/examples/ant/servlets.xml b/examples/ant/servlets.xml
index 8aa43d7..69efebc 100644
--- a/examples/ant/servlets.xml
+++ b/examples/ant/servlets.xml
@@ -30,13 +30,17 @@
       <method access="native" />
     </keepclasseswithmembernames>
     
-    <!-- Preserve a method that is required in all enumeration classes. -->
+    <!-- Preserve the methods that are required in all enumeration classes. -->
     
     <keepclassmembers extends="java.lang.Enum">
-      <method access="public"
+      <method access="public static"
               type="**[]"
               name="values"
               parameters="" />
+      <method access="public static"
+              type="**"
+              name="valueOf"
+              parameters="java.lang.String" />
     </keepclassmembers>
 
     <!-- Explicitly preserve all serialization members. The Serializable
diff --git a/examples/applets.pro b/examples/applets.pro
index 1005150..10dc8aa 100644
--- a/examples/applets.pro
+++ b/examples/applets.pro
@@ -29,10 +29,12 @@
     native <methods>;
 }
 
-# Preserve a method that is required in all enumeration classes.
+# Preserve the special static methods that are required in all enumeration
+# classes.
 
 -keepclassmembers class * extends java.lang.Enum {
-    public **[] values();
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
 }
 
 # Explicitly preserve all serialization members. The Serializable interface
diff --git a/examples/applications.pro b/examples/applications.pro
index 1adf7b2..9b19761 100644
--- a/examples/applications.pro
+++ b/examples/applications.pro
@@ -35,10 +35,12 @@
     native <methods>;
 }
 
-# Preserve a method that is required in all enumeration classes.
+# Preserve the special static methods that are required in all enumeration
+# classes.
 
 -keepclassmembers class * extends java.lang.Enum {
-    public **[] values();
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
 }
 
 # Explicitly preserve all serialization members. The Serializable interface
diff --git a/examples/library.pro b/examples/library.pro
index 1a1a1fa..adf6be3 100644
--- a/examples/library.pro
+++ b/examples/library.pro
@@ -46,10 +46,12 @@
     native <methods>;
 }
 
-# Preserve a method that is required in all enumeration classes.
+# Preserve the special static methods that are required in all enumeration
+# classes.
 
 -keepclassmembers class * extends java.lang.Enum {
-    public **[] values();
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
 }
 
 # Explicitly preserve all serialization members. The Serializable interface
diff --git a/examples/servlets.pro b/examples/servlets.pro
index 3e16c8c..71a7c6a 100644
--- a/examples/servlets.pro
+++ b/examples/servlets.pro
@@ -30,10 +30,12 @@
     native <methods>;
 }
 
-# Preserve a method that is required in all enumeration classes.
+# Preserve the special static methods that are required in all enumeration
+# classes.
 
 -keepclassmembers class * extends java.lang.Enum {
-    public **[] values();
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
 }
 
 # Explicitly preserve all serialization members. The Serializable interface
diff --git a/src/proguard/ArgumentWordReader.java b/src/proguard/ArgumentWordReader.java
index b0e4fef..9bb93a8 100644
--- a/src/proguard/ArgumentWordReader.java
+++ b/src/proguard/ArgumentWordReader.java
@@ -1,8 +1,8 @@
-/* $Id: ArgumentWordReader.java,v 1.14 2005/06/11 13:13:15 eric Exp $
+/* $Id: ArgumentWordReader.java,v 1.14.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ClassMemberSpecification.java b/src/proguard/ClassMemberSpecification.java
index 389721f..654b4a9 100644
--- a/src/proguard/ClassMemberSpecification.java
+++ b/src/proguard/ClassMemberSpecification.java
@@ -1,8 +1,8 @@
-/* $Id: ClassMemberSpecification.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassMemberSpecification.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ClassPath.java b/src/proguard/ClassPath.java
index 70dac03..8d80507 100644
--- a/src/proguard/ClassPath.java
+++ b/src/proguard/ClassPath.java
@@ -1,8 +1,8 @@
-/* $Id: ClassPath.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassPath.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ClassPathEntry.java b/src/proguard/ClassPathEntry.java
index f526891..02c967d 100644
--- a/src/proguard/ClassPathEntry.java
+++ b/src/proguard/ClassPathEntry.java
@@ -1,8 +1,8 @@
-/* $Id: ClassPathEntry.java,v 1.10 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassPathEntry.java,v 1.10.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ClassSpecification.java b/src/proguard/ClassSpecification.java
index 28eb248..c2cebca 100644
--- a/src/proguard/ClassSpecification.java
+++ b/src/proguard/ClassSpecification.java
@@ -1,8 +1,8 @@
-/* $Id: ClassSpecification.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassSpecification.java,v 1.4.2.2 2006/04/09 08:55:53 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -85,11 +85,11 @@ public class ClassSpecification implements Cloneable
      *                                 specified class members are present.
      */
     public ClassSpecification(int     requiredSetAccessFlags,
-                               int     requiredUnsetAccessFlags,
-                               String  className,
-                               String  extendsClassName,
-                               boolean markClassFiles,
-                               boolean markConditionally)
+                              int     requiredUnsetAccessFlags,
+                              String  className,
+                              String  extendsClassName,
+                              boolean markClassFiles,
+                              boolean markConditionally)
     {
         this(requiredSetAccessFlags,
              requiredUnsetAccessFlags,
@@ -126,12 +126,12 @@ public class ClassSpecification implements Cloneable
      * @param comments                 provides optional comments on this option.
      */
     public ClassSpecification(int     requiredSetAccessFlags,
-                               int     requiredUnsetAccessFlags,
-                               String  className,
-                               String  extendsClassName,
-                               boolean markClassFiles,
-                               boolean markConditionally,
-                               String  comments)
+                              int     requiredUnsetAccessFlags,
+                              String  className,
+                              String  extendsClassName,
+                              boolean markClassFiles,
+                              boolean markConditionally,
+                              String  comments)
     {
         this.requiredSetAccessFlags   = requiredSetAccessFlags;
         this.requiredUnsetAccessFlags = requiredUnsetAccessFlags;
diff --git a/src/proguard/ClassSpecificationVisitorFactory.java b/src/proguard/ClassSpecificationVisitorFactory.java
index 0b9e4b7..f9d6a9d 100644
--- a/src/proguard/ClassSpecificationVisitorFactory.java
+++ b/src/proguard/ClassSpecificationVisitorFactory.java
@@ -1,4 +1,4 @@
-/* $Id: ClassSpecificationVisitorFactory.java,v 1.6 2005/08/21 20:25:33 eric Exp $
+/* $Id: ClassSpecificationVisitorFactory.java,v 1.7.2.1 2006/05/06 13:19:00 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
@@ -353,6 +353,8 @@ public class ClassSpecificationVisitorFactory
     {
         return string != null &&
             (string.indexOf('*') >= 0 ||
-             string.indexOf('?') >= 0);
+             string.indexOf('?') >= 0 ||
+             string.indexOf('%') >= 0 ||
+             string.indexOf(',') >= 0);
     }
 }
diff --git a/src/proguard/Configuration.java b/src/proguard/Configuration.java
index 109ab21..9c6772f 100644
--- a/src/proguard/Configuration.java
+++ b/src/proguard/Configuration.java
@@ -1,8 +1,8 @@
-/* $Id: Configuration.java,v 1.17 2005/06/11 13:13:15 eric Exp $
+/* $Id: Configuration.java,v 1.17.2.2 2006/06/07 22:36:52 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -154,6 +154,11 @@ public class Configuration
     public boolean   overloadAggressively        = false;
 
     /**
+     * Specifies whether to generate globally unique class member names.
+     */
+    public boolean   useUniqueClassMemberNames   = false;
+
+    /**
      * An optional default package to which all classes whose name is obfuscated
      * can be moved.
      */
diff --git a/src/proguard/ConfigurationConstants.java b/src/proguard/ConfigurationConstants.java
index 3c6a6ca..bd14cfa 100644
--- a/src/proguard/ConfigurationConstants.java
+++ b/src/proguard/ConfigurationConstants.java
@@ -1,4 +1,4 @@
-/* $Id: ConfigurationConstants.java,v 1.12 2005/06/11 14:50:16 eric Exp $
+/* $Id: ConfigurationConstants.java,v 1.12.2.1 2006/06/07 22:36:52 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
@@ -58,6 +58,7 @@ class ConfigurationConstants
     public static final String APPLY_MAPPING_OPTION                              = "-applymapping";
     public static final String OBFUSCATION_DICTIONARY_OPTION                     = "-obfuscationdictionary";
     public static final String OVERLOAD_AGGRESSIVELY_OPTION                      = "-overloadaggressively";
+    public static final String USE_UNIQUE_CLASS_MEMBER_NAMES_OPTION              = "-useuniqueclassmembernames";
     public static final String DEFAULT_PACKAGE_OPTION                            = "-defaultpackage";
     public static final String DONT_USE_MIXED_CASE_CLASS_NAMES_OPTION            = "-dontusemixedcaseclassnames";
     public static final String KEEP_ATTRIBUTES_OPTION                            = "-keepattributes";
diff --git a/src/proguard/ConfigurationParser.java b/src/proguard/ConfigurationParser.java
index 1584fc1..0840e33 100644
--- a/src/proguard/ConfigurationParser.java
+++ b/src/proguard/ConfigurationParser.java
@@ -1,8 +1,8 @@
-/* $Id: ConfigurationParser.java,v 1.25 2005/08/21 20:25:33 eric Exp $
+/* $Id: ConfigurationParser.java,v 1.26.2.4 2006/10/18 21:12:47 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -134,6 +134,7 @@ public class ConfigurationParser
             else if (ConfigurationConstants.APPLY_MAPPING_OPTION                             .startsWith(nextWord)) configuration.applyMapping                     = parseFile();
             else if (ConfigurationConstants.OBFUSCATION_DICTIONARY_OPTION                    .startsWith(nextWord)) configuration.obfuscationDictionary            = parseFile();
             else if (ConfigurationConstants.OVERLOAD_AGGRESSIVELY_OPTION                     .startsWith(nextWord)) configuration.overloadAggressively             = parseNoArgument(true);
+            else if (ConfigurationConstants.USE_UNIQUE_CLASS_MEMBER_NAMES_OPTION             .startsWith(nextWord)) configuration.useUniqueClassMemberNames        = parseNoArgument(true);
             else if (ConfigurationConstants.DEFAULT_PACKAGE_OPTION                           .startsWith(nextWord)) configuration.defaultPackage                   = ClassUtil.internalClassName(parseOptionalArgument());
             else if (ConfigurationConstants.DONT_USE_MIXED_CASE_CLASS_NAMES_OPTION           .startsWith(nextWord)) configuration.useMixedCaseClassNames           = parseNoArgument(false);
             else if (ConfigurationConstants.KEEP_ATTRIBUTES_OPTION                           .startsWith(nextWord)) configuration.keepAttributes                   = parseKeepAttributesArguments(configuration.keepAttributes);
@@ -146,7 +147,7 @@ public class ConfigurationParser
             else if (ConfigurationConstants.DUMP_OPTION                                      .startsWith(nextWord)) configuration.dump                             = parseOptionalFile();
             else
             {
-                throw new ParseException("Unknown configuration " + reader.locationDescription());
+                throw new ParseException("Unknown option " + reader.locationDescription());
             }
         }
     }
@@ -801,7 +802,7 @@ public class ConfigurationParser
                 // Read a comma (or a different word).
                 readNextWord();
             }
-            
+
             if (!ConfigurationConstants.ARGUMENT_SEPARATOR_KEYWORD.equals(nextWord))
             {
                 break;
@@ -954,6 +955,7 @@ public class ConfigurationParser
                   c == ']' ||
                   c == '<' ||
                   c == '>' ||
+                  c == '-' ||
                   c == '!' ||
                   c == '*' ||
                   c == '?' ||
diff --git a/src/proguard/ConfigurationWriter.java b/src/proguard/ConfigurationWriter.java
index 168ed39..d2d2bb5 100644
--- a/src/proguard/ConfigurationWriter.java
+++ b/src/proguard/ConfigurationWriter.java
@@ -1,8 +1,8 @@
-/* $Id: ConfigurationWriter.java,v 1.18 2005/08/21 19:28:48 eric Exp $
+/* $Id: ConfigurationWriter.java,v 1.18.2.3 2006/06/07 22:36:52 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -140,6 +140,7 @@ public class ConfigurationWriter
         writeOption(ConfigurationConstants.APPLY_MAPPING_OPTION,                              configuration.applyMapping);
         writeOption(ConfigurationConstants.OBFUSCATION_DICTIONARY_OPTION,                     configuration.obfuscationDictionary);
         writeOption(ConfigurationConstants.OVERLOAD_AGGRESSIVELY_OPTION,                      configuration.overloadAggressively);
+        writeOption(ConfigurationConstants.USE_UNIQUE_CLASS_MEMBER_NAMES_OPTION,              configuration.useUniqueClassMemberNames);
         writeOption(ConfigurationConstants.DEFAULT_PACKAGE_OPTION,                            configuration.defaultPackage);
         writeOption(ConfigurationConstants.DONT_USE_MIXED_CASE_CLASS_NAMES_OPTION,            !configuration.useMixedCaseClassNames);
         writeOption(ConfigurationConstants.KEEP_ATTRIBUTES_OPTION,                            ListUtil.commaSeparatedString(configuration.keepAttributes));
@@ -375,12 +376,12 @@ public class ConfigurationWriter
                 // Write out the field name and descriptor.
                 String name       = classMemberSpecification.name;
                 String descriptor = classMemberSpecification.descriptor;
-                
+
                 if (name == null)
                 {
                     name = ConfigurationConstants.ANY_CLASS_MEMBER_KEYWORD;
                 }
-    
+
                 writer.print(descriptor != null ?
                     ClassUtil.externalFullFieldDescription(0,
                                                            name,
@@ -413,12 +414,12 @@ public class ConfigurationWriter
                 // Write out the method name and descriptor.
                 String name       = classMemberSpecification.name;
                 String descriptor = classMemberSpecification.descriptor;
-                
+
                 if (name == null)
                 {
                     name = ConfigurationConstants.ANY_CLASS_MEMBER_KEYWORD;
                 }
-    
+
                 writer.print(descriptor != null ?
                     ClassUtil.externalFullMethodDescription(ClassConstants.INTERNAL_METHOD_NAME_INIT,
                                                             0,
diff --git a/src/proguard/DataEntryReaderFactory.java b/src/proguard/DataEntryReaderFactory.java
index 03e7a7f..becb13f 100644
--- a/src/proguard/DataEntryReaderFactory.java
+++ b/src/proguard/DataEntryReaderFactory.java
@@ -1,8 +1,8 @@
-/* $Id: DataEntryReaderFactory.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: DataEntryReaderFactory.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/DataEntryWriterFactory.java b/src/proguard/DataEntryWriterFactory.java
index 2f5a5dd..abd9821 100644
--- a/src/proguard/DataEntryWriterFactory.java
+++ b/src/proguard/DataEntryWriterFactory.java
@@ -1,8 +1,8 @@
-/* $Id: DataEntryWriterFactory.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: DataEntryWriterFactory.java,v 1.4.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MapCleaner.java b/src/proguard/DuplicateClassFilePrinter.java
similarity index 57%
copy from src/proguard/obfuscate/MapCleaner.java
copy to src/proguard/DuplicateClassFilePrinter.java
index a123e76..f039352 100644
--- a/src/proguard/obfuscate/MapCleaner.java
+++ b/src/proguard/DuplicateClassFilePrinter.java
@@ -1,8 +1,8 @@
-/* $Id: MapCleaner.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: DuplicateClassFilePrinter.java,v 1.1.2.1 2006/11/26 15:29:20 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -18,30 +18,29 @@
  * with this program; if not, write to the Free Software Foundation, Inc.,
  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
-package proguard.obfuscate;
+package proguard;
 
-import proguard.classfile.*;
 import proguard.classfile.visitor.ClassFileVisitor;
-
-import java.util.Map;
+import proguard.classfile.*;
+import proguard.classfile.util.*;
 
 /**
- * This ClassFileVisitor clears a given map whenever it visits a class file.
+ * This ClassFileVisitor writes out notes about the class files that it visits
+ * being duplicates.
  *
  * @author Eric Lafortune
  */
-public class MapCleaner implements ClassFileVisitor
+public class DuplicateClassFilePrinter implements ClassFileVisitor
 {
-    private Map map;
+    private WarningPrinter notePrinter;
 
 
     /**
-     * Creates a new MapCleaner.
-     * @param map the map to be cleared.
+     * Creates a new DuplicateClassFileVisitor.
      */
-    public MapCleaner(Map map)
+    public DuplicateClassFilePrinter(WarningPrinter notePrinter)
     {
-        this.map = map;
+        this.notePrinter = notePrinter;
     }
 
 
@@ -49,12 +48,14 @@ public class MapCleaner implements ClassFileVisitor
 
     public void visitProgramClassFile(ProgramClassFile programClassFile)
     {
-        map.clear();
+        notePrinter.print("Note: duplicate definition of program class [" +
+                          ClassUtil.externalClassName(programClassFile.getName()) + "]");
     }
 
 
     public void visitLibraryClassFile(LibraryClassFile libraryClassFile)
     {
-        map.clear();
+        notePrinter.print("Note: duplicate definition of library class [" +
+                          ClassUtil.externalClassName(libraryClassFile.getName()) + "]");
     }
 }
diff --git a/src/proguard/FileWordReader.java b/src/proguard/FileWordReader.java
index 082b8cf..2598954 100644
--- a/src/proguard/FileWordReader.java
+++ b/src/proguard/FileWordReader.java
@@ -1,8 +1,8 @@
-/* $Id: FileWordReader.java,v 1.12 2005/06/11 13:13:15 eric Exp $
+/* $Id: FileWordReader.java,v 1.12.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/GPL.java b/src/proguard/GPL.java
index e8dd9ff..5d29edd 100644
--- a/src/proguard/GPL.java
+++ b/src/proguard/GPL.java
@@ -1,8 +1,8 @@
-/* $Id: GPL.java,v 1.5 2005/09/11 22:14:13 eric Exp $
+/* $Id: GPL.java,v 1.5.2.5 2006/12/11 20:23:22 eric Exp $
  *
- * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
+ * ProGuard -- shrinking, optimization, and obfuscation of Java bytecode.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -150,7 +150,7 @@ public class GPL
 
 
     /**
-     * Returns whether the given package name is has been granted an exception
+     * Returns whether the given package name has been granted an exception
      * against the GPL linking clause, by the copyright holder of ProGuard.
      * This method is not legally binding, but of course the actual license is.
      * Please contact the copyright holder if you would like an exception for
@@ -158,14 +158,17 @@ public class GPL
      */
     private static boolean isKnown(String packageName)
     {
-        return packageName.startsWith("java")                 ||
-               packageName.startsWith("proguard")             ||
-               packageName.startsWith("org.apache.tools.ant") ||
-               packageName.startsWith("org.eclipse")          ||
-               packageName.startsWith("org.netbeans")         ||
-               packageName.startsWith("com.sun.kvem")         ||
-               packageName.startsWith("jg.j2me")              ||
-               packageName.startsWith("jg.common");
+        return packageName.startsWith("java")                   ||
+               packageName.startsWith("sun.reflect")            ||
+               packageName.startsWith("proguard")               ||
+               packageName.startsWith("org.apache.tools.ant")   ||
+               packageName.startsWith("org.apache.tools.maven") ||
+               packageName.startsWith("org.eclipse")            ||
+               packageName.startsWith("org.netbeans")           ||
+               packageName.startsWith("com.sun.kvem")           ||
+               packageName.startsWith("jg.j2me")                ||
+               packageName.startsWith("jg.common")              ||
+               packageName.startsWith("jg.buildengine");
     }
 
 
diff --git a/src/proguard/Initializer.java b/src/proguard/Initializer.java
new file mode 100644
index 0000000..a1ce277
--- /dev/null
+++ b/src/proguard/Initializer.java
@@ -0,0 +1,240 @@
+/* $Id: Initializer.java,v 1.2.2.8 2006/12/11 21:57:29 eric Exp $
+ *
+ * ProGuard -- shrinking, optimization, and obfuscation of Java bytecode.
+ *
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.AllAttrInfoVisitor;
+import proguard.classfile.instruction.AllInstructionVisitor;
+import proguard.classfile.util.*;
+import proguard.classfile.visitor.*;
+import proguard.util.ClassNameListMatcher;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * This class initializes class pools.
+ *
+ * @author Eric Lafortune
+ */
+public class Initializer
+{
+    private Configuration configuration;
+
+
+    /**
+     * Creates a new Initializer to initialize classes according to the given
+     * configuration.
+     */
+    public Initializer(Configuration configuration)
+    {
+        this.configuration = configuration;
+    }
+
+
+    /**
+     * Initializes the classes in the given program class pool and library class
+     * pool, performs some basic checks, and shrinks the library class pool.
+     */
+    public void execute(ClassPool programClassPool,
+                        ClassPool libraryClassPool) throws IOException
+    {
+        int originalLibraryClassPoolSize = libraryClassPool.size();
+
+        // Initialize the class hierarchy for program classes.
+        WarningPrinter hierarchyWarningPrinter = configuration.warn ?
+            new WarningPrinter(System.err) :
+            null;
+
+        programClassPool.classFilesAccept(
+            new ClassFileHierarchyInitializer(programClassPool,
+                                              libraryClassPool,
+                                              hierarchyWarningPrinter));
+
+        // Initialize the class hierarchy for library classes.
+        libraryClassPool.classFilesAccept(
+            new ClassFileHierarchyInitializer(programClassPool,
+                                              libraryClassPool,
+                                              null));
+
+        // Initialize the Class.forName and .class references.
+        WarningPrinter classForNameNotePrinter = configuration.note ?
+            new WarningPrinter(System.out) :
+            null;
+
+        programClassPool.classFilesAccept(
+            new AllMethodVisitor(
+            new AllAttrInfoVisitor(
+            new AllInstructionVisitor(
+           new ClassFileClassForNameReferenceInitializer(programClassPool,
+                                                         libraryClassPool,
+                                                         classForNameNotePrinter,
+                                                         createNoteExceptionMatcher(configuration.keep))))));
+
+        // Initialize the class references from program class members and
+        // attributes.
+        WarningPrinter referenceWarningPrinter = configuration.warn ?
+            new WarningPrinter(System.err) :
+            null;
+
+        programClassPool.classFilesAccept(
+            new ClassFileReferenceInitializer(programClassPool,
+                                              libraryClassPool,
+                                              referenceWarningPrinter));
+
+        if (!configuration.useUniqueClassMemberNames)
+        {
+            // Reconstruct a library class pool with only those library classes
+            // whose hierarchies are referenced by the program classes.
+            libraryClassPool.clear();
+            programClassPool.classFilesAccept(
+                new ReferencedClassFileVisitor(
+                new LibraryClassFileFilter(
+                new ClassFileHierarchyTraveler(true, true, true, false,
+                new LibraryClassFileFilter(
+                new ClassPoolFiller(libraryClassPool))))));
+        }
+
+        // Initialize the class references from library class members.
+
+        libraryClassPool.classFilesAccept(
+            new ClassFileReferenceInitializer(programClassPool,
+                                              libraryClassPool,
+                                              null));
+
+        // Print out a summary of the notes, if necessary.
+        if (configuration.note)
+        {
+            int classForNameNoteCount = classForNameNotePrinter.getWarningCount();
+            if (classForNameNoteCount > 0)
+            {
+                System.err.println("Note: there were " + classForNameNoteCount +
+                                   " class casts of dynamically created class instances.");
+                System.err.println("      You might consider explicitly keeping the mentioned classes and/or");
+                System.err.println("      their implementations (using '-keep').");
+            }
+
+            if (configuration.optimize ||
+                configuration.obfuscate)
+            {
+                // Check for Java 6 files.
+                ClassFileVersionCounter classFileVersionCounter =
+                    new ClassFileVersionCounter(ClassConstants.MAJOR_VERSION_MAX,
+                                                ClassConstants.MINOR_VERSION_MAX);
+
+                programClassPool.classFilesAccept(classFileVersionCounter);
+
+                int java6count = classFileVersionCounter.getCount();
+                if (java6count > 0)
+                {
+                    System.err.println("Note: there were " + java6count +
+                                       " Java 6 program classes.");
+                    System.err.println("      In order to obtain all of the improved start-up performance of Java 6,");
+                    System.err.println("      they should be preverified after having been optimized or obfuscated.");
+                    System.err.println("      Keep any eye on ProGuard version 4.0 for preverification support,");
+                    System.err.println("      at http://proguard.sourceforge.net/");
+                }
+            }
+        }
+
+        // Print out a summary of the warnings, if necessary.
+        if (configuration.warn)
+        {
+            int hierarchyWarningCount = hierarchyWarningPrinter.getWarningCount();
+            if (hierarchyWarningCount > 0)
+            {
+                System.err.println("Warning: there were " + hierarchyWarningCount +
+                                   " unresolved references to superclasses or interfaces.");
+                System.err.println("         You may need to specify additional library jars (using '-libraryjars'),");
+                System.err.println("         or perhaps the '-dontskipnonpubliclibraryclasses' option.");
+            }
+
+            int referenceWarningCount = referenceWarningPrinter.getWarningCount();
+            if (referenceWarningCount > 0)
+            {
+                System.err.println("Warning: there were " + referenceWarningCount +
+                                   " unresolved references to program class members.");
+                System.err.println("         Your input classes appear to be inconsistent.");
+                System.err.println("         You may need to recompile them and try again.");
+                System.err.println("         Alternatively, you may have to specify the options ");
+                System.err.println("         '-dontskipnonpubliclibraryclasses' and/or");
+                System.err.println("         '-dontskipnonpubliclibraryclassmembers'.");
+            }
+
+            if ((hierarchyWarningCount > 0 ||
+                 referenceWarningCount > 0) &&
+                !configuration.ignoreWarnings)
+            {
+                System.err.println("         If you are sure the mentioned classes are not used anyway,");
+                System.err.println("         you could try your luck using the '-ignorewarnings' option.");
+                throw new IOException("Please correct the above warnings first.");
+            }
+        }
+
+        // Discard unused library classes.
+        if (configuration.verbose)
+        {
+            System.out.println("Ignoring unused library classes...");
+            System.out.println("  Original number of library classes: " + originalLibraryClassPoolSize);
+            System.out.println("  Final number of library classes:    " + libraryClassPool.size());
+        }
+    }
+
+
+    /**
+     * Extracts a list of exceptions for which not to print notes, from the
+     * keep configuration.
+     */
+    private ClassNameListMatcher createNoteExceptionMatcher(List noteExceptions)
+    {
+        if (noteExceptions != null)
+        {
+            List noteExceptionNames = new ArrayList(noteExceptions.size());
+            for (int index = 0; index < noteExceptions.size(); index++)
+            {
+                ClassSpecification classSpecification = (ClassSpecification)noteExceptions.get(index);
+                if (classSpecification.markClassFiles)
+                {
+                    // If the class itself is being kept, it's ok.
+                    String className = classSpecification.className;
+                    if (className != null)
+                    {
+                        noteExceptionNames.add(className);
+                    }
+
+                    // If all of its extensions are being kept, it's ok too.
+                    String extendsClassName = classSpecification.extendsClassName;
+                    if (extendsClassName != null)
+                    {
+                        noteExceptionNames.add(extendsClassName);
+                    }
+                }
+            }
+
+            if (noteExceptionNames.size() > 0)
+            {
+                return new ClassNameListMatcher(noteExceptionNames);
+            }
+        }
+
+        return null;
+    }
+}
diff --git a/src/proguard/InputReader.java b/src/proguard/InputReader.java
new file mode 100644
index 0000000..c8b82b9
--- /dev/null
+++ b/src/proguard/InputReader.java
@@ -0,0 +1,208 @@
+/* $Id: InputReader.java,v 1.1.2.3 2006/11/26 15:29:20 eric Exp $
+ *
+ * ProGuard -- shrinking, optimization, and obfuscation of Java bytecode.
+ *
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard;
+
+import proguard.classfile.ClassPool;
+import proguard.classfile.util.WarningPrinter;
+import proguard.classfile.visitor.*;
+import proguard.io.*;
+
+import java.io.IOException;
+
+/**
+ * This class reads the input class files.
+ *
+ * @author Eric Lafortune
+ */
+public class InputReader
+{
+    private Configuration configuration;
+
+
+    /**
+     * Creates a new InputReader to read input class files as specified by the
+     * given configuration.
+     */
+    public InputReader(Configuration configuration)
+    {
+        this.configuration = configuration;
+    }
+
+
+    /**
+     * Fills the given program class pool and library class pool by reading
+     * class files, based on the current configuration.
+     */
+    public void execute(ClassPool programClassPool,
+                        ClassPool libraryClassPool) throws IOException
+    {
+        // Check if we have at least some program jars.
+        if (configuration.programJars == null)
+        {
+            throw new IOException("The input is empty. You have to specify one or more '-injars' options.");
+        }
+
+        WarningPrinter warningPrinter = configuration.warn ?
+            new WarningPrinter(System.err) :
+            null;
+
+        WarningPrinter notePrinter = configuration.note ?
+            new WarningPrinter(System.out) :
+            null;
+
+        DuplicateClassFilePrinter duplicateClassFilePrinter = configuration.note ?
+            new DuplicateClassFilePrinter(notePrinter) :
+            null;
+
+        // Read the program class files.
+        // Prepare a data entry reader to filter all classes,
+        // which are then decoded to classes by a class reader,
+        // which are then put in the class pool by a class pool filler.
+        readInput("Reading program ",
+                  configuration.programJars,
+                  new ClassFileFilter(
+                  new ClassFileReader(false,
+                                      configuration.skipNonPublicLibraryClasses,
+                                      configuration.skipNonPublicLibraryClassMembers,
+                                      warningPrinter,
+                  new ClassFilePresenceFilter(programClassPool, duplicateClassFilePrinter,
+                  new ClassPoolFiller(programClassPool)))));
+
+        // Check if we have at least some input classes.
+        if (programClassPool.size() == 0)
+        {
+            throw new IOException("The input doesn't contain any classes. Did you specify the proper '-injars' options?");
+        }
+
+        // Read the library class files, if any.
+        if (configuration.libraryJars != null)
+        {
+            // Prepare a data entry reader to filter all classes,
+            // which are then decoded to classes by a class reader,
+            // which are then put in the class pool by a class pool filler.
+            readInput("Reading library ",
+                      configuration.libraryJars,
+                      new ClassFileFilter(
+                      new ClassFileReader(true,
+                                          configuration.skipNonPublicLibraryClasses,
+                                          configuration.skipNonPublicLibraryClassMembers,
+                                          warningPrinter,
+                      new ClassFilePresenceFilter(programClassPool, duplicateClassFilePrinter,
+                      new ClassFilePresenceFilter(libraryClassPool, duplicateClassFilePrinter,
+                      new ClassPoolFiller(libraryClassPool))))));
+        }
+
+        // Print out a summary of the notes, if necessary.
+        if (configuration.note)
+        {
+            int noteCount = notePrinter.getWarningCount();
+            if (noteCount > 0)
+            {
+                System.err.println("Note: there were " + noteCount +
+                                   " duplicate class definitions.");
+            }
+        }
+
+        // Print out a summary of the warnings, if necessary.
+        if (configuration.warn)
+        {
+            int warningCount = warningPrinter.getWarningCount();
+            if (warningCount > 0)
+            {
+                System.err.println("Warning: there were " + warningCount +
+                                   " classes in incorrectly named files.");
+                System.err.println("         You should make sure all file names correspond to their class names.");
+                System.err.println("         The directory hierarchies must correspond to the package hierarchies.");
+
+                if (!configuration.ignoreWarnings)
+                {
+                    System.err.println("         If you don't mind the mentioned classes not being written out,");
+                    System.err.println("         you could try your luck using the '-ignorewarnings' option.");
+                    throw new IOException("Please correct the above warnings first.");
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Reads all input entries from the given class path.
+     */
+    private void readInput(String          messagePrefix,
+                           ClassPath       classPath,
+                           DataEntryReader reader) throws IOException
+    {
+        readInput(messagePrefix,
+                  classPath,
+                  0,
+                  classPath.size(),
+                  reader);
+    }
+
+
+    /**
+     * Reads all input entries from the given section of the given class path.
+     */
+    public void readInput(String          messagePrefix,
+                          ClassPath       classPath,
+                          int             fromIndex,
+                          int             toIndex,
+                          DataEntryReader reader) throws IOException
+    {
+        for (int index = fromIndex; index < toIndex; index++)
+        {
+            ClassPathEntry entry = classPath.get(index);
+            if (!entry.isOutput())
+            {
+                readInput(messagePrefix, entry, reader);
+            }
+        }
+    }
+
+
+    /**
+     * Reads the given input class path entry.
+     */
+    private void readInput(String          messagePrefix,
+                           ClassPathEntry  classPathEntry,
+                           DataEntryReader dataEntryReader) throws IOException
+    {
+        try
+        {
+            // Create a reader that can unwrap jars, wars, ears, and zips.
+            DataEntryReader reader =
+                DataEntryReaderFactory.createDataEntryReader(messagePrefix,
+                                                             classPathEntry,
+                                                             dataEntryReader);
+
+            // Create the data entry pump.
+            DirectoryPump directoryPump =
+                new DirectoryPump(classPathEntry.getFile());
+
+            // Pump the data entries into the reader.
+            directoryPump.pumpDataEntries(reader);
+        }
+        catch (IOException ex)
+        {
+            throw new IOException("Can't read [" + classPathEntry + "] (" + ex.getMessage() + ")");
+        }
+    }
+}
diff --git a/src/proguard/OutputWriter.java b/src/proguard/OutputWriter.java
new file mode 100644
index 0000000..c41f5b4
--- /dev/null
+++ b/src/proguard/OutputWriter.java
@@ -0,0 +1,174 @@
+/* $Id: OutputWriter.java,v 1.1.2.1 2006/03/26 14:30:14 eric Exp $
+ *
+ * ProGuard -- shrinking, optimization, and obfuscation of Java bytecode.
+ *
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard;
+
+import proguard.classfile.ClassPool;
+import proguard.io.*;
+
+import java.io.IOException;
+
+/**
+ * This class writes the output class files.
+ *
+ * @author Eric Lafortune
+ */
+public class OutputWriter
+{
+    private Configuration configuration;
+
+
+    /**
+     * Creates a new OutputWriter to write output class files as specified by
+     * the given configuration.
+     */
+    public OutputWriter(Configuration configuration)
+    {
+        this.configuration = configuration;
+    }
+
+
+    /**
+     * Writes the given class pool to class files, based on the current
+     * configuration.
+     */
+    public void execute(ClassPool programClassPool) throws IOException
+    {
+        ClassPath programJars = configuration.programJars;
+
+        // Perform a check on the first jar.
+        ClassPathEntry firstEntry = programJars.get(0);
+        if (firstEntry.isOutput())
+        {
+            throw new IOException("The output jar [" + firstEntry.getName() +
+                                  "] must be specified after an input jar, or it will be empty.");
+        }
+
+        // Perform some checks on the output jars.
+        for (int index = 0; index < programJars.size() - 1; index++)
+        {
+            ClassPathEntry entry = programJars.get(index);
+            if (entry.isOutput())
+            {
+                // Check if all but the last output jars have filters.
+                if (entry.getFilter()    == null &&
+                    entry.getJarFilter() == null &&
+                    entry.getWarFilter() == null &&
+                    entry.getEarFilter() == null &&
+                    entry.getZipFilter() == null &&
+                    programJars.get(index + 1).isOutput())
+                {
+                    throw new IOException("The output jar [" + entry.getName() +
+                                          "] must have a filter, or all subsequent jars will be empty.");
+                }
+
+                // Check if the output jar name is different from the input jar names.
+                for (int inIndex = 0; inIndex < programJars.size(); inIndex++)
+                {
+                    ClassPathEntry otherEntry = programJars.get(inIndex);
+
+                    if (!otherEntry.isOutput() &&
+                        entry.getFile().equals(otherEntry.getFile()))
+                    {
+                        throw new IOException("The output jar [" + entry.getName() +
+                                              "] must be different from all input jars.");
+                    }
+                }
+            }
+        }
+
+        int firstInputIndex = 0;
+        int lastInputIndex  = 0;
+
+        // Go over all program class path entries.
+        for (int index = 0; index < programJars.size(); index++)
+        {
+            // Is it an input entry?
+            ClassPathEntry entry = programJars.get(index);
+            if (!entry.isOutput())
+            {
+                // Remember the index of the last input entry.
+                lastInputIndex = index;
+            }
+            else
+            {
+                // Check if this the last output entry in a series.
+                int nextIndex = index + 1;
+                if (nextIndex == programJars.size() ||
+                    !programJars.get(nextIndex).isOutput())
+                {
+                    // Write the processed input entries to the output entries.
+                    writeOutput(programClassPool,
+                                programJars,
+                                firstInputIndex,
+                                lastInputIndex + 1,
+                                nextIndex);
+
+                    // Start with the next series of input entries.
+                    firstInputIndex = nextIndex;
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Transfers the specified input jars to the specified output jars.
+     */
+    private void writeOutput(ClassPool programClassPool,
+                             ClassPath classPath,
+                             int       fromInputIndex,
+                             int       fromOutputIndex,
+                             int       toOutputIndex)
+    throws IOException
+    {
+        try
+        {
+            // Construct the writer that can write jars, wars, ears, zips, and
+            // directories, cascading over the specified output entries.
+            DataEntryWriter writer =
+                DataEntryWriterFactory.createDataEntryWriter(classPath,
+                                                             fromOutputIndex,
+                                                             toOutputIndex);
+
+            // Create the reader that can write classes and copy resource
+            // files to the above writer.
+            DataEntryReader reader =
+                new ClassFileFilter(new ClassFileRewriter(programClassPool,
+                                                          writer),
+                                    new DataEntryCopier(writer));
+
+            // Go over the specified input entries and write their processed
+            // versions.
+            new InputReader(configuration).readInput("  Copying resources from program ",
+                                                     classPath,
+                                                     fromInputIndex,
+                                                     fromOutputIndex,
+                                                     reader);
+
+            // Close all output entries.
+            writer.close();
+        }
+        catch (IOException ex)
+        {
+            throw new IOException("Can't write [" + classPath.get(fromOutputIndex).getName() + "] (" + ex.getMessage() + ")");
+        }
+    }
+}
diff --git a/src/proguard/ParseException.java b/src/proguard/ParseException.java
index e64fc9c..88e5e5f 100644
--- a/src/proguard/ParseException.java
+++ b/src/proguard/ParseException.java
@@ -1,8 +1,8 @@
-/* $Id: ParseException.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: ParseException.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ProGuard.java b/src/proguard/ProGuard.java
index e874887..b237f62 100644
--- a/src/proguard/ProGuard.java
+++ b/src/proguard/ProGuard.java
@@ -1,8 +1,8 @@
-/* $Id: ProGuard.java,v 1.101 2005/10/22 11:53:39 eric Exp $
+/* $Id: ProGuard.java,v 1.101.2.13 2006/12/11 21:57:04 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -22,19 +22,13 @@
 package proguard;
 
 import proguard.classfile.ClassPool;
-import proguard.classfile.attribute.AllAttrInfoVisitor;
 import proguard.classfile.editor.ConstantPoolSorter;
-import proguard.classfile.instruction.AllInstructionVisitor;
-import proguard.classfile.util.*;
 import proguard.classfile.visitor.*;
-import proguard.io.*;
 import proguard.obfuscate.Obfuscator;
 import proguard.optimize.Optimizer;
 import proguard.shrink.Shrinker;
-import proguard.util.ClassNameListMatcher;
 
 import java.io.*;
-import java.util.*;
 
 /**
  * Tool for shrinking, optimizing, and obfuscating Java class files.
@@ -43,7 +37,7 @@ import java.util.*;
  */
 public class ProGuard
 {
-    public static final String VERSION = "ProGuard, version 3.4";
+    public static final String VERSION = "ProGuard, version 3.7";
 
     private Configuration configuration;
     private ClassPool     programClassPool = new ClassPool();
@@ -134,132 +128,23 @@ public class ProGuard
 
 
     /**
-     * Reads the input jars (or directories).
+     * Reads the input class files.
      */
     private void readInput() throws IOException
     {
         if (configuration.verbose)
         {
-            System.out.println("Reading jars...");
+            System.out.println("Reading input...");
         }
 
-        // Check if we have at least some program jars.
-        if (configuration.programJars == null)
-        {
-            throw new IOException("The input is empty. You have to specify one or more '-injars' options.");
-        }
-
-        // Read the input program jars.
-        readInput("Reading program ",
-                  configuration.programJars,
-                  createDataEntryClassPoolFiller(false));
-
-        // Check if we have at least some input class files.
-        if (programClassPool.size() == 0)
-        {
-            throw new IOException("The input doesn't contain any class files. Did you specify the proper '-injars' options?");
-        }
-
-        // Read all library jars.
-        if (configuration.libraryJars != null)
-        {
-            readInput("Reading library ",
-                      configuration.libraryJars,
-                      createDataEntryClassPoolFiller(true));
-        }
-    }
-
-
-    /**
-     * Creates a DataEntryReader that will decode class files and put them in
-     * the proper class pool.
-     */
-    private DataEntryReader createDataEntryClassPoolFiller(boolean isLibrary)
-    {
-        // Get the proper class pool.
-        ClassPool classPool = isLibrary ?
-            libraryClassPool :
-            programClassPool;
-
-        // Prepare a data entry reader to filter all class files,
-        // which are then decoded to class files by a class file reader,
-        // which are then put in the class pool by a class pool filler.
-        return
-            new ClassFileFilter(
-            new ClassFileReader(isLibrary,
-                                configuration.skipNonPublicLibraryClasses,
-                                configuration.skipNonPublicLibraryClassMembers,
-                                configuration.note,
-            new ClassPoolFiller(classPool, configuration.note)));
+        // Fill the program class pool and the library class pool.
+        new InputReader(configuration).execute(programClassPool, libraryClassPool);
     }
 
 
     /**
-     * Reads all input entries from the given class path.
-     */
-    private void readInput(String          messagePrefix,
-                           ClassPath       classPath,
-                           DataEntryReader reader) throws IOException
-    {
-        readInput(messagePrefix,
-                  classPath,
-                  0,
-                  classPath.size(),
-                  reader);
-    }
-
-
-    /**
-     * Reads all input entries from the given section of the given class path.
-     */
-    private void readInput(String          messagePrefix,
-                           ClassPath       classPath,
-                           int             fromIndex,
-                           int             toIndex,
-                           DataEntryReader reader) throws IOException
-    {
-        for (int index = fromIndex; index < toIndex; index++)
-        {
-            ClassPathEntry entry = classPath.get(index);
-            if (!entry.isOutput())
-            {
-                readInput(messagePrefix, entry, reader);
-            }
-        }
-    }
-
-
-    /**
-     * Reads the given input class path entry.
-     */
-    private void readInput(String          messagePrefix,
-                           ClassPathEntry  classPathEntry,
-                           DataEntryReader dataEntryReader) throws IOException
-    {
-        try
-        {
-            // Create a reader that can unwrap jars, wars, ears, and zips.
-            DataEntryReader reader =
-                DataEntryReaderFactory.createDataEntryReader(messagePrefix,
-                                                             classPathEntry,
-                                                             dataEntryReader);
-
-            // Create the data entry pump.
-            DirectoryPump directoryPump =
-                new DirectoryPump(classPathEntry.getFile());
-
-            // Pump the data entries into the reader.
-            directoryPump.pumpDataEntries(reader);
-        }
-        catch (IOException ex)
-        {
-            throw new IOException("Can't read [" + classPathEntry + "] (" + ex.getMessage() + ")");
-        }
-    }
-
-
-    /**
-     * Initializes the cross-references between all class files.
+     * Initializes the cross-references between all classes, performs some
+     * basic checks, and shrinks the library class pool.
      */
     private void initialize() throws IOException
     {
@@ -268,148 +153,7 @@ public class ProGuard
             System.out.println("Initializing...");
         }
 
-        int originalLibraryClassPoolSize = libraryClassPool.size();
-
-        // Initialize the class hierarchy for program class files.
-        ClassFileHierarchyInitializer classFileHierarchyInitializer =
-            new ClassFileHierarchyInitializer(programClassPool,
-                                              libraryClassPool,
-                                              configuration.warn);
-
-        programClassPool.classFilesAccept(classFileHierarchyInitializer);
-
-        // Initialize the class hierarchy for library class files.
-        ClassFileHierarchyInitializer classFileHierarchyInitializer2 =
-            new ClassFileHierarchyInitializer(programClassPool,
-                                              libraryClassPool,
-                                              false);
-
-        libraryClassPool.classFilesAccept(classFileHierarchyInitializer2);
-
-        // Initialize the Class.forName and .class references.
-        ClassFileClassForNameReferenceInitializer classFileClassForNameReferenceInitializer =
-            new ClassFileClassForNameReferenceInitializer(programClassPool,
-                                                          libraryClassPool,
-                                                          configuration.note,
-                                                          createNoteExceptionMatcher(configuration.keep));
-
-        programClassPool.classFilesAccept(
-            new AllMethodVisitor(
-            new AllAttrInfoVisitor(
-            new AllInstructionVisitor(classFileClassForNameReferenceInitializer))));
-
-        // Initialize the class references from program class members and attributes.
-        ClassFileReferenceInitializer classFileReferenceInitializer =
-            new ClassFileReferenceInitializer(programClassPool,
-                                              libraryClassPool,
-                                              configuration.warn);
-
-        programClassPool.classFilesAccept(classFileReferenceInitializer);
-
-        // Reinitialize the library class pool with only those library classes
-        // whose hierarchies are referenced by the program classes.
-        ClassPool newLibraryClassPool = new ClassPool();
-        programClassPool.classFilesAccept(
-            new AllCpInfoVisitor(
-            new ReferencedClassFileVisitor(
-            new LibraryClassFileFilter(
-            new ClassFileHierarchyTraveler(true, true, true, false,
-            new LibraryClassFileFilter(
-            new ClassPoolFiller(newLibraryClassPool, false)))))));
-
-        libraryClassPool = newLibraryClassPool;
-
-        // Initialize the class references from library class members.
-        ClassFileReferenceInitializer classFileReferenceInitializer2 =
-            new ClassFileReferenceInitializer(programClassPool,
-                                              libraryClassPool,
-                                              false);
-
-        libraryClassPool.classFilesAccept(classFileReferenceInitializer2);
-
-        int noteCount = classFileClassForNameReferenceInitializer.getNoteCount();
-        if (noteCount > 0)
-        {
-            System.err.println("Note: there were " + noteCount +
-                               " class casts of dynamically created class instances.");
-            System.err.println("      You might consider explicitly keeping the mentioned classes and/or");
-            System.err.println("      their implementations (using '-keep').");
-        }
-
-        int hierarchyWarningCount = classFileHierarchyInitializer.getWarningCount();
-        if (hierarchyWarningCount > 0)
-        {
-            System.err.println("Warning: there were " + hierarchyWarningCount +
-                               " unresolved references to superclasses or interfaces.");
-            System.err.println("         You may need to specify additional library jars (using '-libraryjars'),");
-            System.err.println("         or perhaps the '-dontskipnonpubliclibraryclasses' option.");
-        }
-
-        int referenceWarningCount = classFileReferenceInitializer.getWarningCount();
-        if (referenceWarningCount > 0)
-        {
-            System.err.println("Warning: there were " + referenceWarningCount +
-                               " unresolved references to program class members.");
-            System.err.println("         Your input class files appear to be inconsistent.");
-            System.err.println("         You may need to recompile them and try again.");
-        }
-
-        if ((hierarchyWarningCount > 0 ||
-             referenceWarningCount > 0) &&
-            !configuration.ignoreWarnings)
-        {
-            System.err.println("         If you are sure the mentioned classes are not used anyway,");
-            System.err.println("         you could try your luck using the '-ignorewarnings' option.");
-            throw new IOException("Please correct the above warnings first.");
-        }
-
-        // Discard unused library classes.
-        if (configuration.verbose)
-        {
-            System.out.println("Removed unused library classes...");
-            System.out.println("  Original number of library classes: " + originalLibraryClassPoolSize);
-            System.out.println("  Final number of library classes:    " + libraryClassPool.size());
-        }
-    }
-
-
-    /**
-     * Extracts a list of exceptions for which not to print notes, from the
-     * keep configuration.
-     */
-    private ClassNameListMatcher createNoteExceptionMatcher(List noteExceptions)
-    {
-        if (noteExceptions != null)
-        {
-            List noteExceptionNames = new ArrayList(noteExceptions.size());
-            for (int index = 0; index < noteExceptions.size(); index++)
-            {
-                ClassSpecification classSpecification = (ClassSpecification)noteExceptions.get(index);
-                if (classSpecification.markClassFiles)
-                {
-                    // If the class itself is being kept, it's ok.
-                    String className = classSpecification.className;
-                    if (className != null)
-                    {
-                        noteExceptionNames.add(className);
-                    }
-
-                    // If all of its extensions are being kept, it's ok too.
-                    String extendsClassName = classSpecification.extendsClassName;
-                    if (extendsClassName != null)
-                    {
-                        noteExceptionNames.add(extendsClassName);
-                    }
-                }
-            }
-
-            if (noteExceptionNames.size() > 0)
-            {
-                return new ClassNameListMatcher(noteExceptionNames);
-            }
-        }
-
-        return null;
+        new Initializer(configuration).execute(programClassPool, libraryClassPool);
     }
 
 
@@ -498,7 +242,7 @@ public class ProGuard
 
         if (configuration.verbose)
         {
-            System.out.println("Removed unused program classes and class elements...");
+            System.out.println("Removing unused program classes and class elements...");
             System.out.println("  Original number of program classes: " + originalProgramClassPoolSize);
             System.out.println("  Final number of program classes:    " + newProgramClassPoolSize);
         }
@@ -570,133 +314,17 @@ public class ProGuard
 
 
     /**
-     * Writes the output jars.
+     * Writes the output claaa files.
      */
     private void writeOutput() throws IOException
     {
         if (configuration.verbose)
         {
-            System.out.println("Writing jars...");
-        }
-
-        ClassPath programJars = configuration.programJars;
-
-        // Perform a check on the first jar.
-        ClassPathEntry firstEntry = programJars.get(0);
-        if (firstEntry.isOutput())
-        {
-            throw new IOException("The output jar [" + firstEntry.getName() +
-                                  "] must be specified after an input jar, or it will be empty.");
-        }
-
-        // Perform some checks on the output jars.
-        for (int index = 0; index < programJars.size() - 1; index++)
-        {
-            ClassPathEntry entry = programJars.get(index);
-            if (entry.isOutput())
-            {
-                // Check if all but the last output jars have filters.
-                if (entry.getFilter()    == null &&
-                    entry.getJarFilter() == null &&
-                    entry.getWarFilter() == null &&
-                    entry.getEarFilter() == null &&
-                    entry.getZipFilter() == null &&
-                    programJars.get(index + 1).isOutput())
-                {
-                    throw new IOException("The output jar [" + entry.getName() +
-                                          "] must have a filter, or all subsequent jars will be empty.");
-                }
-
-                // Check if the output jar name is different from the input jar names.
-                for (int inIndex = 0; inIndex < programJars.size(); inIndex++)
-                {
-                    ClassPathEntry otherEntry = programJars.get(inIndex);
-
-                    if (!otherEntry.isOutput() &&
-                        entry.getFile().equals(otherEntry.getFile()))
-                    {
-                        throw new IOException("The output jar [" + entry.getName() +
-                                              "] must be different from all input jars.");
-                    }
-                }
-            }
+            System.out.println("Writing output...");
         }
 
-        int firstInputIndex = 0;
-        int lastInputIndex  = 0;
-
-        // Go over all program class path entries.
-        for (int index = 0; index < programJars.size(); index++)
-        {
-            // Is it an input entry?
-            ClassPathEntry entry = programJars.get(index);
-            if (!entry.isOutput())
-            {
-                // Remember the index of the last input entry.
-                lastInputIndex = index;
-            }
-            else
-            {
-                // Check if this the last output entry in a series.
-                int nextIndex = index + 1;
-                if (nextIndex == programJars.size() ||
-                    !programJars.get(nextIndex).isOutput())
-                {
-                    // Write the processed input entries to the output entries.
-                    writeOutput(programJars,
-                                firstInputIndex,
-                                lastInputIndex + 1,
-                                nextIndex);
-
-                    // Start with the next series of input entries.
-                    firstInputIndex = nextIndex;
-                }
-            }
-        }
-    }
-
-
-
-
-    /**
-     * Transfers the specified input jars to the specified output jars.
-     */
-    private void writeOutput(ClassPath classPath,
-                             int       fromInputIndex,
-                             int       fromOutputIndex,
-                             int       toOutputIndex)
-    throws IOException
-    {
-        try
-        {
-            // Construct the writer that can write jars, wars, ears, zips, and
-            // directories, cascading over the specified output entries.
-            DataEntryWriter writer =
-                DataEntryWriterFactory.createDataEntryWriter(classPath,
-                                                             fromOutputIndex,
-                                                             toOutputIndex);
-
-            // Create the reader that can write class files and copy resource
-            // files to the above writer.
-            DataEntryReader reader =
-                new ClassFileFilter(new ClassFileRewriter(programClassPool,
-                                                          writer),
-                                    new DataEntryCopier(writer));
-
-            // Read and handle the specified input entries.
-            readInput("  Copying resources from program ",
-                      classPath,
-                      fromInputIndex,
-                      fromOutputIndex,
-                      reader);
-
-            // Close all output entries.
-            writer.close();
-        }
-        catch (IOException ex)
-        {
-            throw new IOException("Can't write [" + classPath.get(fromOutputIndex).getName() + "] (" + ex.getMessage() + ")");
-        }
+        // Write out the program class pool.
+        new OutputWriter(configuration).execute(programClassPool);
     }
 
 
diff --git a/src/proguard/SubclassedClassFileFilter.java b/src/proguard/SubclassedClassFileFilter.java
index b74dba7..6a6568b 100644
--- a/src/proguard/SubclassedClassFileFilter.java
+++ b/src/proguard/SubclassedClassFileFilter.java
@@ -1,8 +1,8 @@
-/* $Id: SubclassedClassFileFilter.java,v 1.11 2005/06/11 13:13:15 eric Exp $
+/* $Id: SubclassedClassFileFilter.java,v 1.11.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/WordReader.java b/src/proguard/WordReader.java
index 7eaa554..d6188fe 100644
--- a/src/proguard/WordReader.java
+++ b/src/proguard/WordReader.java
@@ -1,8 +1,8 @@
-/* $Id: WordReader.java,v 1.20 2005/06/11 14:50:16 eric Exp $
+/* $Id: WordReader.java,v 1.20.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ant/ClassMemberSpecificationElement.java b/src/proguard/ant/ClassMemberSpecificationElement.java
index 5f8ba37..103b19d 100644
--- a/src/proguard/ant/ClassMemberSpecificationElement.java
+++ b/src/proguard/ant/ClassMemberSpecificationElement.java
@@ -1,8 +1,8 @@
-/* $Id: ClassMemberSpecificationElement.java,v 1.5 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassMemberSpecificationElement.java,v 1.5.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ant/ClassPathElement.java b/src/proguard/ant/ClassPathElement.java
index 654831b..77905d7 100644
--- a/src/proguard/ant/ClassPathElement.java
+++ b/src/proguard/ant/ClassPathElement.java
@@ -1,8 +1,8 @@
-/* $Id: ClassPathElement.java,v 1.9 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassPathElement.java,v 1.9.2.2 2006/08/10 20:53:47 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -96,6 +96,21 @@ public class ClassPathElement extends Path
             fileNames = list();
         }
 
+        if (output)
+        {
+            if (fileNames.length != 1)
+            {
+                throw new BuildException("The <outjar> element must specify exactly one file or directory ["+fileNames.length+"]");
+            }
+        }
+        else
+        {
+            if (fileNames.length < 1)
+            {
+                throw new BuildException("The <injar> element must specify at least one file or directory");
+            }
+        }
+
         for (int index = 0; index < fileNames.length; index++)
         {
             // Create a new class path entry, with the proper file name and
diff --git a/src/proguard/ant/ClassSpecificationElement.java b/src/proguard/ant/ClassSpecificationElement.java
index 49ce274..cbc2e22 100644
--- a/src/proguard/ant/ClassSpecificationElement.java
+++ b/src/proguard/ant/ClassSpecificationElement.java
@@ -1,8 +1,8 @@
-/* $Id: ClassSpecificationElement.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassSpecificationElement.java,v 1.4.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ant/ConfigurationElement.java b/src/proguard/ant/ConfigurationElement.java
index 09f1358..e4e3e2f 100644
--- a/src/proguard/ant/ConfigurationElement.java
+++ b/src/proguard/ant/ConfigurationElement.java
@@ -1,8 +1,8 @@
-/* $Id: ConfigurationElement.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: ConfigurationElement.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ant/ConfigurationTask.java b/src/proguard/ant/ConfigurationTask.java
index 5bbff11..80531e1 100644
--- a/src/proguard/ant/ConfigurationTask.java
+++ b/src/proguard/ant/ConfigurationTask.java
@@ -1,8 +1,8 @@
-/* $Id: ConfigurationTask.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: ConfigurationTask.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ant/KeepAttributeElement.java b/src/proguard/ant/KeepAttributeElement.java
index ff44e16..dd37bce 100644
--- a/src/proguard/ant/KeepAttributeElement.java
+++ b/src/proguard/ant/KeepAttributeElement.java
@@ -1,8 +1,8 @@
-/* $Id: KeepAttributeElement.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: KeepAttributeElement.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/ant/ProGuardTask.java b/src/proguard/ant/ProGuardTask.java
index 5f5483a..e6c4d84 100644
--- a/src/proguard/ant/ProGuardTask.java
+++ b/src/proguard/ant/ProGuardTask.java
@@ -1,8 +1,8 @@
-/* $Id: ProGuardTask.java,v 1.32 2005/06/11 13:21:35 eric Exp $
+/* $Id: ProGuardTask.java,v 1.32.2.2 2006/06/07 22:36:52 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -142,6 +142,12 @@ public class ProGuardTask extends ConfigurationTask
     }
 
 
+    public void setUseuniqueclassmembernames(boolean useUniqueClassMemberNames)
+    {
+        configuration.useUniqueClassMemberNames = useUniqueClassMemberNames;
+    }
+
+
     public void setDefaultpackage(String defaultPackage)
     {
         configuration.defaultPackage = ClassUtil.internalClassName(defaultPackage);
diff --git a/src/proguard/classfile/ClassConstants.java b/src/proguard/classfile/ClassConstants.java
index a1fced8..de35fcf 100644
--- a/src/proguard/classfile/ClassConstants.java
+++ b/src/proguard/classfile/ClassConstants.java
@@ -1,4 +1,4 @@
-/* $Id: ClassConstants.java,v 1.25 2005/05/22 00:30:30 eric Exp $
+/* $Id: ClassConstants.java,v 1.25.2.2 2006/12/11 21:57:29 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
@@ -36,7 +36,7 @@ public interface ClassConstants
 
     public static final int MAJOR_VERSION_MIN = 45;
     public static final int MINOR_VERSION_MIN = 3;
-    public static final int MAJOR_VERSION_MAX = 49;
+    public static final int MAJOR_VERSION_MAX = 50;
     public static final int MINOR_VERSION_MAX = 0;
 
     public static final int INTERNAL_ACC_PUBLIC       = 0x0001;
@@ -142,6 +142,8 @@ public interface ClassConstants
     public static final char EXTERNAL_PACKAGE_SEPARATOR = '.';
     public static final char INTERNAL_PACKAGE_SEPARATOR = '/';
 
+    public static final char INTERNAL_SPECIAL_CHARACTER = '-';
+
     public static final char EXTERNAL_METHOD_ARGUMENTS_OPEN      = '(';
     public static final char EXTERNAL_METHOD_ARGUMENTS_CLOSE     = ')';
     public static final char EXTERNAL_METHOD_ARGUMENTS_SEPARATOR = ',';
diff --git a/src/proguard/classfile/ClassCpInfo.java b/src/proguard/classfile/ClassCpInfo.java
index 8996e48..16884d8 100644
--- a/src/proguard/classfile/ClassCpInfo.java
+++ b/src/proguard/classfile/ClassCpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: ClassCpInfo.java,v 1.21 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassCpInfo.java,v 1.21.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/ClassFile.java b/src/proguard/classfile/ClassFile.java
index 8cb7e7c..18f1b04 100644
--- a/src/proguard/classfile/ClassFile.java
+++ b/src/proguard/classfile/ClassFile.java
@@ -1,9 +1,9 @@
-/* $Id: ClassFile.java,v 1.25 2005/06/11 13:21:35 eric Exp $
+/* $Id: ClassFile.java,v 1.27.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/ClassPool.java b/src/proguard/classfile/ClassPool.java
index 6a7a9a6..df7112e 100644
--- a/src/proguard/classfile/ClassPool.java
+++ b/src/proguard/classfile/ClassPool.java
@@ -1,9 +1,9 @@
-/* $Id: ClassPool.java,v 1.18 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassPool.java,v 1.18.2.6 2006/11/26 15:29:20 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -38,22 +38,20 @@ public class ClassPool
 
 
     /**
-     * Adds the given ClassFile to the class pool. If a class file of the same
-     * name is already present, it is left unchanged and the old class file is
-     * returned.
+     * Clears the class pool.
      */
-    public ClassFile addClass(ClassFile classFile)
+    public void clear()
     {
-        String name = classFile.getName();
+        classFiles.clear();
+    }
 
-        ClassFile previousClassFile = (ClassFile)classFiles.put(name, classFile);
-        if (previousClassFile != null)
-        {
-            // We'll put the original one back.
-            classFiles.put(name, previousClassFile);
-        }
 
-        return previousClassFile;
+    /**
+     * Adds the given ClassFile to the class pool.
+     */
+    public void addClass(ClassFile classFile)
+    {
+        classFiles.put(classFile.getName(), classFile);
     }
 
 
@@ -67,23 +65,22 @@ public class ClassPool
 
 
     /**
-     * Returns a ClassFile from the class pool based on its name. Returns
+     * Returns a Clazz from the class pool based on its name. Returns
      * <code>null</code> if the class with the given name is not in the class
-     * pool. Returns the base class if the class name is an array type, and the
-     * <code>java.lang.Object</code> class if that base class is a primitive type.
+     * pool. Returns the base class if the class name is an array type.
      */
     public ClassFile getClass(String className)
     {
-        return (ClassFile)classFiles.get(ClassUtil.internalClassNameFromType(className));
+        return (ClassFile)classFiles.get(ClassUtil.internalClassNameFromClassType(className));
     }
 
 
     /**
-     * Returns an Iterator of all ClassFile objects in the class pool.
+     * Returns an Iterator of all class file names in the class pool.
      */
-    public Iterator elements()
+    public Iterator classNames()
     {
-        return classFiles.values().iterator();
+        return classFiles.keySet().iterator();
     }
 
 
@@ -111,18 +108,11 @@ public class ClassPool
      */
     public void classFilesAccept(ClassFileVisitor classFileVisitor)
     {
-        Iterator iterator = elements();
+        Iterator iterator = classFiles.values().iterator();
         while (iterator.hasNext())
         {
             ClassFile classFile = (ClassFile)iterator.next();
-try{
             classFile.accept(classFileVisitor);
-}catch (RuntimeException ex) {
-    System.out.println("Runtime exception while processing class file ["+classFile.getName()+"]");
-    throw ex;
-}catch (Error er) {
-    System.out.println("Runtime error while processing class file ["+classFile.getName()+"]");
-    throw er;}
         }
     }
 
diff --git a/src/proguard/classfile/CpInfo.java b/src/proguard/classfile/CpInfo.java
index b3229c6..c1cd69d 100644
--- a/src/proguard/classfile/CpInfo.java
+++ b/src/proguard/classfile/CpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: CpInfo.java,v 1.23 2005/06/11 13:13:15 eric Exp $
+/* $Id: CpInfo.java,v 1.23.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/DoubleCpInfo.java b/src/proguard/classfile/DoubleCpInfo.java
index ac5f5b3..96b3f1d 100644
--- a/src/proguard/classfile/DoubleCpInfo.java
+++ b/src/proguard/classfile/DoubleCpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: DoubleCpInfo.java,v 1.18 2005/06/11 13:13:15 eric Exp $
+/* $Id: DoubleCpInfo.java,v 1.18.2.2 2006/10/07 08:42:27 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -56,7 +56,7 @@ public class DoubleCpInfo extends CpInfo
      */
     public double getValue()
     {
-        return Double.longBitsToDouble(((long)u4highBytes << 32) | (long)u4lowBytes);
+        return Double.longBitsToDouble((long)u4highBytes << 32 | (u4lowBytes & 0xffffffffL));
     }
 
 
diff --git a/src/proguard/classfile/FieldInfo.java b/src/proguard/classfile/FieldInfo.java
index ba85840..829dd09 100644
--- a/src/proguard/classfile/FieldInfo.java
+++ b/src/proguard/classfile/FieldInfo.java
@@ -1,9 +1,9 @@
-/* $Id: FieldInfo.java,v 1.13 2005/06/11 13:13:15 eric Exp $
+/* $Id: FieldInfo.java,v 1.13.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/FieldrefCpInfo.java b/src/proguard/classfile/FieldrefCpInfo.java
index f4ec471..6ef7042 100644
--- a/src/proguard/classfile/FieldrefCpInfo.java
+++ b/src/proguard/classfile/FieldrefCpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: FieldrefCpInfo.java,v 1.21 2005/06/11 13:13:15 eric Exp $
+/* $Id: FieldrefCpInfo.java,v 1.21.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/FloatCpInfo.java b/src/proguard/classfile/FloatCpInfo.java
index 1d9fffd..91d2dc3 100644
--- a/src/proguard/classfile/FloatCpInfo.java
+++ b/src/proguard/classfile/FloatCpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: FloatCpInfo.java,v 1.17 2005/06/11 13:13:15 eric Exp $
+/* $Id: FloatCpInfo.java,v 1.17.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/IntegerCpInfo.java b/src/proguard/classfile/IntegerCpInfo.java
index 855667c..1f58e01 100644
--- a/src/proguard/classfile/IntegerCpInfo.java
+++ b/src/proguard/classfile/IntegerCpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: IntegerCpInfo.java,v 1.17 2005/06/11 13:13:15 eric Exp $
+/* $Id: IntegerCpInfo.java,v 1.17.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/InterfaceMethodrefCpInfo.java b/src/proguard/classfile/InterfaceMethodrefCpInfo.java
index 2840763..7e5f672 100644
--- a/src/proguard/classfile/InterfaceMethodrefCpInfo.java
+++ b/src/proguard/classfile/InterfaceMethodrefCpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: InterfaceMethodrefCpInfo.java,v 1.21 2005/06/11 13:13:15 eric Exp $
+/* $Id: InterfaceMethodrefCpInfo.java,v 1.21.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/LibraryClassFile.java b/src/proguard/classfile/LibraryClassFile.java
index 65fc671..cf457ee 100644
--- a/src/proguard/classfile/LibraryClassFile.java
+++ b/src/proguard/classfile/LibraryClassFile.java
@@ -1,9 +1,9 @@
-/* $Id: LibraryClassFile.java,v 1.40 2005/06/11 13:21:35 eric Exp $
+/* $Id: LibraryClassFile.java,v 1.40.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/LibraryFieldInfo.java b/src/proguard/classfile/LibraryFieldInfo.java
index 880fc6c..55f8a8e 100644
--- a/src/proguard/classfile/LibraryFieldInfo.java
+++ b/src/proguard/classfile/LibraryFieldInfo.java
@@ -1,9 +1,9 @@
-/* $Id: LibraryFieldInfo.java,v 1.16 2005/06/25 22:07:51 eric Exp $
+/* $Id: LibraryFieldInfo.java,v 1.16.2.2 2006/02/08 00:04:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -60,11 +60,21 @@ public class LibraryFieldInfo extends LibraryMemberInfo implements FieldInfo
     }
 
 
-    /**
-     * Accepts the given visitor.
-     */
+    // Implementations for LibraryMemberInfo.
+
     public void accept(LibraryClassFile libraryClassFile, MemberInfoVisitor memberInfoVisitor)
     {
         memberInfoVisitor.visitLibraryFieldInfo(libraryClassFile, this);
     }
+
+
+    // Implementations for MemberInfo.
+
+    public void referencedClassesAccept(ClassFileVisitor classFileVisitor)
+    {
+        if (referencedClassFile != null)
+        {
+            referencedClassFile.accept(classFileVisitor);
+        }
+    }
 }
diff --git a/src/proguard/classfile/LibraryMemberInfo.java b/src/proguard/classfile/LibraryMemberInfo.java
index bd5310e..1ccb07f 100644
--- a/src/proguard/classfile/LibraryMemberInfo.java
+++ b/src/proguard/classfile/LibraryMemberInfo.java
@@ -1,9 +1,9 @@
-/* $Id: LibraryMemberInfo.java,v 1.22 2005/06/11 13:13:15 eric Exp $
+/* $Id: LibraryMemberInfo.java,v 1.22.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/LibraryMethodInfo.java b/src/proguard/classfile/LibraryMethodInfo.java
index 9d3ef9d..11c8e2e 100644
--- a/src/proguard/classfile/LibraryMethodInfo.java
+++ b/src/proguard/classfile/LibraryMethodInfo.java
@@ -1,9 +1,9 @@
-/* $Id: LibraryMethodInfo.java,v 1.16 2005/06/25 22:07:51 eric Exp $
+/* $Id: LibraryMethodInfo.java,v 1.16.2.2 2006/02/08 00:04:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -60,11 +60,27 @@ public class LibraryMethodInfo extends LibraryMemberInfo implements MethodInfo
     }
 
 
-    /**
-     * Accepts the given visitor.
-     */
+    // Implementations for LibraryMemberInfo.
+
     public void accept(LibraryClassFile libraryClassFile, MemberInfoVisitor memberInfoVisitor)
     {
         memberInfoVisitor.visitLibraryMethodInfo(libraryClassFile, this);
     }
+
+
+    // Implementations for MemberInfo.
+
+    public void referencedClassesAccept(ClassFileVisitor classFileVisitor)
+    {
+        if (referencedClassFiles != null)
+        {
+            for (int i = 0; i < referencedClassFiles.length; i++)
+            {
+                if (referencedClassFiles[i] != null)
+                {
+                    referencedClassFiles[i].accept(classFileVisitor);
+                }
+            }
+        }
+    }
 }
diff --git a/src/proguard/classfile/LongCpInfo.java b/src/proguard/classfile/LongCpInfo.java
index bec79d0..86ddfbd 100644
--- a/src/proguard/classfile/LongCpInfo.java
+++ b/src/proguard/classfile/LongCpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: LongCpInfo.java,v 1.17 2005/06/11 13:13:15 eric Exp $
+/* $Id: LongCpInfo.java,v 1.17.2.2 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -56,7 +56,7 @@ public class LongCpInfo extends CpInfo
      */
     public long getValue()
     {
-        return (long)u4highBytes << 32 | (long)u4lowBytes;
+        return (long)u4highBytes << 32 | (u4lowBytes & 0xffffffffL);
     }
 
 
diff --git a/src/proguard/classfile/MemberInfo.java b/src/proguard/classfile/MemberInfo.java
index 93fb9d6..a9f66b4 100644
--- a/src/proguard/classfile/MemberInfo.java
+++ b/src/proguard/classfile/MemberInfo.java
@@ -1,9 +1,9 @@
-/* $Id: MemberInfo.java,v 1.20 2005/06/11 13:13:15 eric Exp $
+/* $Id: MemberInfo.java,v 1.20.2.2 2006/02/08 00:04:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -21,7 +21,7 @@
  */
 package proguard.classfile;
 
-import proguard.classfile.visitor.MemberInfoVisitor;
+import proguard.classfile.visitor.*;
 
 /**
  * Representation of a field or method from a program class file.
@@ -50,4 +50,10 @@ public interface MemberInfo extends VisitorAccepter
      * Accepts the given class file visitor.
      */
     public void accept(ClassFile classFile, MemberInfoVisitor memberInfoVisitor);
+
+    /**
+     * Lets the ClassFile objects referenced in the descriptor string
+     * accept the given visitor.
+     */
+    public void referencedClassesAccept(ClassFileVisitor classFileVisitor);
 }
diff --git a/src/proguard/classfile/MethodInfo.java b/src/proguard/classfile/MethodInfo.java
index 3b040e6..e228ee4 100644
--- a/src/proguard/classfile/MethodInfo.java
+++ b/src/proguard/classfile/MethodInfo.java
@@ -1,9 +1,9 @@
-/* $Id: MethodInfo.java,v 1.13 2005/06/11 13:13:15 eric Exp $
+/* $Id: MethodInfo.java,v 1.13.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/MethodrefCpInfo.java b/src/proguard/classfile/MethodrefCpInfo.java
index 6cd267a..7da2395 100644
--- a/src/proguard/classfile/MethodrefCpInfo.java
+++ b/src/proguard/classfile/MethodrefCpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: MethodrefCpInfo.java,v 1.21 2005/06/11 13:13:15 eric Exp $
+/* $Id: MethodrefCpInfo.java,v 1.21.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/NameAndTypeCpInfo.java b/src/proguard/classfile/NameAndTypeCpInfo.java
index b0ad21d..1e29ac9 100644
--- a/src/proguard/classfile/NameAndTypeCpInfo.java
+++ b/src/proguard/classfile/NameAndTypeCpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: NameAndTypeCpInfo.java,v 1.21 2005/06/11 13:13:15 eric Exp $
+/* $Id: NameAndTypeCpInfo.java,v 1.21.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/ProgramClassFile.java b/src/proguard/classfile/ProgramClassFile.java
index a97cb14..3c5b96b 100644
--- a/src/proguard/classfile/ProgramClassFile.java
+++ b/src/proguard/classfile/ProgramClassFile.java
@@ -1,9 +1,9 @@
-/* $Id: ProgramClassFile.java,v 1.37 2005/06/11 13:21:35 eric Exp $
+/* $Id: ProgramClassFile.java,v 1.37.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/ProgramFieldInfo.java b/src/proguard/classfile/ProgramFieldInfo.java
index 828988a..c1d04a8 100644
--- a/src/proguard/classfile/ProgramFieldInfo.java
+++ b/src/proguard/classfile/ProgramFieldInfo.java
@@ -1,9 +1,9 @@
-/* $Id: ProgramFieldInfo.java,v 1.18 2005/06/11 13:13:15 eric Exp $
+/* $Id: ProgramFieldInfo.java,v 1.18.2.2 2006/02/08 00:04:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -78,6 +78,8 @@ public class ProgramFieldInfo extends ProgramMemberInfo implements FieldInfo
     }
 
 
+    // Implementations for MemberInfo.
+
     public void referencedClassesAccept(ClassFileVisitor classFileVisitor)
     {
         if (referencedClassFile != null)
diff --git a/src/proguard/classfile/ProgramMemberInfo.java b/src/proguard/classfile/ProgramMemberInfo.java
index 1f2e637..8af14d9 100644
--- a/src/proguard/classfile/ProgramMemberInfo.java
+++ b/src/proguard/classfile/ProgramMemberInfo.java
@@ -1,9 +1,9 @@
-/* $Id: ProgramMemberInfo.java,v 1.29 2005/06/11 13:13:15 eric Exp $
+/* $Id: ProgramMemberInfo.java,v 1.29.2.2 2006/02/08 00:04:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -113,13 +113,6 @@ abstract public class ProgramMemberInfo implements MemberInfo
 
 
     /**
-     * Lets the ClassFile objects referenced in the descriptor string
-     * accept the given visitor.
-     */
-    public abstract void referencedClassesAccept(ClassFileVisitor classFileVisitor);
-
-
-    /**
      * Imports the field or method data to internal representation.
      */
     protected void read(DataInput din, ClassFile cf) throws IOException
diff --git a/src/proguard/classfile/ProgramMethodInfo.java b/src/proguard/classfile/ProgramMethodInfo.java
index b7ee3c6..7863382 100644
--- a/src/proguard/classfile/ProgramMethodInfo.java
+++ b/src/proguard/classfile/ProgramMethodInfo.java
@@ -1,9 +1,9 @@
-/* $Id: ProgramMethodInfo.java,v 1.19 2005/06/11 13:21:35 eric Exp $
+/* $Id: ProgramMethodInfo.java,v 1.19.2.2 2006/02/08 00:04:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -78,6 +78,8 @@ public class ProgramMethodInfo extends ProgramMemberInfo implements MethodInfo
     }
 
 
+    // Implementations for MemberInfo.
+
     public void referencedClassesAccept(ClassFileVisitor classFileVisitor)
     {
         if (referencedClassFiles != null)
diff --git a/src/proguard/classfile/RefCpInfo.java b/src/proguard/classfile/RefCpInfo.java
index af939af..a072103 100644
--- a/src/proguard/classfile/RefCpInfo.java
+++ b/src/proguard/classfile/RefCpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: RefCpInfo.java,v 1.22 2005/06/11 13:13:15 eric Exp $
+/* $Id: RefCpInfo.java,v 1.22.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/StringCpInfo.java b/src/proguard/classfile/StringCpInfo.java
index 9b094ac..4b6205d 100644
--- a/src/proguard/classfile/StringCpInfo.java
+++ b/src/proguard/classfile/StringCpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: StringCpInfo.java,v 1.18 2005/06/11 13:13:15 eric Exp $
+/* $Id: StringCpInfo.java,v 1.18.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/Utf8CpInfo.java b/src/proguard/classfile/Utf8CpInfo.java
index f84e672..7d9e17c 100644
--- a/src/proguard/classfile/Utf8CpInfo.java
+++ b/src/proguard/classfile/Utf8CpInfo.java
@@ -1,9 +1,9 @@
-/* $Id: Utf8CpInfo.java,v 1.21 2005/06/11 13:13:15 eric Exp $
+/* $Id: Utf8CpInfo.java,v 1.21.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/VisitorAccepter.java b/src/proguard/classfile/VisitorAccepter.java
index 7bb10d4..269843b 100644
--- a/src/proguard/classfile/VisitorAccepter.java
+++ b/src/proguard/classfile/VisitorAccepter.java
@@ -1,9 +1,9 @@
-/* $Id: VisitorAccepter.java,v 1.12 2005/06/11 13:13:15 eric Exp $
+/* $Id: VisitorAccepter.java,v 1.12.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/AttrInfo.java b/src/proguard/classfile/attribute/AttrInfo.java
index 056e57f..cd55b6a 100644
--- a/src/proguard/classfile/attribute/AttrInfo.java
+++ b/src/proguard/classfile/attribute/AttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: AttrInfo.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: AttrInfo.java,v 1.4.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/AttrInfoVisitor.java b/src/proguard/classfile/attribute/AttrInfoVisitor.java
index db5ba3b..2ff0c75 100644
--- a/src/proguard/classfile/attribute/AttrInfoVisitor.java
+++ b/src/proguard/classfile/attribute/AttrInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: AttrInfoVisitor.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: AttrInfoVisitor.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/CodeAttrInfo.java b/src/proguard/classfile/attribute/CodeAttrInfo.java
index b092965..67594e3 100644
--- a/src/proguard/classfile/attribute/CodeAttrInfo.java
+++ b/src/proguard/classfile/attribute/CodeAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: CodeAttrInfo.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: CodeAttrInfo.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/DeprecatedAttrInfo.java b/src/proguard/classfile/attribute/DeprecatedAttrInfo.java
index 24ebd51..0eb31f0 100644
--- a/src/proguard/classfile/attribute/DeprecatedAttrInfo.java
+++ b/src/proguard/classfile/attribute/DeprecatedAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: DeprecatedAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: DeprecatedAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/EnclosingMethodAttrInfo.java b/src/proguard/classfile/attribute/EnclosingMethodAttrInfo.java
index 7f00fd6..3134c6f 100644
--- a/src/proguard/classfile/attribute/EnclosingMethodAttrInfo.java
+++ b/src/proguard/classfile/attribute/EnclosingMethodAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: EnclosingMethodAttrInfo.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: EnclosingMethodAttrInfo.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/ExceptionInfo.java b/src/proguard/classfile/attribute/ExceptionInfo.java
index bae6bf6..e0f64d4 100644
--- a/src/proguard/classfile/attribute/ExceptionInfo.java
+++ b/src/proguard/classfile/attribute/ExceptionInfo.java
@@ -1,9 +1,9 @@
-/* $Id: ExceptionInfo.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: ExceptionInfo.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/ExceptionInfoVisitor.java b/src/proguard/classfile/attribute/ExceptionInfoVisitor.java
index abff86c..722f36b 100644
--- a/src/proguard/classfile/attribute/ExceptionInfoVisitor.java
+++ b/src/proguard/classfile/attribute/ExceptionInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: ExceptionInfoVisitor.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: ExceptionInfoVisitor.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/ExceptionsAttrInfo.java b/src/proguard/classfile/attribute/ExceptionsAttrInfo.java
index 2268fec..54cecf4 100644
--- a/src/proguard/classfile/attribute/ExceptionsAttrInfo.java
+++ b/src/proguard/classfile/attribute/ExceptionsAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: ExceptionsAttrInfo.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: ExceptionsAttrInfo.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/InnerClassesAttrInfo.java b/src/proguard/classfile/attribute/InnerClassesAttrInfo.java
index 5c2f629..5e03f56 100644
--- a/src/proguard/classfile/attribute/InnerClassesAttrInfo.java
+++ b/src/proguard/classfile/attribute/InnerClassesAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: InnerClassesAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: InnerClassesAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/InnerClassesInfo.java b/src/proguard/classfile/attribute/InnerClassesInfo.java
index dac0a70..f09320e 100644
--- a/src/proguard/classfile/attribute/InnerClassesInfo.java
+++ b/src/proguard/classfile/attribute/InnerClassesInfo.java
@@ -1,9 +1,9 @@
-/* $Id: InnerClassesInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: InnerClassesInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/InnerClassesInfoVisitor.java b/src/proguard/classfile/attribute/InnerClassesInfoVisitor.java
index de3b05c..bf594cf 100644
--- a/src/proguard/classfile/attribute/InnerClassesInfoVisitor.java
+++ b/src/proguard/classfile/attribute/InnerClassesInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: InnerClassesInfoVisitor.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: InnerClassesInfoVisitor.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/LibraryAttrInfo.java b/src/proguard/classfile/attribute/LibraryAttrInfo.java
index ad12694..85385cd 100644
--- a/src/proguard/classfile/attribute/LibraryAttrInfo.java
+++ b/src/proguard/classfile/attribute/LibraryAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: LibraryAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: LibraryAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/LineNumberInfo.java b/src/proguard/classfile/attribute/LineNumberInfo.java
index 0d7542b..ce8c887 100644
--- a/src/proguard/classfile/attribute/LineNumberInfo.java
+++ b/src/proguard/classfile/attribute/LineNumberInfo.java
@@ -1,9 +1,9 @@
-/* $Id: LineNumberInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: LineNumberInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/LineNumberTableAttrInfo.java b/src/proguard/classfile/attribute/LineNumberTableAttrInfo.java
index 0d4ca07..b8b93e0 100644
--- a/src/proguard/classfile/attribute/LineNumberTableAttrInfo.java
+++ b/src/proguard/classfile/attribute/LineNumberTableAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: LineNumberTableAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: LineNumberTableAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/LocalVariableInfo.java b/src/proguard/classfile/attribute/LocalVariableInfo.java
index 531b435..273eb4e 100644
--- a/src/proguard/classfile/attribute/LocalVariableInfo.java
+++ b/src/proguard/classfile/attribute/LocalVariableInfo.java
@@ -1,9 +1,9 @@
-/* $Id: LocalVariableInfo.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: LocalVariableInfo.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/LocalVariableInfoVisitor.java b/src/proguard/classfile/attribute/LocalVariableInfoVisitor.java
index 2337f2c..8dcb5e3 100644
--- a/src/proguard/classfile/attribute/LocalVariableInfoVisitor.java
+++ b/src/proguard/classfile/attribute/LocalVariableInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: LocalVariableInfoVisitor.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: LocalVariableInfoVisitor.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/LocalVariableTableAttrInfo.java b/src/proguard/classfile/attribute/LocalVariableTableAttrInfo.java
index fdb630b..934c865 100644
--- a/src/proguard/classfile/attribute/LocalVariableTableAttrInfo.java
+++ b/src/proguard/classfile/attribute/LocalVariableTableAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: LocalVariableTableAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: LocalVariableTableAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/LocalVariableTypeInfo.java b/src/proguard/classfile/attribute/LocalVariableTypeInfo.java
index db9924e..b6440ad 100644
--- a/src/proguard/classfile/attribute/LocalVariableTypeInfo.java
+++ b/src/proguard/classfile/attribute/LocalVariableTypeInfo.java
@@ -1,9 +1,9 @@
-/* $Id: LocalVariableTypeInfo.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: LocalVariableTypeInfo.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/LocalVariableTypeInfoVisitor.java b/src/proguard/classfile/attribute/LocalVariableTypeInfoVisitor.java
index f6f4999..4a79d08 100644
--- a/src/proguard/classfile/attribute/LocalVariableTypeInfoVisitor.java
+++ b/src/proguard/classfile/attribute/LocalVariableTypeInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: LocalVariableTypeInfoVisitor.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: LocalVariableTypeInfoVisitor.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/LocalVariableTypeTableAttrInfo.java b/src/proguard/classfile/attribute/LocalVariableTypeTableAttrInfo.java
index e3846c3..4f8d00b 100644
--- a/src/proguard/classfile/attribute/LocalVariableTypeTableAttrInfo.java
+++ b/src/proguard/classfile/attribute/LocalVariableTypeTableAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: LocalVariableTypeTableAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: LocalVariableTypeTableAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/MultiAttrInfoVisitor.java b/src/proguard/classfile/attribute/MultiAttrInfoVisitor.java
index 4e76ee7..f6e2379 100644
--- a/src/proguard/classfile/attribute/MultiAttrInfoVisitor.java
+++ b/src/proguard/classfile/attribute/MultiAttrInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: MultiAttrInfoVisitor.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: MultiAttrInfoVisitor.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/SignatureAttrInfo.java b/src/proguard/classfile/attribute/SignatureAttrInfo.java
index 74d11c6..f81b149 100644
--- a/src/proguard/classfile/attribute/SignatureAttrInfo.java
+++ b/src/proguard/classfile/attribute/SignatureAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: SignatureAttrInfo.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: SignatureAttrInfo.java,v 1.3.2.2 2006/02/08 00:04:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -22,6 +22,7 @@
 package proguard.classfile.attribute;
 
 import proguard.classfile.*;
+import proguard.classfile.visitor.ClassFileVisitor;
 
 import java.io.*;
 
@@ -51,6 +52,25 @@ public class SignatureAttrInfo extends AttrInfo
     }
 
 
+    /**
+     * Lets the ClassFile objects referenced in the signature string
+     * accept the given visitor.
+     */
+    public void referencedClassesAccept(ClassFileVisitor classFileVisitor)
+    {
+        if (referencedClassFiles != null)
+        {
+            for (int i = 0; i < referencedClassFiles.length; i++)
+            {
+                if (referencedClassFiles[i] != null)
+                {
+                    referencedClassFiles[i].accept(classFileVisitor);
+                }
+            }
+        }
+    }
+
+
     // Implementations for AttrInfo.
 
     protected int getLength()
diff --git a/src/proguard/classfile/attribute/SourceDirAttrInfo.java b/src/proguard/classfile/attribute/SourceDirAttrInfo.java
index 8e55146..a1c18f6 100644
--- a/src/proguard/classfile/attribute/SourceDirAttrInfo.java
+++ b/src/proguard/classfile/attribute/SourceDirAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: SourceDirAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: SourceDirAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/SourceFileAttrInfo.java b/src/proguard/classfile/attribute/SourceFileAttrInfo.java
index c3ef70c..1693531 100644
--- a/src/proguard/classfile/attribute/SourceFileAttrInfo.java
+++ b/src/proguard/classfile/attribute/SourceFileAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: SourceFileAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: SourceFileAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/SyntheticAttrInfo.java b/src/proguard/classfile/attribute/SyntheticAttrInfo.java
index 7ba5a30..7d75a5a 100644
--- a/src/proguard/classfile/attribute/SyntheticAttrInfo.java
+++ b/src/proguard/classfile/attribute/SyntheticAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: SyntheticAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: SyntheticAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/UnknownAttrInfo.java b/src/proguard/classfile/attribute/UnknownAttrInfo.java
index 2ee01a9..aa72bd6 100644
--- a/src/proguard/classfile/attribute/UnknownAttrInfo.java
+++ b/src/proguard/classfile/attribute/UnknownAttrInfo.java
@@ -1,9 +1,9 @@
-/* $Id: UnknownAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: UnknownAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/annotation/Annotation.java b/src/proguard/classfile/attribute/annotation/Annotation.java
index 105c4a3..61b2e4a 100644
--- a/src/proguard/classfile/attribute/annotation/Annotation.java
+++ b/src/proguard/classfile/attribute/annotation/Annotation.java
@@ -1,8 +1,8 @@
-/* $Id: Annotation.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: Annotation.java,v 1.4.2.2 2006/10/14 12:33:22 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -21,6 +21,7 @@
 package proguard.classfile.attribute.annotation;
 
 import proguard.classfile.*;
+import proguard.classfile.visitor.ClassFileVisitor;
 
 import java.io.*;
 
@@ -109,6 +110,42 @@ public class Annotation implements VisitorAccepter
 
 
     /**
+     * Applies the given visitor to the first referenced class. This is the
+     * main annotation class.
+     */
+    public void referencedClassFileAccept(ClassFileVisitor classFileVisitor)
+    {
+        if (referencedClassFiles != null)
+        {
+            ClassFile referencedClassFile = referencedClassFiles[0];
+            if (referencedClassFile != null)
+            {
+                referencedClassFile.accept(classFileVisitor);
+            }
+        }
+    }
+
+
+    /**
+     * Applies the given visitor to all referenced classes.
+     */
+    public void referencedClassFilesAccept(ClassFileVisitor classFileVisitor)
+    {
+        if (referencedClassFiles != null)
+        {
+            for (int index = 0; index < referencedClassFiles.length; index++)
+            {
+                ClassFile referencedClassFile = referencedClassFiles[index];
+                if (referencedClassFile != null)
+                {
+                    referencedClassFile.accept(classFileVisitor);
+                }
+            }
+        }
+    }
+
+
+    /**
      * Applies the given visitor to all element value pairs.
      */
     public void elementValuesAccept(ClassFile classFile, ElementValueVisitor elementValueVisitor)
diff --git a/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttrInfo.java b/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttrInfo.java
index 9b6a4dd..40479e4 100644
--- a/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttrInfo.java
+++ b/src/proguard/classfile/attribute/annotation/AnnotationDefaultAttrInfo.java
@@ -1,8 +1,8 @@
-/* $Id: AnnotationDefaultAttrInfo.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: AnnotationDefaultAttrInfo.java,v 1.4.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java b/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java
index 9c9b2c9..9ccb6d4 100644
--- a/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/AnnotationElementValue.java
@@ -1,9 +1,9 @@
-/* $Id: AnnotationElementValue.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: AnnotationElementValue.java,v 1.4.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/annotation/AnnotationVisitor.java b/src/proguard/classfile/attribute/annotation/AnnotationVisitor.java
index bfb784f..21e4520 100644
--- a/src/proguard/classfile/attribute/annotation/AnnotationVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/AnnotationVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: AnnotationVisitor.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: AnnotationVisitor.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/ArrayElementValue.java b/src/proguard/classfile/attribute/annotation/ArrayElementValue.java
index e972551..da0af12 100644
--- a/src/proguard/classfile/attribute/annotation/ArrayElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ArrayElementValue.java
@@ -1,9 +1,9 @@
-/* $Id: ArrayElementValue.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: ArrayElementValue.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/annotation/ClassElementValue.java b/src/proguard/classfile/attribute/annotation/ClassElementValue.java
index 1551a72..436075a 100644
--- a/src/proguard/classfile/attribute/annotation/ClassElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ClassElementValue.java
@@ -1,9 +1,9 @@
-/* $Id: ClassElementValue.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassElementValue.java,v 1.3.2.2 2006/10/14 12:33:22 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -22,6 +22,7 @@
 package proguard.classfile.attribute.annotation;
 
 import proguard.classfile.*;
+import proguard.classfile.visitor.ClassFileVisitor;
 
 import java.io.*;
 
@@ -51,6 +52,25 @@ public class ClassElementValue extends ElementValue
     }
 
 
+    /**
+     * Applies the given visitor to all referenced classes.
+     */
+    public void referencedClassesAccept(ClassFileVisitor classFileVisitor)
+    {
+        if (referencedClassFiles != null)
+        {
+            for (int index = 0; index < referencedClassFiles.length; index++)
+            {
+                ClassFile referencedClassFile = referencedClassFiles[index];
+                if (referencedClassFile != null)
+                {
+                    referencedClassFile.accept(classFileVisitor);
+                }
+            }
+        }
+    }
+
+
     // Implementations for ElementValue.
 
     protected int getLength()
diff --git a/src/proguard/classfile/attribute/annotation/ConstantElementValue.java b/src/proguard/classfile/attribute/annotation/ConstantElementValue.java
index c5d9b3e..0c06c49 100644
--- a/src/proguard/classfile/attribute/annotation/ConstantElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ConstantElementValue.java
@@ -1,9 +1,9 @@
-/* $Id: ConstantElementValue.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: ConstantElementValue.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/annotation/ElementValue.java b/src/proguard/classfile/attribute/annotation/ElementValue.java
index 92cd996..86aa1e9 100644
--- a/src/proguard/classfile/attribute/annotation/ElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/ElementValue.java
@@ -1,8 +1,8 @@
-/* $Id: ElementValue.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: ElementValue.java,v 1.6.2.2 2006/10/14 12:33:22 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
@@ -21,6 +21,7 @@
 package proguard.classfile.attribute.annotation;
 
 import proguard.classfile.*;
+import proguard.classfile.visitor.MemberInfoVisitor;
 
 import java.io.*;
 
@@ -43,9 +44,16 @@ public abstract class ElementValue implements VisitorAccepter
     public int u2elementName;
 
     /**
+     * An extra field pointing to the referenced ClassFile object.
+     * This field is typically filled out by the <code>{@link
+     * proguard.classfile.util.ClassReferenceInitializer}</code>.
+     */
+    public ClassFile referencedClassFile;
+
+    /**
      * An extra field pointing to the referenced <code>MethodInfo</code>
      * object, if applicable. This field is typically filled out by the
-     * <code>{@link ClassFileReferenceInitializer}</code>.
+     * <code>{@link proguard.classfile.util.ClassFileReferenceInitializer}</code>.
      */
     public MethodInfo referencedMethodInfo;
 
@@ -141,6 +149,17 @@ public abstract class ElementValue implements VisitorAccepter
     public abstract void accept(ClassFile classFile, Annotation annotation, ElementValueVisitor elementValueVisitor);
 
 
+    /**
+     * Applies the given visitor to the referenced method.
+     */
+    public void referencedMethodInfoAccept(MemberInfoVisitor memberInfoVisitor)
+    {
+        if (referencedMethodInfo != null)
+        {
+            referencedMethodInfo.accept(referencedClassFile, memberInfoVisitor);
+        }
+    }
+
 
     // Implementations for VisitorAccepter.
 
diff --git a/src/proguard/classfile/attribute/annotation/ElementValueVisitor.java b/src/proguard/classfile/attribute/annotation/ElementValueVisitor.java
index e80abc0..94dc8f6 100644
--- a/src/proguard/classfile/attribute/annotation/ElementValueVisitor.java
+++ b/src/proguard/classfile/attribute/annotation/ElementValueVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: ElementValueVisitor.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: ElementValueVisitor.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java b/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java
index f3f61ad..dd085af 100644
--- a/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java
+++ b/src/proguard/classfile/attribute/annotation/EnumConstantElementValue.java
@@ -1,9 +1,9 @@
-/* $Id: EnumConstantElementValue.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: EnumConstantElementValue.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
  * Copyright (c) 1999      Mark Welsh (markw at retrologic.com)
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeAnnotationsAttrInfo.java b/src/proguard/classfile/attribute/annotation/RuntimeAnnotationsAttrInfo.java
index 955bf76..7122e21 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeAnnotationsAttrInfo.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeAnnotationsAttrInfo.java
@@ -1,8 +1,8 @@
-/* $Id: RuntimeAnnotationsAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: RuntimeAnnotationsAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttrInfo.java b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttrInfo.java
index e5deeed..4f07973 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttrInfo.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleAnnotationsAttrInfo.java
@@ -1,8 +1,8 @@
-/* $Id: RuntimeInvisibleAnnotationsAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: RuntimeInvisibleAnnotationsAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttrInfo.java b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttrInfo.java
index fd3e360..e8d7e7f 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttrInfo.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeInvisibleParameterAnnotationsAttrInfo.java
@@ -1,8 +1,8 @@
-/* $Id: RuntimeInvisibleParameterAnnotationsAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: RuntimeInvisibleParameterAnnotationsAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeParameterAnnotationsAttrInfo.java b/src/proguard/classfile/attribute/annotation/RuntimeParameterAnnotationsAttrInfo.java
index 2ccf809..7439a94 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeParameterAnnotationsAttrInfo.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeParameterAnnotationsAttrInfo.java
@@ -1,8 +1,8 @@
-/* $Id: RuntimeParameterAnnotationsAttrInfo.java,v 1.6 2005/06/25 22:04:04 eric Exp $
+/* $Id: RuntimeParameterAnnotationsAttrInfo.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttrInfo.java b/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttrInfo.java
index c315723..ffe3e39 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttrInfo.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeVisibleAnnotationsAttrInfo.java
@@ -1,8 +1,8 @@
-/* $Id: RuntimeVisibleAnnotationsAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: RuntimeVisibleAnnotationsAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttrInfo.java b/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttrInfo.java
index 2644f30..95223ab 100644
--- a/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttrInfo.java
+++ b/src/proguard/classfile/attribute/annotation/RuntimeVisibleParameterAnnotationsAttrInfo.java
@@ -1,8 +1,8 @@
-/* $Id: RuntimeVisibleParameterAnnotationsAttrInfo.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: RuntimeVisibleParameterAnnotationsAttrInfo.java,v 1.2.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by
diff --git a/src/proguard/classfile/editor/ClassFileReferenceFixer.java b/src/proguard/classfile/editor/ClassFileReferenceFixer.java
index 73df5e5..0217e02 100644
--- a/src/proguard/classfile/editor/ClassFileReferenceFixer.java
+++ b/src/proguard/classfile/editor/ClassFileReferenceFixer.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileReferenceFixer.java,v 1.4 2005/06/25 22:07:51 eric Exp $
+/* $Id: ClassFileReferenceFixer.java,v 1.4.2.2 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -43,9 +43,25 @@ public class ClassFileReferenceFixer
              AnnotationVisitor,
              ElementValueVisitor
 {
+    private boolean ensureUniqueMemberNames;
+
+
     private ConstantPoolEditor constantPoolEditor = new ConstantPoolEditor();
 
 
+    /**
+     * Creates a new ClassFileReferenceFixer.
+     * @param ensureUniqueMemberNames specifies whether class members whose
+     *                                descriptor changes should get new, unique
+     *                                names, in order to avoid naming conflicts
+     *                                with similar methods.
+     */
+    public ClassFileReferenceFixer(boolean ensureUniqueMemberNames)
+    {
+        this.ensureUniqueMemberNames = ensureUniqueMemberNames;
+    }
+
+
     // Implementations for ClassFileVisitor.
 
     public void visitProgramClassFile(ProgramClassFile programClassFile)
@@ -84,6 +100,15 @@ public class ClassFileReferenceFixer
             // Update the descriptor.
             programFieldInfo.u2descriptorIndex =
                 constantPoolEditor.addUtf8CpInfo(programClassFile, newDescriptor);
+
+            // Update the name, if requested.
+            if (ensureUniqueMemberNames)
+            {
+                String name    = programFieldInfo.getName(programClassFile);
+                String newName = newUniqueMemberName(name, descriptor);
+                programFieldInfo.u2nameIndex =
+                    constantPoolEditor.addUtf8CpInfo(programClassFile, newName);
+            }
         }
 
         // Fix the attributes.
@@ -103,6 +128,15 @@ public class ClassFileReferenceFixer
             // Update the descriptor.
             programMethodInfo.u2descriptorIndex =
                 constantPoolEditor.addUtf8CpInfo(programClassFile, newDescriptor);
+
+            // Update the name, if requested.
+            if (ensureUniqueMemberNames)
+            {
+                String name    = programMethodInfo.getName(programClassFile);
+                String newName = newUniqueMemberName(name, descriptor);
+                programMethodInfo.u2nameIndex =
+                    constantPoolEditor.addUtf8CpInfo(programClassFile, newName);
+            }
         }
 
         // Fix the attributes.
@@ -464,6 +498,19 @@ public class ClassFileReferenceFixer
 
 
     /**
+     * Returns a new unique class member name, based on the given name and
+     * descriptor.
+     */
+    private String newUniqueMemberName(String name, String descriptor)
+    {
+        // TODO: Avoid duplicate constructors.
+        return name.equals(ClassConstants.INTERNAL_METHOD_NAME_INIT) ?
+            ClassConstants.INTERNAL_METHOD_NAME_INIT :
+            name + '$' + Long.toHexString(Math.abs((descriptor).hashCode()));
+    }
+
+
+    /**
      * Returns the new class name based on the given class name and the new
      * name of the given referenced class file. Class names of array types
      * are handled properly.
diff --git a/src/proguard/classfile/editor/CodeAttrInfoEditor.java b/src/proguard/classfile/editor/CodeAttrInfoEditor.java
index b06f481..800329c 100644
--- a/src/proguard/classfile/editor/CodeAttrInfoEditor.java
+++ b/src/proguard/classfile/editor/CodeAttrInfoEditor.java
@@ -1,8 +1,8 @@
-/* $Id: CodeAttrInfoEditor.java,v 1.14 2005/10/22 11:55:29 eric Exp $
+/* $Id: CodeAttrInfoEditor.java,v 1.14.2.3 2006/11/20 22:11:40 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -49,9 +49,12 @@ public class CodeAttrInfoEditor
     /*private*/public Instruction[]    postInsertions;
     private boolean[]        deleted;
 
-    private int[]            instructionOffsetMap;
+    private int[]   instructionOffsetMap;
+    private int     newOffset;
+    private boolean lengthIncreased;
 
-    private StackSizeUpdater stackSizeUpdater;
+    private StackSizeUpdater  stackSizeUpdater;
+    private InstructionWriter instructionWriter = new InstructionWriter();
 
 
     /**
@@ -186,6 +189,22 @@ public class CodeAttrInfoEditor
 
 
     /**
+     * Remembers not to delete the instruction at the given offset.
+     * @param instructionOffset the offset of the instruction not to be deleted.
+     */
+    public void undeleteInstruction(int instructionOffset)
+    {
+        if (instructionOffset < 0 ||
+            instructionOffset >= codeLength)
+        {
+            throw new IllegalArgumentException("Invalid instruction offset ["+instructionOffset+"] in code with length ["+codeLength+"]");
+        }
+
+        deleted[instructionOffset] = false;
+    }
+
+
+    /**
      * Returns whether the instruction at the given offset has been modified
      * in any way.
      */
@@ -239,12 +258,15 @@ public class CodeAttrInfoEditor
         {
             // Simply overwrite the instructions.
             performSimpleReplacements(codeAttrInfo);
+
+            // Update the maximum stack size.
+            stackSizeUpdater.visitCodeAttrInfo(classFile, methodInfo, codeAttrInfo);
         }
         else
         {
             // Move and remap the instructions.
             codeAttrInfo.u4codeLength =
-                moveInstructions(classFile, methodInfo, codeAttrInfo);
+                updateInstructions(classFile, methodInfo, codeAttrInfo);
 
             // Remap the exception table.
             codeAttrInfo.exceptionsAccept(classFile, methodInfo, this);
@@ -256,14 +278,15 @@ public class CodeAttrInfoEditor
             codeAttrInfo.u2exceptionTableLength =
                  removeEmptyExceptions(codeAttrInfo.exceptionTable,
                                        codeAttrInfo.u2exceptionTableLength);
-        }
 
-        // Update the maximum stack size.
-        stackSizeUpdater.visitCodeAttrInfo(classFile, methodInfo, codeAttrInfo);
-    }
+            // Update the maximum stack size.
+            stackSizeUpdater.visitCodeAttrInfo(classFile, methodInfo, codeAttrInfo);
 
+            // Make sure instructions are widened if necessary.
+            instructionWriter.visitCodeAttrInfo(classFile, methodInfo, codeAttrInfo);
+        }
+    }
 
-    // Implementations for LineNumberInfoVisitor.
 
     public void visitLineNumberTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LineNumberTableAttrInfo lineNumberTableAttrInfo)
     {
@@ -278,8 +301,6 @@ public class CodeAttrInfoEditor
     }
 
 
-    // Implementations for LocalVariableInfoVisitor.
-
     public void visitLocalVariableTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTableAttrInfo localVariableTableAttrInfo)
     {
         // Remap all local variable table entries.
@@ -292,8 +313,6 @@ public class CodeAttrInfoEditor
     }
 
 
-    // Implementations for LocalVariableInfoVisitor.
-
     public void visitLocalVariableTypeTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTypeTableAttrInfo localVariableTypeTableAttrInfo)
     {
         // Remap all local variable table entries.
@@ -306,97 +325,9 @@ public class CodeAttrInfoEditor
     }
 
 
-    // Implementations for InstructionVisitor.
-
-    public void visitSimpleInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, SimpleInstruction simpleInstruction) {}
-    public void visitCpInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, CpInstruction cpInstruction) {}
-    public void visitVariableInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, VariableInstruction variableInstruction) {}
-
-
-    public void visitBranchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, BranchInstruction branchInstruction)
-    {
-        // Adjust the branch offset.
-        branchInstruction.branchOffset = remapBranchOffset(offset,
-                                                           branchInstruction.branchOffset);
-    }
-
-
-    public void visitTableSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, TableSwitchInstruction tableSwitchInstruction)
-    {
-        // Adjust the default jump offset.
-        tableSwitchInstruction.defaultOffset = remapBranchOffset(offset,
-                                                                 tableSwitchInstruction.defaultOffset);
-
-        // Adjust the jump offsets.
-        remapJumpOffsets(offset,
-                         tableSwitchInstruction.jumpOffsets,
-                         tableSwitchInstruction.highCase -
-                         tableSwitchInstruction.lowCase + 1);
-    }
-
-
-    public void visitLookUpSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
-    {
-        // Adjust the default jump offset.
-        lookUpSwitchInstruction.defaultOffset = remapBranchOffset(offset,
-                                                                  lookUpSwitchInstruction.defaultOffset);
-
-        // Adjust the jump offsets.
-        remapJumpOffsets(offset,
-                         lookUpSwitchInstruction.jumpOffsets,
-                         lookUpSwitchInstruction.jumpOffsetCount);
-    }
-
-
-    // Implementations for ExceptionInfoVisitor.
-
-    public void visitExceptionInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, ExceptionInfo exceptionInfo)
-    {
-        // Remap the code offsets. Note that the instruction offset map also has
-        // an entry for the first offset after the code, for u2endpc.
-        exceptionInfo.u2startpc   = remapInstructionOffset(exceptionInfo.u2startpc);
-        exceptionInfo.u2endpc     = remapInstructionOffset(exceptionInfo.u2endpc);
-        exceptionInfo.u2handlerpc = remapInstructionOffset(exceptionInfo.u2handlerpc);
-    }
-
-
-    // Implementations for LineNumberInfoVisitor.
-
-    public void visitLineNumberInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LineNumberInfo lineNumberInfo)
-    {
-        // Remap the code offset.
-        lineNumberInfo.u2startpc = remapInstructionOffset(lineNumberInfo.u2startpc);
-    }
-
-
-    // Implementations for LocalVariableInfoVisitor.
-
-    public void visitLocalVariableInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableInfo localVariableInfo)
-    {
-        // Remap the code offset and length.
-        localVariableInfo.u2length  = remapBranchOffset(localVariableInfo.u2startpc,
-                                                        localVariableInfo.u2length);
-        localVariableInfo.u2startpc = remapInstructionOffset(localVariableInfo.u2startpc);
-    }
-
-
-    // Implementations for LocalVariableTypeInfoVisitor.
-
-    public void visitLocalVariableTypeInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTypeInfo localVariableTypeInfo)
-    {
-        // Remap the code offset and length.
-        localVariableTypeInfo.u2length  = remapBranchOffset(localVariableTypeInfo.u2startpc,
-                                                            localVariableTypeInfo.u2length);
-        localVariableTypeInfo.u2startpc = remapInstructionOffset(localVariableTypeInfo.u2startpc);
-    }
-
-
-    // Small utility methods.
-
     /**
      * Checks if it is possible to modifies the given code without having to
      * update any offsets.
-     *
      * @param codeAttrInfo the code to be changed.
      * @return the new code length.
      */
@@ -430,13 +361,11 @@ public class CodeAttrInfoEditor
 
     /**
      * Modifies the given code without updating any offsets.
-     *
      * @param codeAttrInfo the code to be changed.
      */
     private void performSimpleReplacements(CodeAttrInfo codeAttrInfo)
     {
-        byte[] code       = codeAttrInfo.code;
-        int    codeLength = codeAttrInfo.u4codeLength;
+        int codeLength = codeAttrInfo.u4codeLength;
 
         // Go over all replacement instructions.
         for (int offset = 0; offset < codeLength; offset++)
@@ -454,15 +383,14 @@ public class CodeAttrInfoEditor
 
     /**
      * Modifies the given code based on the previously specified changes.
-     *
      * @param classFile    the class file of the code to be changed.
      * @param methodInfo   the method of the code to be changed.
      * @param codeAttrInfo the code to be changed.
      * @return the new code length.
      */
-    private int moveInstructions(ClassFile    classFile,
-                                 MethodInfo   methodInfo,
-                                 CodeAttrInfo codeAttrInfo)
+    private int updateInstructions(ClassFile    classFile,
+                                   MethodInfo   methodInfo,
+                                   CodeAttrInfo codeAttrInfo)
     {
         byte[] oldCode   = codeAttrInfo.code;
         int    oldLength = codeAttrInfo.u4codeLength;
@@ -474,26 +402,56 @@ public class CodeAttrInfoEditor
             instructionOffsetMap = new int[oldLength + 1];
         }
 
-        // Fill out the offset map that specifies the new instruction offsets,
-        // given their current instruction offsets, by going over the
-        // instructions, deleting and inserting instructions as specified.
-        int     oldOffset       = 0;
-        int     newOffset       = 0;
-        boolean lengthIncreased = false;
+        // Fill out the instruction offset map.
+        int newLength = mapInstructions(oldCode,
+                                        oldLength);
+
+        // Create a new code array if necessary.
+        if (lengthIncreased)
+        {
+            codeAttrInfo.code = new byte[newLength];
+        }
+
+        // Prepare for possible widening of instructions.
+        instructionWriter.reset(newLength);
+
+        // Move the instructions into the new code array.
+        moveInstructions(classFile,
+                         methodInfo,
+                         codeAttrInfo,
+                         oldCode,
+                         oldLength);
+
+        // We can return the new length.
+        return newLength;
+    }
+
+
+    /**
+     * Fills out the instruction offset map for the given code block.
+     * @param oldCode   the instructions to be moved.
+     * @param oldLength the code length.
+     * @return the new code length.
+     */
+    private int mapInstructions(byte[] oldCode, int oldLength)
+    {
+        // Start mapping instructions at the beginning.
+        newOffset       = 0;
+        lengthIncreased = false;
+
+        int oldOffset = 0;
         do
         {
             // Get the next instruction.
             Instruction instruction = InstructionFactory.create(oldCode, oldOffset);
 
             // Compute the mapping of the instruction.
-            newOffset = mapInstruction(instruction, oldOffset, newOffset);
+            mapInstruction(oldOffset, instruction);
 
             oldOffset += instruction.length(oldOffset);
 
-            // Is the new instruction exceeding the available space?
             if (newOffset > oldOffset)
             {
-                // Remember to create a new code array later on.
                 lengthIncreased = true;
             }
         }
@@ -502,41 +460,17 @@ public class CodeAttrInfoEditor
         // Also add an entry for the first offset after the code.
         instructionOffsetMap[oldOffset] = newOffset;
 
-        // Create a new code array if necessary.
-        if (lengthIncreased)
-        {
-            codeAttrInfo.code = new byte[newOffset];
-        }
-
-        // Now actually move the instructions based on this map.
-        oldOffset = 0;
-        do
-        {
-            // Get the next instruction.
-            Instruction instruction = InstructionFactory.create(oldCode, oldOffset);
-
-            // Move the instruction to its new offset.
-            moveInstruction(classFile, methodInfo, codeAttrInfo, oldOffset, instruction);
-
-            oldOffset += instruction.length(oldOffset);
-        }
-        while (oldOffset < oldLength);
-
         return newOffset;
     }
 
 
     /**
-     * Fills out the instruction offset map for the given instruction with its
-     * new offset.
-     * @param instruction the instruction to be moved.
+     * Fills out the instruction offset map for the given instruction.
      * @param oldOffset   the instruction's old offset.
-     * @param newOffset   the instruction's new offset.
-     * @return            the next new offset.
+     * @param instruction the instruction to be moved.
      */
-    private int mapInstruction(Instruction instruction,
-                               int         oldOffset,
-                               int         newOffset)
+    private void mapInstruction(int         oldOffset,
+                                Instruction instruction)
     {
         instructionOffsetMap[oldOffset] = newOffset;
 
@@ -567,13 +501,52 @@ public class CodeAttrInfoEditor
         {
             newOffset += postInstruction.length(newOffset);
         }
+    }
 
-        return newOffset;
+
+    /**
+     * Moves the given code block to the new offsets.
+     * @param classFile    the class file of the code to be changed.
+     * @param methodInfo   the method of the code to be changed.
+     * @param codeAttrInfo the code to be changed.
+     * @param oldCode      the original code to be moved.
+     * @param oldLength    the original code length.
+     */
+    private void moveInstructions(ClassFile    classFile,
+                                  MethodInfo   methodInfo,
+                                  CodeAttrInfo codeAttrInfo,
+                                  byte[]       oldCode,
+                                  int          oldLength)
+    {
+        // Start writing instructions at the beginning.
+        newOffset = 0;
+
+        int oldOffset = 0;
+        do
+        {
+            // Get the next instruction.
+            Instruction instruction = InstructionFactory.create(oldCode, oldOffset);
+
+            // Move the instruction to its new offset.
+            moveInstruction(classFile,
+                            methodInfo,
+                            codeAttrInfo,
+                            oldOffset,
+                            instruction);
+
+            oldOffset += instruction.length(oldOffset);
+        }
+        while (oldOffset < oldLength);
     }
 
 
     /**
      * Moves the given instruction to its new offset.
+     * @param classFile    the class file of the code to be changed.
+     * @param methodInfo   the method of the code to be changed.
+     * @param codeAttrInfo the code to be changed.
+     * @param oldOffset    the original instruction offset.
+     * @param instruction  the original instruction.
      */
     private void moveInstruction(ClassFile    classFile,
                                  MethodInfo   methodInfo,
@@ -581,36 +554,31 @@ public class CodeAttrInfoEditor
                                  int          oldOffset,
                                  Instruction  instruction)
     {
-        int newOffset = remapInstructionOffset(oldOffset);
-
         // Remap and insert the pre-inserted instruction, if any.
         Instruction preInstruction = preInsertions[oldOffset];
         if (preInstruction != null)
         {
+            // Remap the instruction.
             preInstruction.accept(classFile, methodInfo, codeAttrInfo, oldOffset, this);
 
-            preInstruction.write(codeAttrInfo, newOffset);
-
             newOffset += preInstruction.length(newOffset);
         }
 
-        // Remap and insert the replacment instruction, or the current
+        // Remap and insert the replacement instruction, or the current
         // instruction, if it shouldn't be deleted.
         Instruction replacementInstruction = replacements[oldOffset];
         if (replacementInstruction != null)
         {
+            // Remap the instruction.
             replacementInstruction.accept(classFile, methodInfo, codeAttrInfo, oldOffset, this);
 
-            replacementInstruction.write(codeAttrInfo, newOffset);
-
             newOffset += replacementInstruction.length(newOffset);
         }
         else if (!deleted[oldOffset])
         {
+            // Remap the instruction.
             instruction.accept(classFile, methodInfo, codeAttrInfo, oldOffset, this);
 
-            instruction.write(codeAttrInfo, newOffset);
-
             newOffset += instruction.length(newOffset);
         }
 
@@ -618,13 +586,150 @@ public class CodeAttrInfoEditor
         Instruction postInstruction = postInsertions[oldOffset];
         if (postInstruction != null)
         {
+            // Remap the instruction.
             postInstruction.accept(classFile, methodInfo, codeAttrInfo, oldOffset, this);
 
-            postInstruction.write(codeAttrInfo, newOffset);
+            newOffset += postInstruction.length(newOffset);
         }
     }
 
 
+    // Implementations for InstructionVisitor.
+
+    public void visitSimpleInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, SimpleInstruction simpleInstruction)
+    {
+        // Write out the instruction.
+        instructionWriter.visitSimpleInstruction(classFile,
+                                                 methodInfo,
+                                                 codeAttrInfo,
+                                                 newOffset,
+                                                 simpleInstruction);
+    }
+
+
+    public void visitCpInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, CpInstruction cpInstruction)
+    {
+        // Write out the instruction.
+        instructionWriter.visitCpInstruction(classFile,
+                                             methodInfo,
+                                             codeAttrInfo,
+                                             newOffset,
+                                             cpInstruction);
+    }
+
+
+    public void visitVariableInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, VariableInstruction variableInstruction)
+    {
+        // Write out the instruction.
+        instructionWriter.visitVariableInstruction(classFile,
+                                                   methodInfo,
+                                                   codeAttrInfo,
+                                                   newOffset,
+                                                   variableInstruction);
+    }
+
+
+    public void visitBranchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, BranchInstruction branchInstruction)
+    {
+        // Adjust the branch offset.
+        branchInstruction.branchOffset = remapBranchOffset(offset,
+                                                           branchInstruction.branchOffset);
+
+        // Write out the instruction.
+        instructionWriter.visitBranchInstruction(classFile,
+                                                 methodInfo,
+                                                 codeAttrInfo,
+                                                 newOffset,
+                                                 branchInstruction);
+    }
+
+
+    public void visitTableSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, TableSwitchInstruction tableSwitchInstruction)
+    {
+        // Adjust the default jump offset.
+        tableSwitchInstruction.defaultOffset = remapBranchOffset(offset,
+                                                                 tableSwitchInstruction.defaultOffset);
+
+        // Adjust the jump offsets.
+        remapJumpOffsets(offset,
+                         tableSwitchInstruction.jumpOffsets,
+                         tableSwitchInstruction.highCase -
+                         tableSwitchInstruction.lowCase + 1);
+
+        // Write out the instruction.
+        instructionWriter.visitTableSwitchInstruction(classFile,
+                                                      methodInfo,
+                                                      codeAttrInfo,
+                                                      newOffset,
+                                                      tableSwitchInstruction);
+    }
+
+
+    public void visitLookUpSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
+    {
+        // Adjust the default jump offset.
+        lookUpSwitchInstruction.defaultOffset = remapBranchOffset(offset,
+                                                                  lookUpSwitchInstruction.defaultOffset);
+
+        // Adjust the jump offsets.
+        remapJumpOffsets(offset,
+                         lookUpSwitchInstruction.jumpOffsets,
+                         lookUpSwitchInstruction.jumpOffsetCount);
+
+        // Write out the instruction.
+        instructionWriter.visitLookUpSwitchInstruction(classFile,
+                                                       methodInfo,
+                                                       codeAttrInfo,
+                                                       newOffset,
+                                                       lookUpSwitchInstruction);
+    }
+
+
+    // Implementations for ExceptionInfoVisitor.
+
+    public void visitExceptionInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, ExceptionInfo exceptionInfo)
+    {
+        // Remap the code offsets. Note that the instruction offset map also has
+        // an entry for the first offset after the code, for u2endpc.
+        exceptionInfo.u2startpc   = remapInstructionOffset(exceptionInfo.u2startpc);
+        exceptionInfo.u2endpc     = remapInstructionOffset(exceptionInfo.u2endpc);
+        exceptionInfo.u2handlerpc = remapInstructionOffset(exceptionInfo.u2handlerpc);
+    }
+
+
+    // Implementations for LineNumberInfoVisitor.
+
+    public void visitLineNumberInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LineNumberInfo lineNumberInfo)
+    {
+        // Remap the code offset.
+        lineNumberInfo.u2startpc = remapInstructionOffset(lineNumberInfo.u2startpc);
+    }
+
+
+    // Implementations for LocalVariableInfoVisitor.
+
+    public void visitLocalVariableInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableInfo localVariableInfo)
+    {
+        // Remap the code offset and length.
+        localVariableInfo.u2length  = remapBranchOffset(localVariableInfo.u2startpc,
+                                                        localVariableInfo.u2length);
+        localVariableInfo.u2startpc = remapInstructionOffset(localVariableInfo.u2startpc);
+    }
+
+
+    // Implementations for LocalVariableTypeInfoVisitor.
+
+    public void visitLocalVariableTypeInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTypeInfo localVariableTypeInfo)
+    {
+        // Remap the code offset and length.
+        localVariableTypeInfo.u2length  = remapBranchOffset(localVariableTypeInfo.u2startpc,
+                                                            localVariableTypeInfo.u2length);
+        localVariableTypeInfo.u2startpc = remapInstructionOffset(localVariableTypeInfo.u2startpc);
+    }
+
+
+    // Small utility methods.
+
     /**
      * Adjusts the given jump offsets for the instruction at the given offset.
      */
diff --git a/src/proguard/classfile/editor/CodeAttrInfoEditorResetter.java b/src/proguard/classfile/editor/CodeAttrInfoEditorResetter.java
index 147b54a..cbced5b 100644
--- a/src/proguard/classfile/editor/CodeAttrInfoEditorResetter.java
+++ b/src/proguard/classfile/editor/CodeAttrInfoEditorResetter.java
@@ -1,8 +1,8 @@
-/* $Id: CodeAttrInfoEditorResetter.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: CodeAttrInfoEditorResetter.java,v 1.4.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ComparableCpInfo.java b/src/proguard/classfile/editor/ComparableCpInfo.java
index 8f6ac86..967b78d 100644
--- a/src/proguard/classfile/editor/ComparableCpInfo.java
+++ b/src/proguard/classfile/editor/ComparableCpInfo.java
@@ -1,8 +1,8 @@
-/* $Id: ComparableCpInfo.java,v 1.5 2005/06/11 13:13:15 eric Exp $
+/* $Id: ComparableCpInfo.java,v 1.5.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ConstantPoolEditor.java b/src/proguard/classfile/editor/ConstantPoolEditor.java
index a0d5725..b1716c9 100644
--- a/src/proguard/classfile/editor/ConstantPoolEditor.java
+++ b/src/proguard/classfile/editor/ConstantPoolEditor.java
@@ -1,8 +1,8 @@
-/* $Id: ConstantPoolEditor.java,v 1.10 2005/06/11 13:21:35 eric Exp $
+/* $Id: ConstantPoolEditor.java,v 1.10.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ConstantPoolRemapper.java b/src/proguard/classfile/editor/ConstantPoolRemapper.java
index 170f2e1..789b597 100644
--- a/src/proguard/classfile/editor/ConstantPoolRemapper.java
+++ b/src/proguard/classfile/editor/ConstantPoolRemapper.java
@@ -1,8 +1,8 @@
-/* $Id: ConstantPoolRemapper.java,v 1.11 2005/06/11 13:13:15 eric Exp $
+/* $Id: ConstantPoolRemapper.java,v 1.11.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/ConstantPoolSorter.java b/src/proguard/classfile/editor/ConstantPoolSorter.java
index 107e9ef..0ae72f6 100644
--- a/src/proguard/classfile/editor/ConstantPoolSorter.java
+++ b/src/proguard/classfile/editor/ConstantPoolSorter.java
@@ -1,8 +1,8 @@
-/* $Id: ConstantPoolSorter.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: ConstantPoolSorter.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/InstructionWriter.java b/src/proguard/classfile/editor/InstructionWriter.java
new file mode 100644
index 0000000..e8ff71b
--- /dev/null
+++ b/src/proguard/classfile/editor/InstructionWriter.java
@@ -0,0 +1,299 @@
+/* $Id: InstructionWriter.java,v 1.1.2.2 2006/11/26 15:25:17 eric Exp $
+ *
+ * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
+ *
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.editor;
+
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.instruction.*;
+import proguard.classfile.*;
+
+/**
+ * This InstructionVisitor writes out the instructions that it visits,
+ * collecting instructions that have to be widened. As an AttrInfoVisitor,
+ * it then applies the collected changes. The process will be repeated
+ * recursively, if necessary.
+ *
+ * @author Eric Lafortune
+ */
+public class InstructionWriter
+  implements InstructionVisitor,
+             AttrInfoVisitor
+{
+    private int codeLength;
+
+    private CodeAttrInfoEditor codeAttrInfoEditor;
+
+
+    /**
+     * Resets the accumulated code changes.
+     * @param codeLength the length of the code that will be edited next.
+     */
+    public void reset(int codeLength)
+    {
+        this.codeLength = codeLength;
+
+        // The code attribute editor has to be created lazily.
+        if (codeAttrInfoEditor != null)
+        {
+            codeAttrInfoEditor.reset(codeLength);
+        }
+    }
+
+
+    // Implementations for InstructionVisitor.
+
+    public void visitSimpleInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, SimpleInstruction simpleInstruction)
+    {
+        // Try to write out the instruction.
+        // Simple instructions should always fit.
+        simpleInstruction.write(codeAttrInfo, offset);
+    }
+
+
+    public void visitCpInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, CpInstruction cpInstruction)
+    {
+        try
+        {
+            // Try to write out the instruction.
+            cpInstruction.write(codeAttrInfo, offset);
+        }
+        catch (IllegalArgumentException exception)
+        {
+            // Create a new constant instruction that will fit.
+            Instruction replacementInstruction =
+                new CpInstruction().copy(cpInstruction).shrink();
+
+            replaceInstruction(offset, replacementInstruction);
+
+            // Write out a dummy constant instruction for now.
+            cpInstruction.cpIndex  = 0;
+            cpInstruction.constant = 0;
+            cpInstruction.write(codeAttrInfo, offset);
+        }
+    }
+
+
+    public void visitVariableInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, VariableInstruction variableInstruction)
+    {
+        try
+        {
+            // Try to write out the instruction.
+            variableInstruction.write(codeAttrInfo, offset);
+        }
+        catch (IllegalArgumentException exception)
+        {
+            // Create a new variable instruction that will fit.
+            Instruction replacementInstruction =
+                new VariableInstruction(variableInstruction.opcode,
+                                        variableInstruction.variableIndex,
+                                        variableInstruction.constant);
+
+            replaceInstruction(offset, replacementInstruction);
+
+            // Write out a dummy variable instruction for now.
+            variableInstruction.variableIndex = 0;
+            variableInstruction.constant      = 0;
+            variableInstruction.write(codeAttrInfo, offset);
+        }
+    }
+
+
+    public void visitBranchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, BranchInstruction branchInstruction)
+    {
+        try
+        {
+            // Try to write out the instruction.
+            branchInstruction.write(codeAttrInfo, offset);
+        }
+        catch (IllegalArgumentException exception)
+        {
+            // Create a new unconditional branch that will fit.
+            Instruction replacementInstruction =
+                new BranchInstruction(InstructionConstants.OP_GOTO_W,
+                                      branchInstruction.branchOffset);
+
+            // Create a new instruction that will fit.
+            switch (branchInstruction.opcode)
+            {
+                default:
+                {
+                    // Create a new branch instruction that will fit.
+                    replacementInstruction =
+                        new BranchInstruction().copy(branchInstruction).shrink();
+
+                    break;
+                }
+
+                // Some special cases, for which a wide branch doesn't exist.
+                case InstructionConstants.OP_IFEQ:
+                case InstructionConstants.OP_IFNE:
+                case InstructionConstants.OP_IFLT:
+                case InstructionConstants.OP_IFGE:
+                case InstructionConstants.OP_IFGT:
+                case InstructionConstants.OP_IFLE:
+                case InstructionConstants.OP_IFICMPEQ:
+                case InstructionConstants.OP_IFICMPNE:
+                case InstructionConstants.OP_IFICMPLT:
+                case InstructionConstants.OP_IFICMPGE:
+                case InstructionConstants.OP_IFICMPGT:
+                case InstructionConstants.OP_IFICMPLE:
+                case InstructionConstants.OP_IFACMPEQ:
+                case InstructionConstants.OP_IFACMPNE:
+                {
+                    // Insert the complementary conditional branch.
+                    Instruction complementaryConditionalBranch =
+                        new BranchInstruction((byte)(((branchInstruction.opcode+1) ^ 1) - 1),
+                                              (1+2) + (1+4));
+
+                    insertBeforeInstruction(offset, complementaryConditionalBranch);
+
+                    // Create a new unconditional branch that will fit.
+                    break;
+                }
+
+                case InstructionConstants.OP_IFNULL:
+                case InstructionConstants.OP_IFNONNULL:
+                {
+                    // Insert the complementary conditional branch.
+                    Instruction complementaryConditionalBranch =
+                        new BranchInstruction((byte)(branchInstruction.opcode ^ 1),
+                                              (1+2) + (1+4));
+
+                    insertBeforeInstruction(offset, complementaryConditionalBranch);
+
+                    // Create a new unconditional branch that will fit.
+                    break;
+                }
+            }
+
+            replaceInstruction(offset, replacementInstruction);
+
+            // Write out a dummy branch instruction for now.
+            branchInstruction.branchOffset = 0;
+            branchInstruction.write(codeAttrInfo, offset);
+        }
+    }
+
+
+    public void visitTableSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, TableSwitchInstruction tableSwitchInstruction)
+    {
+        // Try to write out the instruction.
+        // Table switch instructions should always fit.
+        tableSwitchInstruction.write(codeAttrInfo, offset);
+    }
+
+
+    public void visitLookUpSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
+    {
+        // Try to write out the instruction.
+        // Table switch instructions should always fit.
+        lookUpSwitchInstruction.write(codeAttrInfo, offset);
+    }
+
+
+    // Implementations for AttrInfoVisitor.
+
+    public void visitUnknownAttrInfo(ClassFile classFile, UnknownAttrInfo unknownAttrInfo) {}
+    public void visitInnerClassesAttrInfo(ClassFile classFile, InnerClassesAttrInfo innerClassesAttrInfo) {}
+    public void visitEnclosingMethodAttrInfo(ClassFile classFile, EnclosingMethodAttrInfo enclosingMethodAttrInfo) {}
+    public void visitConstantValueAttrInfo(ClassFile classFile, FieldInfo fieldInfo, ConstantValueAttrInfo constantValueAttrInfo) {}
+    public void visitExceptionsAttrInfo(ClassFile classFile, MethodInfo methodInfo, ExceptionsAttrInfo exceptionsAttrInfo) {}
+    public void visitLineNumberTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LineNumberTableAttrInfo lineNumberTableAttrInfo) {}
+    public void visitLocalVariableTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTableAttrInfo localVariableTableAttrInfo) {}
+    public void visitLocalVariableTypeTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTypeTableAttrInfo localVariableTypeTableAttrInfo) {}
+    public void visitSourceFileAttrInfo(ClassFile classFile, SourceFileAttrInfo sourceFileAttrInfo) {}
+    public void visitSourceDirAttrInfo(ClassFile classFile, SourceDirAttrInfo sourceDirAttrInfo) {}
+    public void visitDeprecatedAttrInfo(ClassFile classFile, DeprecatedAttrInfo deprecatedAttrInfo) {}
+    public void visitSyntheticAttrInfo(ClassFile classFile, SyntheticAttrInfo syntheticAttrInfo) {}
+    public void visitSignatureAttrInfo(ClassFile classFile, SignatureAttrInfo signatureAttrInfo) {}
+    public void visitRuntimeVisibleAnnotationAttrInfo(ClassFile classFile, RuntimeVisibleAnnotationsAttrInfo runtimeVisibleAnnotationsAttrInfo) {}
+    public void visitRuntimeInvisibleAnnotationAttrInfo(ClassFile classFile, RuntimeInvisibleAnnotationsAttrInfo runtimeInvisibleAnnotationsAttrInfo) {}
+    public void visitRuntimeVisibleParameterAnnotationAttrInfo(ClassFile classFile, RuntimeVisibleParameterAnnotationsAttrInfo runtimeVisibleParameterAnnotationsAttrInfo) {}
+    public void visitRuntimeInvisibleParameterAnnotationAttrInfo(ClassFile classFile, RuntimeInvisibleParameterAnnotationsAttrInfo runtimeInvisibleParameterAnnotationsAttrInfo) {}
+    public void visitAnnotationDefaultAttrInfo(ClassFile classFile, AnnotationDefaultAttrInfo annotationDefaultAttrInfo) {}
+
+
+    public void visitCodeAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo)
+    {
+        // Avoid doing any work if nothing is changing anyway.
+        if (codeAttrInfoEditor != null)
+        {
+            // Apply the collected expansions.
+            codeAttrInfoEditor.visitCodeAttrInfo(classFile, methodInfo, codeAttrInfo);
+
+            // Clear the modifications for the next run.
+            codeAttrInfoEditor = null;
+        }
+    }
+
+
+    // Small utility methods.
+
+    /**
+     * Remembers to place the given instruction right before the instruction
+     * at the given offset.
+     */
+    private void insertBeforeInstruction(int instructionOffset, Instruction instruction)
+    {
+        ensureCodeAttrInfoEditor();
+
+        // Replace the instruction.
+        codeAttrInfoEditor.insertBeforeInstruction(instructionOffset, instruction);
+    }
+
+
+    /**
+     * Remembers to replace the instruction at the given offset by the given
+     * instruction.
+     */
+    private void replaceInstruction(int instructionOffset, Instruction instruction)
+    {
+        ensureCodeAttrInfoEditor();
+
+        // Replace the instruction.
+        codeAttrInfoEditor.replaceInstruction(instructionOffset, instruction);
+    }
+
+
+    /**
+     * Remembers to place the given instruction right after the instruction
+     * at the given offset.
+     */
+    private void insertAfterInstruction(int instructionOffset, Instruction instruction)
+    {
+        ensureCodeAttrInfoEditor();
+
+        // Replace the instruction.
+        codeAttrInfoEditor.insertAfterInstruction(instructionOffset, instruction);
+    }
+
+
+    /**
+     * Makes sure there is a code attribute editor for the given code attribute.
+     */
+    private void ensureCodeAttrInfoEditor()
+    {
+        if (codeAttrInfoEditor == null)
+        {
+            codeAttrInfoEditor = new CodeAttrInfoEditor(codeLength);
+        }
+    }
+}
diff --git a/src/proguard/classfile/editor/MemberReferenceFixer.java b/src/proguard/classfile/editor/MemberReferenceFixer.java
index 052b83d..1c865f9 100644
--- a/src/proguard/classfile/editor/MemberReferenceFixer.java
+++ b/src/proguard/classfile/editor/MemberReferenceFixer.java
@@ -1,8 +1,8 @@
-/* $Id: MemberReferenceFixer.java,v 1.4 2005/06/25 22:07:51 eric Exp $
+/* $Id: MemberReferenceFixer.java,v 1.4.2.3 2006/10/14 12:33:22 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -23,6 +23,7 @@ package proguard.classfile.editor;
 import proguard.classfile.*;
 import proguard.classfile.attribute.*;
 import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.util.ClassUtil;
 import proguard.classfile.visitor.*;
 
 /**
@@ -256,11 +257,19 @@ implements   ClassFileVisitor,
 
     public void visitClassCpInfo(ClassFile classFile, ClassCpInfo classCpInfo)
     {
-        // Check if this class entry refers to an interface class.
-        ClassFile referencedClassFile = classCpInfo.referencedClassFile;
-        if (referencedClassFile != null)
+        // Check if this class entry is an array type.
+        if (ClassUtil.isInternalArrayType(classCpInfo.getName(classFile)))
         {
-            isInterfaceMethod = (referencedClassFile.getAccessFlags() & ClassConstants.INTERNAL_ACC_INTERFACE) != 0;
+            isInterfaceMethod = false;
+        }
+        else
+        {
+            // Check if this class entry refers to an interface class.
+            ClassFile referencedClassFile = classCpInfo.referencedClassFile;
+            if (referencedClassFile != null)
+            {
+                isInterfaceMethod = (referencedClassFile.getAccessFlags() & ClassConstants.INTERNAL_ACC_INTERFACE) != 0;
+            }
         }
     }
 
@@ -441,7 +450,7 @@ implements   ClassFileVisitor,
         {
             // Does it have a new name or type?
             String methodName    = elementValue.getMethodName(classFile);
-            String newMethodName = referencedMemberInfo.getName(annotation.referencedClassFiles[0]);
+            String newMethodName = referencedMemberInfo.getName(elementValue.referencedClassFile);
             if (!methodName.equals(newMethodName))
             {
                 // Update the element name index.
diff --git a/src/proguard/classfile/editor/MethodInvocationFixer.java b/src/proguard/classfile/editor/MethodInvocationFixer.java
index 6de23d6..0ef7cc4 100644
--- a/src/proguard/classfile/editor/MethodInvocationFixer.java
+++ b/src/proguard/classfile/editor/MethodInvocationFixer.java
@@ -1,8 +1,8 @@
-/* $Id: MethodInvocationFixer.java,v 1.4 2005/08/13 21:01:04 eric Exp $
+/* $Id: MethodInvocationFixer.java,v 1.4.2.2 2006/03/28 22:03:59 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -212,11 +212,19 @@ implements   InstructionVisitor,
 
     public void visitClassCpInfo(ClassFile classFile, ClassCpInfo classCpInfo)
     {
-        // Check if this class entry refers to an interface class.
-        ClassFile referencedClassFile = classCpInfo.referencedClassFile;
-        if (referencedClassFile != null)
+        // Check if this class entry is an array type.
+        if (ClassUtil.isInternalArrayType(classCpInfo.getName(classFile)))
         {
-            isInterfaceMethod = (referencedClassFile.getAccessFlags() & ClassConstants.INTERNAL_ACC_INTERFACE) != 0;
+            isInterfaceMethod = false;
+        }
+        else
+        {
+            // Check if this class entry refers to an interface class.
+            ClassFile referencedClassFile = classCpInfo.referencedClassFile;
+            if (referencedClassFile != null)
+            {
+                isInterfaceMethod = (referencedClassFile.getAccessFlags() & ClassConstants.INTERNAL_ACC_INTERFACE) != 0;
+            }
         }
     }
 
diff --git a/src/proguard/classfile/editor/StackSizeUpdater.java b/src/proguard/classfile/editor/StackSizeUpdater.java
index ec78170..adf01ca 100644
--- a/src/proguard/classfile/editor/StackSizeUpdater.java
+++ b/src/proguard/classfile/editor/StackSizeUpdater.java
@@ -1,8 +1,8 @@
-/* $Id: StackSizeUpdater.java,v 1.14 2005/06/25 22:02:22 eric Exp $
+/* $Id: StackSizeUpdater.java,v 1.14.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/editor/VariableEditor.java b/src/proguard/classfile/editor/VariableEditor.java
index 023009a..1ab8f4a 100644
--- a/src/proguard/classfile/editor/VariableEditor.java
+++ b/src/proguard/classfile/editor/VariableEditor.java
@@ -1,8 +1,8 @@
-/* $Id: VariableEditor.java,v 1.5 2005/09/11 22:15:22 eric Exp $
+/* $Id: VariableEditor.java,v 1.5.2.2 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -162,6 +162,10 @@ public class VariableEditor
             {
                 variableMap[oldVariableIndex] = newVariableIndex++;
             }
+            else
+            {
+                variableMap[oldVariableIndex] = -1;
+            }
         }
 
         // Set the map.
diff --git a/src/proguard/classfile/editor/VariableRemapper.java b/src/proguard/classfile/editor/VariableRemapper.java
index a804e31..ee6eb0c 100644
--- a/src/proguard/classfile/editor/VariableRemapper.java
+++ b/src/proguard/classfile/editor/VariableRemapper.java
@@ -1,8 +1,8 @@
-/* $Id: VariableRemapper.java,v 1.4 2005/06/11 13:21:35 eric Exp $
+/* $Id: VariableRemapper.java,v 1.4.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/BranchInstruction.java b/src/proguard/classfile/instruction/BranchInstruction.java
index 0a0726c..e04bd8b 100644
--- a/src/proguard/classfile/instruction/BranchInstruction.java
+++ b/src/proguard/classfile/instruction/BranchInstruction.java
@@ -1,8 +1,8 @@
-/* $Id: BranchInstruction.java,v 1.15 2005/06/11 13:13:15 eric Exp $
+/* $Id: BranchInstruction.java,v 1.15.2.2 2006/11/20 22:11:40 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -65,9 +65,10 @@ public class BranchInstruction extends Instruction
 
     public Instruction shrink()
     {
-        // Is this a wide branch that can be replaced by a normal branch?
-        if (branchOffset << 16 >> 16 == branchOffset)
+        // Do we need an ordinary branch or a wide branch?
+        if (requiredBranchOffsetSize() == 2)
         {
+            // Can we replace the wide branch by an ordinary branch?
             if      (opcode == InstructionConstants.OP_GOTO_W)
             {
                 opcode = InstructionConstants.OP_GOTO;
@@ -77,6 +78,22 @@ public class BranchInstruction extends Instruction
                 opcode = InstructionConstants.OP_JSR;
             }
         }
+        else
+        {
+            // Can we replace the ordinary branch by a wide branch?
+            if      (opcode == InstructionConstants.OP_GOTO)
+            {
+                opcode = InstructionConstants.OP_GOTO_W;
+            }
+            else if (opcode == InstructionConstants.OP_JSR)
+            {
+                opcode = InstructionConstants.OP_JSR_W;
+            }
+            else
+            {
+                throw new IllegalArgumentException("Branch instruction can't be widened ("+this.toString()+")");
+            }
+        }
 
         return this;
     }
@@ -89,6 +106,11 @@ public class BranchInstruction extends Instruction
 
     protected void writeInfo(byte[] code, int offset)
     {
+        if (requiredBranchOffsetSize() > branchOffsetSize())
+        {
+            throw new IllegalArgumentException("Instruction has invalid branch offset size ("+this.toString(offset)+")");
+        }
+
         writeValue(code, offset, branchOffset, branchOffsetSize());
     }
 
@@ -122,7 +144,7 @@ public class BranchInstruction extends Instruction
     // Small utility methods.
 
     /**
-     * Computes the appropriate branch offset size for this instruction.
+     * Returns the branch offset size for this instruction.
      */
     private int branchOffsetSize()
     {
@@ -130,4 +152,15 @@ public class BranchInstruction extends Instruction
                opcode == InstructionConstants.OP_JSR_W  ? 4 :
                                                           2;
     }
+
+
+    /**
+     * Computes the required branch offset size for this instruction's branch
+     * offset.
+     */
+    private int requiredBranchOffsetSize()
+    {
+        return branchOffset << 16 >> 16 == branchOffset ? 2 :
+                                                          4;
+    }
 }
diff --git a/src/proguard/classfile/instruction/CpInstruction.java b/src/proguard/classfile/instruction/CpInstruction.java
index 8cc1d3b..541b97f 100644
--- a/src/proguard/classfile/instruction/CpInstruction.java
+++ b/src/proguard/classfile/instruction/CpInstruction.java
@@ -1,8 +1,8 @@
-/* $Id: CpInstruction.java,v 1.20 2005/06/11 13:13:15 eric Exp $
+/* $Id: CpInstruction.java,v 1.20.2.2 2006/11/20 22:11:40 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -89,15 +89,22 @@ implements   CpInfoVisitor
 
     public Instruction shrink()
     {
-        if      (opcode == InstructionConstants.OP_LDC &&
-                 cpIndex > 0xff)
+        // Do we need a short index or a long index?
+        if (requiredCpIndexSize() == 1)
         {
-            opcode = InstructionConstants.OP_LDC_W;
+            // Can we replace the long instruction by a short instruction?
+            if (opcode == InstructionConstants.OP_LDC_W)
+            {
+                opcode = InstructionConstants.OP_LDC;
+            }
         }
-        else if (opcode == InstructionConstants.OP_LDC_W &&
-                 cpIndex <= 0xff)
+        else
         {
-            opcode = InstructionConstants.OP_LDC;
+            // Should we replace the short instruction by a long instruction?
+            if (opcode == InstructionConstants.OP_LDC)
+            {
+                opcode = InstructionConstants.OP_LDC_W;
+            }
         }
 
         return this;
@@ -118,7 +125,12 @@ implements   CpInfoVisitor
         int cpIndexSize  = cpIndexSize();
         int constantSize = constantSize();
 
-        writeValue(code, offset, cpIndex,  cpIndexSize);  offset += cpIndexSize;
+        if (requiredCpIndexSize() > cpIndexSize)
+        {
+            throw new IllegalArgumentException("Instruction has invalid constant index size ("+this.toString(offset)+")");
+        }
+
+        writeValue(code, offset, cpIndex,  cpIndexSize); offset += cpIndexSize;
         writeValue(code, offset, constant, constantSize);
     }
 
@@ -246,7 +258,7 @@ implements   CpInfoVisitor
     // Small utility methods.
 
     /**
-     * Computes the appropriate constant pool index size for this instruction.
+     * Returns the constant pool index size for this instruction.
      */
     private int cpIndexSize()
     {
@@ -256,7 +268,7 @@ implements   CpInfoVisitor
 
 
     /**
-     * Computes the appropriate constant size for this instruction.
+     * Returns the constant size for this instruction.
      */
     private int constantSize()
     {
@@ -264,4 +276,16 @@ implements   CpInfoVisitor
                opcode == InstructionConstants.OP_INVOKEINTERFACE ? 2 :
                                                                    0;
     }
+
+
+    /**
+     * Computes the required constant pool index size for this instruction's
+     * constant pool index.
+     */
+    private int requiredCpIndexSize()
+    {
+        return (cpIndex &   0xff) == cpIndex ? 1 :
+               (cpIndex & 0xffff) == cpIndex ? 2 :
+                                               4;
+    }
 }
diff --git a/src/proguard/classfile/instruction/Instruction.java b/src/proguard/classfile/instruction/Instruction.java
index 57bbda9..76138ca 100644
--- a/src/proguard/classfile/instruction/Instruction.java
+++ b/src/proguard/classfile/instruction/Instruction.java
@@ -1,8 +1,8 @@
-/* $Id: Instruction.java,v 1.24 2005/10/22 11:55:29 eric Exp $
+/* $Id: Instruction.java,v 1.24.2.2 2006/11/20 22:11:40 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -662,13 +662,18 @@ public abstract class Instruction
     /**
      * Shrinks this instruction to its shortest possible form.
      * @return this instruction.
+     * @throws IllegalArgumentException if the instruction can't be expanded
+     *                                  to the necessary size, e.g. if it
+     *                                  contains an offset that is too large.
      */
     public abstract Instruction shrink();
 
 
-
     /**
-     * Writes the Instruction back to the data in the byte array.
+     * Writes the Instruction at the given offset in the given code attribute.
+     * @throws IllegalArgumentException if the instruction can't be written out
+     *                                  in its current state, e.g. if it
+     *                                  contains an offset that is too large.
      */
     public final void write(CodeAttrInfo codeAttrInfo, int offset)
     {
diff --git a/src/proguard/classfile/instruction/InstructionCounter.java b/src/proguard/classfile/instruction/InstructionCounter.java
index 2671f9b..aa2a868 100644
--- a/src/proguard/classfile/instruction/InstructionCounter.java
+++ b/src/proguard/classfile/instruction/InstructionCounter.java
@@ -1,8 +1,8 @@
-/* $Id: InstructionCounter.java,v 1.1 2005/07/31 18:50:05 eric Exp $
+/* $Id: InstructionCounter.java,v 1.1.2.3 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -26,23 +26,23 @@ import proguard.classfile.instruction.*;
 
 /**
  * This InstructionVisitor counts the number of instructions that has been visited.
- * 
+ *
  * @author Eric Lafortune
  */
 public class InstructionCounter implements InstructionVisitor
 {
     private int count;
-    
-    
+
+
     /**
      * Returns the number of instructions that has been visited so far.
      */
     public int getCount()
     {
-        return count++;
+        return count;
     }
-    
-    
+
+
     // Implementations for InstructionVisitor.
 
     public void visitBranchInstruction(ClassFile         classFile,
@@ -54,7 +54,7 @@ public class InstructionCounter implements InstructionVisitor
         count++;
     }
 
-    
+
     public void visitCpInstruction(ClassFile     classFile,
                                    MethodInfo    methodInfo,
                                    CodeAttrInfo  codeAttrInfo,
@@ -64,7 +64,7 @@ public class InstructionCounter implements InstructionVisitor
         count++;
     }
 
-    
+
     public void visitLookUpSwitchInstruction(ClassFile               classFile,
                                              MethodInfo              methodInfo,
                                              CodeAttrInfo            codeAttrInfo,
@@ -74,7 +74,7 @@ public class InstructionCounter implements InstructionVisitor
         count++;
     }
 
-    
+
     public void visitSimpleInstruction(ClassFile         classFile,
                                        MethodInfo        methodInfo,
                                        CodeAttrInfo      codeAttrInfo,
@@ -83,8 +83,8 @@ public class InstructionCounter implements InstructionVisitor
     {
         count++;
     }
-    
-    
+
+
     public void visitTableSwitchInstruction(ClassFile              classFile,
                                             MethodInfo             methodInfo,
                                             CodeAttrInfo           codeAttrInfo,
@@ -94,7 +94,7 @@ public class InstructionCounter implements InstructionVisitor
         count++;
     }
 
-    
+
     public void visitVariableInstruction(ClassFile           classFile,
                                          MethodInfo          methodInfo,
                                          CodeAttrInfo        codeAttrInfo,
diff --git a/src/proguard/classfile/instruction/InstructionFactory.java b/src/proguard/classfile/instruction/InstructionFactory.java
index 7f72b82..f5758cb 100644
--- a/src/proguard/classfile/instruction/InstructionFactory.java
+++ b/src/proguard/classfile/instruction/InstructionFactory.java
@@ -1,8 +1,8 @@
-/* $Id: InstructionFactory.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: InstructionFactory.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/InstructionVisitor.java b/src/proguard/classfile/instruction/InstructionVisitor.java
index 1af3da6..b15d2ce 100644
--- a/src/proguard/classfile/instruction/InstructionVisitor.java
+++ b/src/proguard/classfile/instruction/InstructionVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: InstructionVisitor.java,v 1.14 2005/06/11 13:13:15 eric Exp $
+/* $Id: InstructionVisitor.java,v 1.14.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/LookUpSwitchInstruction.java b/src/proguard/classfile/instruction/LookUpSwitchInstruction.java
index 8192bb3..7f3bc41 100644
--- a/src/proguard/classfile/instruction/LookUpSwitchInstruction.java
+++ b/src/proguard/classfile/instruction/LookUpSwitchInstruction.java
@@ -1,8 +1,8 @@
-/* $Id: LookUpSwitchInstruction.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: LookUpSwitchInstruction.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/MultiInstructionVisitor.java b/src/proguard/classfile/instruction/MultiInstructionVisitor.java
index 5f97342..8c23262 100644
--- a/src/proguard/classfile/instruction/MultiInstructionVisitor.java
+++ b/src/proguard/classfile/instruction/MultiInstructionVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: MultiInstructionVisitor.java,v 1.5 2005/06/11 13:13:15 eric Exp $
+/* $Id: MultiInstructionVisitor.java,v 1.5.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/SimpleInstruction.java b/src/proguard/classfile/instruction/SimpleInstruction.java
index 98b013e..cc19dd8 100644
--- a/src/proguard/classfile/instruction/SimpleInstruction.java
+++ b/src/proguard/classfile/instruction/SimpleInstruction.java
@@ -1,8 +1,8 @@
-/* $Id: SimpleInstruction.java,v 1.9 2005/06/11 13:13:15 eric Exp $
+/* $Id: SimpleInstruction.java,v 1.9.2.2 2006/11/20 22:11:40 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -77,19 +77,30 @@ public class SimpleInstruction extends Instruction
 
     public Instruction shrink()
     {
-        // Is this a sipush instruction that can be a bipush instruction?
-        if (opcode == InstructionConstants.OP_SIPUSH &&
-            constant << 24 >> 24 == constant)
-        {
-            opcode = InstructionConstants.OP_BIPUSH;
-        }
+        int requiredConstantSize = requiredConstantSize();
 
-        // Is this a bipush instruction that can be an iconst instruction?
-        if (opcode == InstructionConstants.OP_BIPUSH &&
-            constant >= -1 &&
-            constant <= 5)
+        // Is the (integer) constant size right?
+        if (opcode != InstructionConstants.OP_NEWARRAY &&
+            requiredConstantSize != constantSize())
         {
-            opcode = (byte)(InstructionConstants.OP_ICONST_0 + constant);
+            // Can we replace the integer push instruction?
+            switch (requiredConstantSize)
+            {
+                case 0:
+                    opcode = (byte)(InstructionConstants.OP_ICONST_0 + constant);
+                    break;
+
+                case 1:
+                    opcode = InstructionConstants.OP_BIPUSH;
+                    break;
+
+                case 2:
+                    opcode = InstructionConstants.OP_SIPUSH;
+                    break;
+
+                default:
+                    throw new IllegalArgumentException("Simple instruction can't be widened ("+this.toString()+")");
+            }
         }
 
         return this;
@@ -137,7 +148,14 @@ public class SimpleInstruction extends Instruction
 
     protected void writeInfo(byte[] code, int offset)
     {
-        writeValue(code, offset, constant, constantSize());
+        int constantSize = constantSize();
+
+        if (requiredConstantSize() > constantSize)
+        {
+            throw new IllegalArgumentException("Instruction has invalid constant size ("+this.toString(offset)+")");
+        }
+
+        writeValue(code, offset, constant, constantSize);
     }
 
 
@@ -170,7 +188,7 @@ public class SimpleInstruction extends Instruction
     // Small utility methods.
 
     /**
-     * Computes the appropriate constant size for this instruction.
+     * Returns the constant size for this instruction.
      */
     private int constantSize()
     {
@@ -179,4 +197,16 @@ public class SimpleInstruction extends Instruction
                opcode == InstructionConstants.OP_SIPUSH   ? 2 :
                                                             0;
     }
+
+
+    /**
+     * Computes the required constant size for this instruction.
+     */
+    private int requiredConstantSize()
+    {
+        return constant >= -1 && constant <= 5  ? 0 :
+               constant << 24 >> 24 == constant ? 1 :
+               constant << 16 >> 16 == constant ? 2 :
+                                                  4;
+    }
 }
diff --git a/src/proguard/classfile/instruction/TableSwitchInstruction.java b/src/proguard/classfile/instruction/TableSwitchInstruction.java
index 14debda..726836b 100644
--- a/src/proguard/classfile/instruction/TableSwitchInstruction.java
+++ b/src/proguard/classfile/instruction/TableSwitchInstruction.java
@@ -1,8 +1,8 @@
-/* $Id: TableSwitchInstruction.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: TableSwitchInstruction.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/instruction/VariableInstruction.java b/src/proguard/classfile/instruction/VariableInstruction.java
index c51db2a..22aefc7 100644
--- a/src/proguard/classfile/instruction/VariableInstruction.java
+++ b/src/proguard/classfile/instruction/VariableInstruction.java
@@ -1,8 +1,8 @@
-/* $Id: VariableInstruction.java,v 1.20 2005/06/11 13:21:35 eric Exp $
+/* $Id: VariableInstruction.java,v 1.20.2.2 2006/11/20 22:11:40 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -31,9 +31,9 @@ import proguard.classfile.attribute.*;
  */
 public class VariableInstruction extends Instruction
 {
-    public boolean wide;
     public int     variableIndex;
     public int     constant;
+    public boolean wide;
 
 
     /**
@@ -56,7 +56,8 @@ public class VariableInstruction extends Instruction
         this.opcode        = opcode;
         this.variableIndex = variableIndex;
         this.constant      = constant;
-        this.wide          = mustBeWide();
+        this.wide          = requiredVariableIndexSize() > 2 ||
+                             requiredConstantSize() > 1;
     }
 
 
@@ -94,6 +95,7 @@ public class VariableInstruction extends Instruction
 
     public Instruction shrink()
     {
+        // First widen the instruction.
         switch (opcode)
         {
             case InstructionConstants.OP_ILOAD_0:
@@ -159,7 +161,8 @@ public class VariableInstruction extends Instruction
         }
 
         // Only make the instruction wide if necessary.
-        wide = mustBeWide();
+        wide = requiredVariableIndexSize() > 2 ||
+               requiredConstantSize()      > 1;
 
         return this;
     }
@@ -198,6 +201,16 @@ public class VariableInstruction extends Instruction
         int variableIndexSize = variableIndexSize();
         int constantSize      = constantSize();
 
+        if (requiredVariableIndexSize() > variableIndexSize)
+        {
+            throw new IllegalArgumentException("Instruction has invalid variable index size ("+this.toString(offset)+")");
+        }
+
+        if (requiredConstantSize() > constantSize)
+        {
+            throw new IllegalArgumentException("Instruction has invalid constant size ("+this.toString(offset)+")");
+        }
+
         writeValue(code, offset, variableIndex, variableIndexSize); offset += variableIndexSize;
         writeValue(code, offset, constant,      constantSize);
     }
@@ -232,20 +245,7 @@ public class VariableInstruction extends Instruction
     // Small utility methods.
 
     /**
-     * Returns whether this instruction must be wide due to its variable index
-     * and constant.
-     */
-    private boolean mustBeWide()
-    {
-        return variableIndex > 0xff ||
-               (opcode == InstructionConstants.OP_IINC ? (constant < -128 ||
-                                                          constant > 127) :
-                                                         constant > 255);
-    }
-
-
-    /**
-     * Returns the appropriate variable index size for this instruction.
+     * Returns the variable index size for this instruction.
      */
     private int variableIndexSize()
     {
@@ -259,11 +259,38 @@ public class VariableInstruction extends Instruction
 
 
     /**
-     * Returns the appropriate constant size for this instruction.
+     * Computes the required variable index size for this instruction's variable
+     * index.
+     */
+    private int requiredVariableIndexSize()
+    {
+        return (variableIndex &    0x3) == variableIndex ? 0 :
+               (variableIndex &   0xff) == variableIndex ? 1 :
+               (variableIndex & 0xffff) == variableIndex ? 2 :
+                                                           4;
+
+    }
+
+
+    /**
+     * Returns the constant size for this instruction.
      */
     private int constantSize()
     {
-        return opcode == InstructionConstants.OP_IINC ? (wide ? 2 : 1) :
-                                                        0;
+        return opcode != InstructionConstants.OP_IINC ? 0 :
+               wide                                   ? 2 :
+                                                        1;
+    }
+
+
+    /**
+     * Computes the required constant size for this instruction's constant.
+     */
+    private int requiredConstantSize()
+    {
+        return opcode != InstructionConstants.OP_IINC ? 0 :
+               constant << 24 >> 24 == constant       ? 1 :
+               constant << 16 >> 16 == constant       ? 2 :
+                                                        4;
     }
 }
diff --git a/src/proguard/classfile/util/AccessUtil.java b/src/proguard/classfile/util/AccessUtil.java
index 965a4e6..45141f6 100644
--- a/src/proguard/classfile/util/AccessUtil.java
+++ b/src/proguard/classfile/util/AccessUtil.java
@@ -1,8 +1,8 @@
-/* $Id: AccessUtil.java,v 1.6 2005/06/11 13:21:35 eric Exp $
+/* $Id: AccessUtil.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/ClassFileClassForNameReferenceInitializer.java b/src/proguard/classfile/util/ClassFileClassForNameReferenceInitializer.java
index d0f327b..e62da9d 100644
--- a/src/proguard/classfile/util/ClassFileClassForNameReferenceInitializer.java
+++ b/src/proguard/classfile/util/ClassFileClassForNameReferenceInitializer.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileClassForNameReferenceInitializer.java,v 1.17 2005/07/17 14:47:15 eric Exp $
+/* $Id: ClassFileClassForNameReferenceInitializer.java,v 1.17.2.3 2006/11/25 16:56:11 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -48,12 +48,9 @@ public class ClassFileClassForNameReferenceInitializer
 {
     private ClassPool            programClassPool;
     private ClassPool            libraryClassPool;
-    private boolean              note;
+    private WarningPrinter       notePrinter;
     private ClassNameListMatcher noteExceptionMatcher;
 
-    // Counter for notes.
-    private int noteCount;
-
     // Fields to remember the previous StringCpInfo and MethodRefCpInfo objects
     // while visiting all instructions (to find Class.forName, class$, and
     // Class.newInstance invocations, and possible class casts afterwards).
@@ -66,42 +63,22 @@ public class ClassFileClassForNameReferenceInitializer
 
 
     /**
-     * Creates a new ClassFileClassForNameReferenceInitializer that prints notes.
-     */
-    public ClassFileClassForNameReferenceInitializer(ClassPool programClassPool,
-                                                     ClassPool libraryClassPool)
-    {
-        this(programClassPool, libraryClassPool, true, null);
-    }
-
-
-    /**
      * Creates a new ClassFileClassForNameReferenceInitializer that optionally
      * prints notes, with optional class specifications for which never to
      * print notes.
      */
     public ClassFileClassForNameReferenceInitializer(ClassPool            programClassPool,
                                                      ClassPool            libraryClassPool,
-                                                     boolean              note,
+                                                     WarningPrinter       notePrinter,
                                                      ClassNameListMatcher noteExceptionMatcher)
     {
         this.programClassPool     = programClassPool;
         this.libraryClassPool     = libraryClassPool;
-        this.note                 = note;
+        this.notePrinter          = notePrinter;
         this.noteExceptionMatcher = noteExceptionMatcher;
     }
 
 
-    /**
-     * Returns the number of notes printed about occurrences of
-     * '<code>(SomeClass)Class.forName(variable).newInstance()</code>'.
-     */
-    public int getNoteCount()
-    {
-        return noteCount;
-    }
-
-
     // Implementations for InstructionVisitor.
 
     public void visitSimpleInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, SimpleInstruction simpleInstruction)
@@ -109,29 +86,29 @@ public class ClassFileClassForNameReferenceInitializer
         // Nothing interesting; just forget any stored indices.
         clearConstantPoolIndices();
     }
-    
-    
+
+
     public void visitBranchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, BranchInstruction branchInstruction)
     {
         // Nothing interesting; just forget any stored indices.
         clearConstantPoolIndices();
     }
-    
-    
+
+
     public void visitTableSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, TableSwitchInstruction tableSwitchInstruction)
     {
         // Nothing interesting; just forget any stored indices.
         clearConstantPoolIndices();
     }
-    
-    
+
+
     public void visitLookUpSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, LookUpSwitchInstruction lookUpSwitchInstruction)
     {
         // Nothing interesting; just forget any stored indices.
         clearConstantPoolIndices();
     }
-    
-    
+
+
     public void visitVariableInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, VariableInstruction variableInstruction)
     {
 
@@ -281,22 +258,21 @@ public class ClassFileClassForNameReferenceInitializer
      */
     public void visitClassCpInfo(ClassFile classFile, ClassCpInfo classCpInfo)
     {
-        if (note &&
+        if (notePrinter != null &&
             (noteExceptionMatcher == null ||
              !noteExceptionMatcher.matches(classCpInfo.getName(classFile))))
         {
-            noteCount++;
-            System.err.println("Note: " +
-                               ClassUtil.externalClassName(classFile.getName()) +
-                               " calls '(" +
-                               ClassUtil.externalClassName(classCpInfo.getName(classFile)) +
-                               ")Class.forName(variable).newInstance()'");
+            notePrinter.print("Note: " +
+                                 ClassUtil.externalClassName(classFile.getName()) +
+                                 " calls '(" +
+                                 ClassUtil.externalClassName(classCpInfo.getName(classFile)) +
+                                 ")Class.forName(variable).newInstance()'");
         }
     }
 
 
     // Small utility methods.
-    
+
     /**
      * Clears all references to the constant pool.
      */
@@ -306,8 +282,8 @@ public class ClassFileClassForNameReferenceInitializer
         invokestaticMethodRefCpIndex  = -1;
         invokevirtualMethodRefCpIndex = -1;
     }
-    
-    
+
+
     /**
      * Returns the class with the given name, either for the program class pool
      * or from the library class pool, or <code>null</code> if it can't be found.
diff --git a/src/proguard/classfile/util/ClassFileHierarchyInitializer.java b/src/proguard/classfile/util/ClassFileHierarchyInitializer.java
index fd35e4c..da193f9 100644
--- a/src/proguard/classfile/util/ClassFileHierarchyInitializer.java
+++ b/src/proguard/classfile/util/ClassFileHierarchyInitializer.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileHierarchyInitializer.java,v 1.12 2005/06/25 22:07:51 eric Exp $
+/* $Id: ClassFileHierarchyInitializer.java,v 1.12.2.2 2006/11/25 16:56:11 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -23,7 +23,6 @@ package proguard.classfile.util;
 import proguard.classfile.*;
 import proguard.classfile.visitor.*;
 
-
 /**
  * This ClassFileVisitor initializes the class hierarchy of all class files that
  * it visits.
@@ -48,47 +47,23 @@ public class ClassFileHierarchyInitializer
     // A visitor info flag to indicate the class file has been initialized.
     private static final Object INITIALIZED = new Object();
 
-    private ClassPool programClassPool;
-    private ClassPool libraryClassPool;
-    private boolean   warn;
-
-    // Counter for warnings.
-    private int warningCount;
-
-
-    /**
-     * Creates a new ClassFileReferenceInitializer that initializes the hierarchy
-     * of all visited class files, printing warnings if some classes can't be found.
-     */
-    public ClassFileHierarchyInitializer(ClassPool programClassPool,
-                                         ClassPool libraryClassPool)
-    {
-        this(programClassPool, libraryClassPool, true);
-    }
+    private ClassPool      programClassPool;
+    private ClassPool      libraryClassPool;
+    private WarningPrinter warningPrinter;
 
 
     /**
-     * Creates a new ClassFileReferenceInitializer that initializes the hierarchy
-     * of all visited class files, optionally printing warnings if some classes
-     * can't be found.
+     * Creates a new ClassFileReferenceInitializer that initializes the
+     * hierarchy of all visited class files, optionally printing warnings if
+     * some classes can't be found.
      */
-    public ClassFileHierarchyInitializer(ClassPool programClassPool,
-                                         ClassPool libraryClassPool,
-                                         boolean   warn)
+    public ClassFileHierarchyInitializer(ClassPool      programClassPool,
+                                         ClassPool      libraryClassPool,
+                                         WarningPrinter warningPrinter)
     {
         this.programClassPool = programClassPool;
         this.libraryClassPool = libraryClassPool;
-        this.warn             = warn;
-    }
-
-
-    /**
-     * Returns the number of warnings printed about unresolved references to
-     * superclasses or interfaces.
-     */
-    public int getWarningCount()
-    {
-        return warningCount;
+        this.warningPrinter   = warningPrinter;
     }
 
 
@@ -269,14 +244,13 @@ public class ClassFileHierarchyInitializer
         {
             classFile.addSubClass(subclass);
         }
-        else if (warn)
+        else if (warningPrinter != null)
         {
             // We didn't find the superclass or interface. Print a warning.
-            warningCount++;
-            System.err.println("Warning: " +
-                               ClassUtil.externalClassName(subclass.getName()) +
-                               ": can't find superclass or interface " +
-                               ClassUtil.externalClassName(className));
+            warningPrinter.print("Warning: " +
+                                 ClassUtil.externalClassName(subclass.getName()) +
+                                 ": can't find superclass or interface " +
+                                 ClassUtil.externalClassName(className));
         }
     }
 }
diff --git a/src/proguard/classfile/util/ClassFileReferenceInitializer.java b/src/proguard/classfile/util/ClassFileReferenceInitializer.java
index 3343373..f10d793 100644
--- a/src/proguard/classfile/util/ClassFileReferenceInitializer.java
+++ b/src/proguard/classfile/util/ClassFileReferenceInitializer.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileReferenceInitializer.java,v 1.31 2005/06/25 22:07:51 eric Exp $
+/* $Id: ClassFileReferenceInitializer.java,v 1.31.2.4 2006/11/25 16:56:11 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -25,7 +25,6 @@ import proguard.classfile.attribute.*;
 import proguard.classfile.attribute.annotation.*;
 import proguard.classfile.visitor.*;
 
-
 /**
  * This ClassFileVisitor initializes the references of all class files that
  * it visits.
@@ -58,47 +57,23 @@ public class ClassFileReferenceInitializer
 {
     private MemberFinder memberFinder = new MemberFinder();
 
-    private ClassPool programClassPool;
-    private ClassPool libraryClassPool;
-    private boolean   warn;
-
-    // Counter for warnings.
-    private int warningCount;
-
-
-    /**
-     * Creates a new ClassFileReferenceInitializer that initializes the hierarchy
-     * of all visited class files, printing warnings if some classes can't be found.
-     */
-    public ClassFileReferenceInitializer(ClassPool programClassPool,
-                                         ClassPool libraryClassPool)
-    {
-        this(programClassPool, libraryClassPool, true);
-    }
+    private ClassPool      programClassPool;
+    private ClassPool      libraryClassPool;
+    private WarningPrinter warningPrinter;
 
 
     /**
-     * Creates a new ClassFileReferenceInitializer that initializes the hierarchy
-     * of all visited class files, optionally printing warnings if some classes
-     * can't be found.
+     * Creates a new ClassFileReferenceInitializer that initializes the
+     * references of all visited class files, optionally printing warnings if
+     * some classes can't be found.
      */
-    public ClassFileReferenceInitializer(ClassPool programClassPool,
-                                         ClassPool libraryClassPool,
-                                         boolean   warn)
+    public ClassFileReferenceInitializer(ClassPool      programClassPool,
+                                         ClassPool      libraryClassPool,
+                                         WarningPrinter warningPrinter)
     {
         this.programClassPool = programClassPool;
         this.libraryClassPool = libraryClassPool;
-        this.warn             = warn;
-    }
-
-
-    /**
-     * Returns the number of warnings printed about unresolved references to
-     * class members in program class files.
-     */
-    public int getWarningCount()
-    {
-        return warningCount;
+        this.warningPrinter   = warningPrinter;
     }
 
 
@@ -207,24 +182,26 @@ public class ClassFileReferenceInitializer
 
             // See if we can find the referenced class member somewhere in the
             // hierarchy.
-            refCpInfo.referencedMemberInfo = memberFinder.findMember(referencedClassFile,
+            refCpInfo.referencedMemberInfo = memberFinder.findMember(classFile,
+                                                                     referencedClassFile,
                                                                      name,
                                                                      type,
                                                                      isFieldRef);
             refCpInfo.referencedClassFile  = memberFinder.correspondingClassFile();
 
-            if (warn && refCpInfo.referencedMemberInfo == null)
+            // Check if we haven't found the class member anywhere in the
+            // hierarchy.
+            if (refCpInfo.referencedMemberInfo == null &&
+                warningPrinter != null)
             {
-                // We've haven't found the class member anywhere in the hierarchy.
-                warningCount++;
-                System.err.println("Warning: " +
-                                   ClassUtil.externalClassName(classFile.getName()) +
-                                   ": can't find referenced " +
-                                   (isFieldRef ?
-                                    "field '"  + ClassUtil.externalFullFieldDescription(0, name, type) :
-                                    "method '" + ClassUtil.externalFullMethodDescription(className, 0, name, type)) +
-                                   "' in class " +
-                                   ClassUtil.externalClassName(className));
+                warningPrinter.print("Warning: " +
+                                     ClassUtil.externalClassName(classFile.getName()) +
+                                     ": can't find referenced " +
+                                     (isFieldRef ?
+                                         "field '"  + ClassUtil.externalFullFieldDescription(0, name, type) :
+                                         "method '" + ClassUtil.externalFullMethodDescription(className, 0, name, type)) +
+                                     "' in class " +
+                                     ClassUtil.externalClassName(className));
             }
         }
     }
@@ -260,13 +237,12 @@ public class ClassFileReferenceInitializer
         if (referencedClassFile == null)
         {
             // We couldn't find the enclosing class.
-            if (warn)
+            if (warningPrinter != null)
             {
-                warningCount++;
-                System.err.println("Warning: " +
-                                   ClassUtil.externalClassName(classFile.getName()) +
-                                   ": can't find enclosing class " +
-                                   ClassUtil.externalClassName(className));
+                warningPrinter.print("Warning: " +
+                                     ClassUtil.externalClassName(classFile.getName()) +
+                                     ": can't find enclosing class " +
+                                     ClassUtil.externalClassName(className));
             }
 
             return;
@@ -287,15 +263,14 @@ public class ClassFileReferenceInitializer
         if (referencedMethodInfo == null)
         {
             // We couldn't find the enclosing method.
-            if (warn)
+            if (warningPrinter != null)
             {
-                warningCount++;
-                System.err.println("Warning: " +
-                                   ClassUtil.externalClassName(classFile.getName()) +
-                                   ": can't find enclosing method '" +
-                                   ClassUtil.externalFullMethodDescription(className, 0, name, type) +
-                                   "' in class " +
-                                   ClassUtil.externalClassName(className));
+                warningPrinter.print("Warning: " +
+                                     ClassUtil.externalClassName(classFile.getName()) +
+                                     ": can't find enclosing method '" +
+                                     ClassUtil.externalFullMethodDescription(className, 0, name, type) +
+                                     "' in class " +
+                                     ClassUtil.externalClassName(className));
             }
 
             return;
@@ -458,8 +433,9 @@ public class ClassFileReferenceInitializer
             // (ignoring the descriptor).
             String name = classFile.getCpString(elementValue.u2elementName);
 
-            elementValue.referencedMethodInfo =
-                annotation.referencedClassFiles[0].findMethod(name, null);
+            ClassFile referencedClassFile = annotation.referencedClassFiles[0];
+            elementValue.referencedClassFile  = referencedClassFile;
+            elementValue.referencedMethodInfo = referencedClassFile.findMethod(name, null);
         }
     }
 
diff --git a/src/proguard/classfile/util/ClassForNameChecker.java b/src/proguard/classfile/util/ClassForNameChecker.java
index 2c9beea..31f91ff 100644
--- a/src/proguard/classfile/util/ClassForNameChecker.java
+++ b/src/proguard/classfile/util/ClassForNameChecker.java
@@ -1,8 +1,8 @@
-/* $Id: ClassForNameChecker.java,v 1.12 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassForNameChecker.java,v 1.12.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/ClassNewInstanceChecker.java b/src/proguard/classfile/util/ClassNewInstanceChecker.java
index 1ccb9b7..2c2ebd4 100644
--- a/src/proguard/classfile/util/ClassNewInstanceChecker.java
+++ b/src/proguard/classfile/util/ClassNewInstanceChecker.java
@@ -1,8 +1,8 @@
-/* $Id: ClassNewInstanceChecker.java,v 1.8 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassNewInstanceChecker.java,v 1.8.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/ClassUtil.java b/src/proguard/classfile/util/ClassUtil.java
index dc372ce..c16f897 100644
--- a/src/proguard/classfile/util/ClassUtil.java
+++ b/src/proguard/classfile/util/ClassUtil.java
@@ -1,8 +1,8 @@
-/* $Id: ClassUtil.java,v 1.25 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassUtil.java,v 1.25.2.3 2006/12/11 21:57:29 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -206,7 +206,7 @@ public class ClassUtil
 
     /**
      * Returns whether the given internal type is a plain class type
-     * (not an array type).
+     * (including an array type of a plain class type).
      * @param internalType the internal type,
      *                     e.g. "<code>Ljava/lang/Object;</code>".
      * @return <code>true</code> if the given type is a class type,
@@ -216,7 +216,7 @@ public class ClassUtil
     {
         int length = internalType.length();
         return length > 1 &&
-               internalType.charAt(0)        == ClassConstants.INTERNAL_TYPE_CLASS_START &&
+//             internalType.charAt(0)        == ClassConstants.INTERNAL_TYPE_CLASS_START &&
                internalType.charAt(length-1) == ClassConstants.INTERNAL_TYPE_CLASS_END;
     }
 
@@ -238,21 +238,28 @@ public class ClassUtil
 
 
     /**
-     * Returns the internal class name of a given internal class type.
+     * Returns the internal class name of a given internal class type
+     * (including an array type). Types involving primitive types are returned
+     * unchanged.
      * @param internalClassType the internal class type,
-     *                          e.g. "<code>Ljava/lang/Object;</code>".
+     *                          e.g. "<code>[Ljava/lang/Object;</code>",
+     *                               "<code>Ljava/lang/Object;</code>", or
+     *                               "<code>java/lang/Object</code>".
      * @return the internal class name,
      *                          e.g. "<code>java/lang/Object</code>".
      */
     public static String internalClassNameFromClassType(String internalClassType)
     {
-        return internalClassType.substring(1, internalClassType.length()-1);
+        return isInternalClassType(internalClassType) ?
+            internalClassType.substring(internalClassType.indexOf(ClassConstants.INTERNAL_TYPE_CLASS_START)+1,
+                                        internalClassType.length()-1) :
+            internalClassType;
     }
 
 
     /**
-     * Returns the internal class name of any given internal type, disregarding
-     * array prefixes.
+     * Returns the internal class name of any given internal descriptor type,
+     * disregarding array prefixes.
      * @param internalClassType the internal class type,
      *                          e.g. "<code>Ljava/lang/Object;</code>" or
      *                               "<code>[[I</code>".
@@ -262,23 +269,18 @@ public class ClassUtil
      */
     public static String internalClassNameFromType(String internalClassType)
     {
+        if (!isInternalClassType(internalClassType))
+        {
+            return null;
+        }
+
         // Is it an array type?
         if (isInternalArrayType(internalClassType))
         {
             internalClassType = internalTypeFromArrayType(internalClassType);
-
-            // Is the array of a non-primitive type?
-            if (isInternalClassType(internalClassType))
-            {
-                internalClassType = internalClassNameFromClassType(internalClassType);
-            }
-            else
-            {
-                internalClassType = null;//ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT;
-            }
         }
 
-        return internalClassType;
+        return internalClassNameFromClassType(internalClassType);
     }
 
 
diff --git a/src/proguard/classfile/util/DescriptorClassEnumeration.java b/src/proguard/classfile/util/DescriptorClassEnumeration.java
index c92fb13..d4f4c23 100644
--- a/src/proguard/classfile/util/DescriptorClassEnumeration.java
+++ b/src/proguard/classfile/util/DescriptorClassEnumeration.java
@@ -1,8 +1,8 @@
-/* $Id: DescriptorClassEnumeration.java,v 1.12 2005/06/11 13:21:35 eric Exp $
+/* $Id: DescriptorClassEnumeration.java,v 1.12.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/ExternalTypeEnumeration.java b/src/proguard/classfile/util/ExternalTypeEnumeration.java
index 4631b1f..216f549 100644
--- a/src/proguard/classfile/util/ExternalTypeEnumeration.java
+++ b/src/proguard/classfile/util/ExternalTypeEnumeration.java
@@ -1,8 +1,8 @@
-/* $Id: ExternalTypeEnumeration.java,v 1.10 2005/06/11 13:13:15 eric Exp $
+/* $Id: ExternalTypeEnumeration.java,v 1.10.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/InternalTypeEnumeration.java b/src/proguard/classfile/util/InternalTypeEnumeration.java
index d32f6ea..59caa37 100644
--- a/src/proguard/classfile/util/InternalTypeEnumeration.java
+++ b/src/proguard/classfile/util/InternalTypeEnumeration.java
@@ -1,8 +1,8 @@
-/* $Id: InternalTypeEnumeration.java,v 1.9 2005/06/11 13:13:15 eric Exp $
+/* $Id: InternalTypeEnumeration.java,v 1.9.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/util/MemberFinder.java b/src/proguard/classfile/util/MemberFinder.java
index 8294133..b12bffa 100644
--- a/src/proguard/classfile/util/MemberFinder.java
+++ b/src/proguard/classfile/util/MemberFinder.java
@@ -1,8 +1,8 @@
-/* $Id: MemberFinder.java,v 1.7 2005/06/11 13:21:35 eric Exp $
+/* $Id: MemberFinder.java,v 1.7.2.4 2006/03/26 14:21:36 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -23,7 +23,6 @@ package proguard.classfile.util;
 import proguard.classfile.*;
 import proguard.classfile.visitor.*;
 
-
 /**
  * This class provides methods to find class members in a given class or in its
  * hierarchy.
@@ -44,9 +43,12 @@ public class MemberFinder
      * Finds the field with the given name and descriptor in the given
      * class file or its hierarchy.
      */
-    public FieldInfo findField(ClassFile classFile, String name, String descriptor)
+    public FieldInfo findField(ClassFile referencingClassFile,
+                               ClassFile classFile,
+                               String    name,
+                               String    descriptor)
     {
-        return (FieldInfo)findMember(classFile, name, descriptor, true);
+        return (FieldInfo)findMember(referencingClassFile, classFile, name, descriptor, true);
     }
 
 
@@ -54,9 +56,12 @@ public class MemberFinder
      * Finds the method with the given name and descriptor in the given
      * class file or its hierarchy.
      */
-    public MethodInfo findMethod(ClassFile classFile, String name, String descriptor)
+    public MethodInfo findMethod(ClassFile referencingClassFile,
+                                 ClassFile classFile,
+                                 String    name,
+                                 String    descriptor)
     {
-        return (MethodInfo)findMember(classFile, name, descriptor, false);
+        return (MethodInfo)findMember(referencingClassFile, classFile, name, descriptor, false);
     }
 
 
@@ -64,37 +69,27 @@ public class MemberFinder
      * Finds the class member with the given name and descriptor in the given
      * class file or its hierarchy.
      */
-    public MemberInfo findMember(ClassFile classFile,
+    public MemberInfo findMember(ClassFile referencingClassFile,
+                                 ClassFile classFile,
                                  String    name,
                                  String    descriptor,
                                  boolean   isField)
     {
-        // For efficiency, first see if we can find the method in the
-        // referenced class itself.
-        this.classFile  = classFile;
-        this.memberInfo = isField ?
-            (MemberInfo)classFile.findField(name, descriptor) :
-            (MemberInfo)classFile.findMethod(name, descriptor);
-
-        if (memberInfo == null)
+        // Organize a search in the hierarchy of superclasses and interfaces.
+        // The class member may be in a different class, if the code was
+        // compiled with "-target 1.2" or higher (the default in JDK 1.4).
+        try
+        {
+            this.classFile  = null;
+            this.memberInfo = null;
+            classFile.hierarchyAccept(true, true, true, false, isField ?
+                (ClassFileVisitor)new NamedFieldVisitor(name, descriptor,
+                                  new MemberInfoClassFileAccessFilter(referencingClassFile, this)) :
+                (ClassFileVisitor)new NamedMethodVisitor(name, descriptor,
+                                  new MemberInfoClassFileAccessFilter(referencingClassFile, this)));
+        }
+        catch (MemberFoundException ex)
         {
-            // We didn't find the method yet. Organize a search in the hierarchy
-            // of superclasses and interfaces. This can happen with classes
-            // compiled with "-target 1.2" or higher (the default in JDK 1.4).
-            try
-            {
-                this.classFile  = null;
-                this.memberInfo = null;
-                classFile.hierarchyAccept(false, true, true, false,
-                                          isField ?
-                                              (ClassFileVisitor)new NamedFieldVisitor(name, descriptor,
-                                                                new MemberInfoAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE, this)) :
-                                              (ClassFileVisitor)new NamedMethodVisitor(name, descriptor,
-                                                                new MemberInfoAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE, this)));
-            }
-            catch (MemberFoundException ex)
-            {
-            }
         }
 
         return memberInfo;
diff --git a/src/proguard/classfile/util/MethodInfoLinker.java b/src/proguard/classfile/util/MethodInfoLinker.java
index dcfe3b8..73c621a 100644
--- a/src/proguard/classfile/util/MethodInfoLinker.java
+++ b/src/proguard/classfile/util/MethodInfoLinker.java
@@ -1,8 +1,8 @@
-/* $Id: MethodInfoLinker.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: MethodInfoLinker.java,v 1.2.2.2 2006/06/07 22:36:52 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -26,12 +26,11 @@ import proguard.classfile.visitor.*;
 import java.util.*;
 
 /**
- * This ClassFileVisitor links all corresponding methods in the class hierarchies
- * of all visited class files. Visited class files are typically all class
- * files that are not being subclassed. Chains of links that have been created in
- * previous invocations are merged with new chains of links, in order to create
- * a consistent set of chains. Class initialization methods and constructors are
- * ignored.
+ * This ClassFileVisitor links all corresponding non-private methods in the class
+ * hierarchies of all visited classes. Visited classes are typically all class
+ * files that are not being subclassed. Chains of links that have been created
+ * in previous invocations are merged with new chains of links, in order to
+ * create a consistent set of chains.
  *
  * @author Eric Lafortune
  */
@@ -40,20 +39,22 @@ public class MethodInfoLinker
              MemberInfoVisitor
 {
     // An object that is reset and reused every time.
-    // The map: [class member name+descriptor - class member info]
-    private final Map methodInfoMap = new HashMap();
+    // The map: [class member name+' '+descriptor - class member info]
+    private final Map memberInfoMap = new HashMap();
 
 
     // Implementations for ClassFileVisitor.
 
     public void visitProgramClassFile(ProgramClassFile programClassFile)
     {
-        // Collect all members in this class hierarchy.
+        // Collect all non-private members in this class hierarchy.
         programClassFile.hierarchyAccept(true, true, true, false,
-                                         new AllMemberInfoVisitor(this));
+            new AllMemberInfoVisitor(
+            new MemberInfoAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE,
+            this)));
 
         // Clean up for the next class hierarchy.
-        methodInfoMap.clear();
+        memberInfoMap.clear();
     }
 
 
@@ -66,43 +67,39 @@ public class MethodInfoLinker
 
     public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo)
     {
+        visitMemberInfo(programClassFile, programFieldInfo);
     }
 
 
     public void visitProgramMethodInfo(ProgramClassFile programClassFile, ProgramMethodInfo programMethodInfo)
     {
-        visitMethodInfo(programClassFile, programMethodInfo);
+        visitMemberInfo(programClassFile, programMethodInfo);
     }
 
 
     public void visitLibraryFieldInfo(LibraryClassFile libraryClassFile, LibraryFieldInfo libraryFieldInfo)
     {
+        visitMemberInfo(libraryClassFile, libraryFieldInfo);
     }
 
 
     public void visitLibraryMethodInfo(LibraryClassFile libraryClassFile, LibraryMethodInfo libraryMethodInfo)
     {
-        visitMethodInfo(libraryClassFile, libraryMethodInfo);
+        visitMemberInfo(libraryClassFile, libraryMethodInfo);
     }
 
 
     /**
-     * Links the given method into the chains of links. Class initialization
+     * Links the given member into the chains of links. Class initialization
      * methods and constructors are ignored.
      * @param classFile  the class file of the given method.
-     * @param methodInfo the method to be linked.
+     * @param memberInfo the method to be linked.
      */
-    private void visitMethodInfo(ClassFile classFile, MethodInfo methodInfo)
+    private void visitMemberInfo(ClassFile classFile, MemberInfo memberInfo)
     {
-        // Private methods don't have to be linked.
-        if ((methodInfo.getAccessFlags() & ClassConstants.INTERNAL_ACC_PRIVATE) != 0)
-        {
-            return;
-        }
-
         // Get the method's original name and descriptor.
-        String name       = methodInfo.getName(classFile);
-        String descriptor = methodInfo.getDescriptor(classFile);
+        String name       = memberInfo.getName(classFile);
+        String descriptor = memberInfo.getDescriptor(classFile);
 
         // Special cases: <clinit> and <init> are always kept unchanged.
         // We can ignore them here.
@@ -112,35 +109,35 @@ public class MethodInfoLinker
             return;
         }
 
-        // Get the last method in the chain.
-        MemberInfo thisLastMethodInfo = lastMethodInfo(methodInfo);
+        // Get the last member in the chain.
+        MemberInfo thisLastMemberInfo = lastMemberInfo(memberInfo);
 
-        // See if we've already come across a method with the same name and
+        // See if we've already come across a member with the same name and
         // descriptor.
-        String key = name + descriptor;
-        MethodInfo otherMethodInfo = (MethodInfo)methodInfoMap.get(key);
+        String key = name + ' ' + descriptor;
+        MemberInfo otherMemberInfo = (MemberInfo)memberInfoMap.get(key);
 
-        if (otherMethodInfo == null)
+        if (otherMemberInfo == null)
         {
-            // Store the new class method info in the map.
-            methodInfoMap.put(key, thisLastMethodInfo);
+            // Store the new class member info in the map.
+            memberInfoMap.put(key, thisLastMemberInfo);
         }
         else
         {
-            // Get the last method in the other chain.
-            MethodInfo otherLastMethodInfo = lastMethodInfo(otherMethodInfo);
+            // Get the last member in the other chain.
+            MemberInfo otherLastMemberInfo = lastMemberInfo(otherMemberInfo);
 
             // Check if both link chains aren't already ending in the same element.
-            if (!thisLastMethodInfo.equals(otherLastMethodInfo))
+            if (!thisLastMemberInfo.equals(otherLastMemberInfo))
             {
                 // Merge the two chains, with the library members last.
-                if (otherLastMethodInfo instanceof LibraryMemberInfo)
+                if (otherLastMemberInfo instanceof LibraryMemberInfo)
                 {
-                    thisLastMethodInfo.setVisitorInfo(otherLastMethodInfo);
+                    thisLastMemberInfo.setVisitorInfo(otherLastMemberInfo);
                 }
                 else
                 {
-                    otherLastMethodInfo.setVisitorInfo(thisLastMethodInfo);
+                    otherLastMemberInfo.setVisitorInfo(thisLastMemberInfo);
                 }
             }
         }
@@ -150,20 +147,20 @@ public class MethodInfoLinker
     // Small utility methods.
 
     /**
-     * Finds the last method in the linked list of related methods.
-     * @param methodInfo the given method.
-     * @return the last method in the linked list.
+     * Finds the last member in the linked list of related members.
+     * @param memberInfo the given member.
+     * @return the last member in the linked list.
      */
-    public static MethodInfo lastMethodInfo(MethodInfo methodInfo)
+    public static MemberInfo lastMemberInfo(MemberInfo memberInfo)
     {
-        MethodInfo lastMethodInfo = methodInfo;
-        while (lastMethodInfo.getVisitorInfo() != null &&
-               lastMethodInfo.getVisitorInfo() instanceof MethodInfo)
+        MemberInfo lastMemberInfo = memberInfo;
+        while (lastMemberInfo.getVisitorInfo() != null &&
+               lastMemberInfo.getVisitorInfo() instanceof MemberInfo)
         {
-            lastMethodInfo = (MethodInfo)lastMethodInfo.getVisitorInfo();
+            lastMemberInfo = (MemberInfo)lastMemberInfo.getVisitorInfo();
         }
 
-        return lastMethodInfo;
+        return lastMemberInfo;
     }
 
     /**
diff --git a/src/proguard/classfile/util/WarningPrinter.java b/src/proguard/classfile/util/WarningPrinter.java
new file mode 100644
index 0000000..a4516c8
--- /dev/null
+++ b/src/proguard/classfile/util/WarningPrinter.java
@@ -0,0 +1,77 @@
+/* $Id: WarningPrinter.java,v 1.1.2.1 2006/11/25 15:54:01 eric Exp $
+ *
+ * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
+ *
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.util;
+
+import proguard.classfile.visitor.*;
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.*;
+
+import java.io.PrintStream;
+
+/**
+ * This class prints out and counts warnings.
+ *
+ * @author Eric Lafortune
+ */
+public class WarningPrinter
+{
+    private PrintStream printStream;
+    private int         warningCount;
+
+
+    /**
+     * Creates a new WarningPrinter that prints to the System.err print stream.
+     */
+    public WarningPrinter()
+    {
+        this(System.err);
+    }
+
+
+    /**
+     * Creates a new WarningPrinter that prints to the given print stream.
+     */
+    public WarningPrinter(PrintStream printStream)
+    {
+        this.printStream = printStream;
+    }
+
+
+    /**
+     * Prints out the given warning and increments the warning count.
+     */
+    public void print(String warning)
+    {
+        printStream.println(warning);
+
+        warningCount++;
+    }
+
+
+    /**
+     * Returns the number of warnings printed so far.
+     */
+    public int getWarningCount()
+    {
+        return warningCount;
+    }
+}
diff --git a/src/proguard/classfile/visitor/AllClassFileVisitor.java b/src/proguard/classfile/visitor/AllClassFileVisitor.java
index 25ab8aa..071f274 100644
--- a/src/proguard/classfile/visitor/AllClassFileVisitor.java
+++ b/src/proguard/classfile/visitor/AllClassFileVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: AllClassFileVisitor.java,v 1.11 2005/06/11 13:13:15 eric Exp $
+/* $Id: AllClassFileVisitor.java,v 1.11.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/AllCpInfoVisitor.java b/src/proguard/classfile/visitor/AllCpInfoVisitor.java
index 480ba39..489c1a6 100644
--- a/src/proguard/classfile/visitor/AllCpInfoVisitor.java
+++ b/src/proguard/classfile/visitor/AllCpInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: AllCpInfoVisitor.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: AllCpInfoVisitor.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/AllFieldVisitor.java b/src/proguard/classfile/visitor/AllFieldVisitor.java
index 4be2777..342475e 100644
--- a/src/proguard/classfile/visitor/AllFieldVisitor.java
+++ b/src/proguard/classfile/visitor/AllFieldVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: AllFieldVisitor.java,v 1.13 2005/06/11 13:13:15 eric Exp $
+/* $Id: AllFieldVisitor.java,v 1.13.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/AllMemberInfoVisitor.java b/src/proguard/classfile/visitor/AllMemberInfoVisitor.java
index 2301cb4..d03f261 100644
--- a/src/proguard/classfile/visitor/AllMemberInfoVisitor.java
+++ b/src/proguard/classfile/visitor/AllMemberInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: AllMemberInfoVisitor.java,v 1.11 2005/06/11 13:13:15 eric Exp $
+/* $Id: AllMemberInfoVisitor.java,v 1.11.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/AllMethodVisitor.java b/src/proguard/classfile/visitor/AllMethodVisitor.java
index b1f82fc..2fd7b93 100644
--- a/src/proguard/classfile/visitor/AllMethodVisitor.java
+++ b/src/proguard/classfile/visitor/AllMethodVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: AllMethodVisitor.java,v 1.13 2005/06/11 13:13:15 eric Exp $
+/* $Id: AllMethodVisitor.java,v 1.13.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/BottomClassFileFilter.java b/src/proguard/classfile/visitor/BottomClassFileFilter.java
index 9876961..31d0993 100644
--- a/src/proguard/classfile/visitor/BottomClassFileFilter.java
+++ b/src/proguard/classfile/visitor/BottomClassFileFilter.java
@@ -1,8 +1,8 @@
-/* $Id: BottomClassFileFilter.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: BottomClassFileFilter.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassCounter.java b/src/proguard/classfile/visitor/ClassCounter.java
index 32d9469..de301b1 100644
--- a/src/proguard/classfile/visitor/ClassCounter.java
+++ b/src/proguard/classfile/visitor/ClassCounter.java
@@ -1,8 +1,8 @@
-/* $Id: ClassCounter.java,v 1.1 2005/07/31 18:50:05 eric Exp $
+/* $Id: ClassCounter.java,v 1.1.2.3 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -25,23 +25,23 @@ import proguard.classfile.visitor.*;
 
 /**
  * This ClassFileVisitor counts the number of classes that has been visited.
- * 
+ *
  * @author Eric Lafortune
  */
 public class ClassCounter implements ClassFileVisitor
 {
     private int count;
-    
-    
+
+
     /**
      * Returns the number of classes that has been visited so far.
      */
     public int getCount()
     {
-        return count++;
+        return count;
     }
-    
-    
+
+
     // Implementations for ClassFileVisitor.
 
     public void visitLibraryClassFile(LibraryClassFile libraryClassFile)
@@ -49,7 +49,7 @@ public class ClassCounter implements ClassFileVisitor
         count++;
     }
 
-    
+
     public void visitProgramClassFile(ProgramClassFile programClassFile)
     {
         count++;
diff --git a/src/proguard/classfile/visitor/ClassFileAccessFilter.java b/src/proguard/classfile/visitor/ClassFileAccessFilter.java
index 18c7777..5327bd2 100644
--- a/src/proguard/classfile/visitor/ClassFileAccessFilter.java
+++ b/src/proguard/classfile/visitor/ClassFileAccessFilter.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileAccessFilter.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassFileAccessFilter.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassFileCleaner.java b/src/proguard/classfile/visitor/ClassFileCleaner.java
index ec90a32..51e50f2 100644
--- a/src/proguard/classfile/visitor/ClassFileCleaner.java
+++ b/src/proguard/classfile/visitor/ClassFileCleaner.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileCleaner.java,v 1.18 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassFileCleaner.java,v 1.18.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassFileHierarchyTraveler.java b/src/proguard/classfile/visitor/ClassFileHierarchyTraveler.java
index 2fe7d36..bdfc4a9 100644
--- a/src/proguard/classfile/visitor/ClassFileHierarchyTraveler.java
+++ b/src/proguard/classfile/visitor/ClassFileHierarchyTraveler.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileHierarchyTraveler.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassFileHierarchyTraveler.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassFileMemberInfoVisitor.java b/src/proguard/classfile/visitor/ClassFileMemberInfoVisitor.java
index 25637b9..a377972 100644
--- a/src/proguard/classfile/visitor/ClassFileMemberInfoVisitor.java
+++ b/src/proguard/classfile/visitor/ClassFileMemberInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileMemberInfoVisitor.java,v 1.5 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassFileMemberInfoVisitor.java,v 1.5.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassFileNameFilter.java b/src/proguard/classfile/visitor/ClassFileNameFilter.java
index 142e306..2b369d4 100644
--- a/src/proguard/classfile/visitor/ClassFileNameFilter.java
+++ b/src/proguard/classfile/visitor/ClassFileNameFilter.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileNameFilter.java,v 1.10 2005/08/21 20:25:33 eric Exp $
+/* $Id: ClassFileNameFilter.java,v 1.10.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ClassFilePresenceFilter.java b/src/proguard/classfile/visitor/ClassFilePresenceFilter.java
new file mode 100644
index 0000000..75b7e35
--- /dev/null
+++ b/src/proguard/classfile/visitor/ClassFilePresenceFilter.java
@@ -0,0 +1,95 @@
+/* $Id: ClassFilePresenceFilter.java,v 1.1.2.1 2006/11/26 15:29:20 eric Exp $
+ *
+ * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
+ *
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.visitor;
+
+import proguard.classfile.*;
+
+/**
+ * This <code>ClassFileVisitor</code> delegates its visits to one of two
+ * <code>ClassFileVisitor</code> instances, depending on whether the name of
+ * the visited class file is present in a given <code>ClassPool</code> or not.
+ *
+ * @author Eric Lafortune
+ */
+public class ClassFilePresenceFilter implements ClassFileVisitor
+{
+    private ClassPool        classPool;
+    private ClassFileVisitor presentClassFileVisitor;
+    private ClassFileVisitor missingClassFileVisitor;
+
+
+    /**
+     * Creates a new ClassFilePresenceFilter.
+     * @param classPool               the <code>ClassPool</code> in which the
+     *                                presence will be tested.
+     * @param presentClassFileVisitor the <code>ClassFileVisitor</code> to which
+     *                                visits of present class files will be
+     *                                delegated.
+     * @param missingClassFileVisitor the <code>ClassFileVisitor</code> to which
+     *                                visits of missing class files will be
+     *                                delegated.
+     */
+    public ClassFilePresenceFilter(ClassPool        classPool,
+                                   ClassFileVisitor presentClassFileVisitor,
+                                   ClassFileVisitor missingClassFileVisitor)
+    {
+        this.classPool               = classPool;
+        this.presentClassFileVisitor = presentClassFileVisitor;
+        this.missingClassFileVisitor = missingClassFileVisitor;
+    }
+
+
+    // Implementations for ClassFileVisitor.
+
+    public void visitProgramClassFile(ProgramClassFile programClassFile)
+    {
+        ClassFileVisitor classFileVisitor = classFileVisitor(programClassFile);
+
+        if (classFileVisitor != null)
+        {
+            classFileVisitor.visitProgramClassFile(programClassFile);
+        }
+    }
+
+
+    public void visitLibraryClassFile(LibraryClassFile libraryClassFile)
+    {
+        ClassFileVisitor classFileVisitor = classFileVisitor(libraryClassFile);
+
+        if (classFileVisitor != null)
+        {
+            classFileVisitor.visitLibraryClassFile(libraryClassFile);
+        }
+    }
+
+
+    // Small utility methods.
+
+    /**
+     * Returns the appropriate <code>ClassFileVisitor</code>.
+     */
+    private ClassFileVisitor classFileVisitor(ClassFile classFile)
+    {
+        return classPool.getClass(classFile.getName()) != null ?
+            presentClassFileVisitor :
+            missingClassFileVisitor;
+    }
+}
diff --git a/src/proguard/classfile/visitor/ClassFilePrinter.java b/src/proguard/classfile/visitor/ClassFilePrinter.java
index 14f33f0..9c430c8 100644
--- a/src/proguard/classfile/visitor/ClassFilePrinter.java
+++ b/src/proguard/classfile/visitor/ClassFilePrinter.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFilePrinter.java,v 1.31 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassFilePrinter.java,v 1.31.2.2 2006/11/20 22:10:50 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -77,10 +77,9 @@ public class ClassFilePrinter
     {
         println("_____________________________________________________________________");
         println(visitorInfo(programClassFile) + " CLASS: " + programClassFile.getName());
-        println("Access:        " + ClassUtil.externalClassAccessFlags(programClassFile.u2accessFlags) + "(" + Integer.toHexString(programClassFile.u2accessFlags) + ")");
         println("Minor version: " + Integer.toHexString(programClassFile.u2minorVersion));
         println("Major version: " + Integer.toHexString(programClassFile.u2majorVersion));
-        println("Access:        " + Integer.toHexString(programClassFile.u2accessFlags));
+        println("Access:        " + ClassUtil.externalClassAccessFlags(programClassFile.u2accessFlags) + "(" + Integer.toHexString(programClassFile.u2accessFlags) + ")");
         println("Superclass:    " + programClassFile.getSuperName());
         println();
 
diff --git a/src/proguard/classfile/visitor/ClassFileVersionCounter.java b/src/proguard/classfile/visitor/ClassFileVersionCounter.java
new file mode 100644
index 0000000..00f23d4
--- /dev/null
+++ b/src/proguard/classfile/visitor/ClassFileVersionCounter.java
@@ -0,0 +1,79 @@
+/* $Id: ClassFileVersionCounter.java,v 1.1.2.1 2006/12/11 22:07:35 eric Exp $
+ *
+ * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
+ *
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.visitor;
+
+import proguard.classfile.*;
+
+/**
+ * This <code>ClassFileVisitor</code> counts the number of visited program class
+ * files that have at least the given version number.
+ *
+ * @author Eric Lafortune
+ */
+public class ClassFileVersionCounter implements ClassFileVisitor
+{
+    private int majorVersionNumber;
+    private int minorVersionNumber;
+
+    private int count;
+
+
+    /**
+     * Creates a new ClassFileVersionChecker.
+     * @param majorVersionNumber the major version number.
+     * @param minorVersionNumber the minor version number.
+     */
+    public ClassFileVersionCounter(int majorVersionNumber,
+                                   int minorVersionNumber)
+    {
+        this.majorVersionNumber = majorVersionNumber;
+        this.minorVersionNumber = minorVersionNumber;
+    }
+
+
+    /**
+     * Returns the number of visited program class files with the given minimum
+     * version number.
+     */
+    public int getCount()
+    {
+        return count;
+    }
+
+
+    // Implementations for ClassFileVisitor.
+
+    public void visitProgramClassFile(ProgramClassFile programClassFile)
+    {
+        if ((programClassFile.u2majorVersion == majorVersionNumber &&
+             programClassFile.u2minorVersion >=  minorVersionNumber) ||
+            programClassFile.u2majorVersion > majorVersionNumber)
+        {
+            count++;
+        }
+    }
+
+
+    public void visitLibraryClassFile(LibraryClassFile libraryClassFile)
+    {
+        // Library class files don't store their version numbers.
+    }
+}
diff --git a/src/proguard/classfile/visitor/ClassFileVisitor.java b/src/proguard/classfile/visitor/ClassFileVisitor.java
index 91b8867..594bf50 100644
--- a/src/proguard/classfile/visitor/ClassFileVisitor.java
+++ b/src/proguard/classfile/visitor/ClassFileVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileVisitor.java,v 1.8 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassFileVisitor.java,v 1.8.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ReferencedClassFileVisitor.java b/src/proguard/classfile/visitor/ClassForNameClassFileVisitor.java
similarity index 55%
copy from src/proguard/classfile/visitor/ReferencedClassFileVisitor.java
copy to src/proguard/classfile/visitor/ClassForNameClassFileVisitor.java
index 95edea9..cde8694 100644
--- a/src/proguard/classfile/visitor/ReferencedClassFileVisitor.java
+++ b/src/proguard/classfile/visitor/ClassForNameClassFileVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: ReferencedClassFileVisitor.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassForNameClassFileVisitor.java,v 1.1.2.1 2006/02/13 00:19:28 eric Exp $
  *
- * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
+ * ProGuard -- shrinking, optimization, and obfuscation of Java bytecode.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -21,21 +21,30 @@
 package proguard.classfile.visitor;
 
 import proguard.classfile.*;
+import proguard.classfile.instruction.*;
+import proguard.classfile.util.*;
 
 
 /**
- * This CpInfoVisitor lets a given ClassFileVisitor visit all the referenced
- * class files of the constant pool entries that it visits.
+ * This CpInfoVisitor lets a given <code>ClassFileVisitor</code> visit all
+ * constant classes involved in any <code>Class.forName</code> constructs
+ * that it visits.
+ *
+ * @see DotClassClassFileVisitor
  *
  * @author Eric Lafortune
  */
-public class ReferencedClassFileVisitor
-  implements CpInfoVisitor
+public class ClassForNameClassFileVisitor implements CpInfoVisitor
 {
     private ClassFileVisitor classFileVisitor;
 
 
-    public ReferencedClassFileVisitor(ClassFileVisitor classFileVisitor)
+    /**
+     * Creates a new ClassForNameClassFileVisitor
+     * @param classFileVisitor the <code>ClassFileVisitor</code> to which
+     *                         visits will be delegated.
+     */
+    public ClassForNameClassFileVisitor(ClassFileVisitor classFileVisitor)
     {
         this.classFileVisitor = classFileVisitor;
     }
@@ -48,58 +57,17 @@ public class ReferencedClassFileVisitor
     public void visitFloatCpInfo(ClassFile classFile, FloatCpInfo floatCpInfo) {}
     public void visitDoubleCpInfo(ClassFile classFile, DoubleCpInfo doubleCpInfo) {}
     public void visitUtf8CpInfo(ClassFile classFile, Utf8CpInfo utf8CpInfo) {}
+    public void visitFieldrefCpInfo(ClassFile classFile, FieldrefCpInfo fieldrefCpInfo) {}
+    public void visitInterfaceMethodrefCpInfo(ClassFile classFile, InterfaceMethodrefCpInfo interfaceMethodrefCpInfo) {}
+    public void visitMethodrefCpInfo(ClassFile classFile, MethodrefCpInfo methodrefCpInfo) {}
+    public void visitClassCpInfo(ClassFile classFile, ClassCpInfo classCpInfo) {}
     public void visitNameAndTypeCpInfo(ClassFile classFile, NameAndTypeCpInfo nameAndTypeCpInfo) {}
 
 
     public void visitStringCpInfo(ClassFile classFile, StringCpInfo stringCpInfo)
     {
-        visitReferencedClassFile(stringCpInfo.referencedClassFile);
-    }
-
-
-    public void visitFieldrefCpInfo(ClassFile classFile, FieldrefCpInfo fieldrefCpInfo)
-    {
-        visitReferencedClassFile(fieldrefCpInfo.referencedClassFile);
-    }
-
-
-    public void visitInterfaceMethodrefCpInfo(ClassFile classFile, InterfaceMethodrefCpInfo interfaceMethodrefCpInfo)
-    {
-        visitReferencedClassFile(interfaceMethodrefCpInfo.referencedClassFile);
-    }
-
-
-    public void visitMethodrefCpInfo(ClassFile classFile, MethodrefCpInfo methodrefCpInfo)
-    {
-        visitReferencedClassFile(methodrefCpInfo.referencedClassFile);
-    }
-
-
-    public void visitClassCpInfo(ClassFile classFile, ClassCpInfo classCpInfo)
-    {
-        visitReferencedClassFile(classCpInfo.referencedClassFile);
-    }
-
-
-    // Small utility methods.
-
-    private void visitReferencedClassFiles(ClassFile[] referencedClassFiles)
-    {
-        if (referencedClassFiles != null)
-        {
-            for (int index = 0; index < referencedClassFiles.length; index++)
-            {
-                visitReferencedClassFile(referencedClassFiles[index]);
-            }
-        }
-    }
-
-
-    private void visitReferencedClassFile(ClassFile referencedClassFile)
-    {
-        if (referencedClassFile != null)
-        {
-            referencedClassFile.accept(classFileVisitor);
-        }
+        // Visit the referenced class from the ClassFile.forName construct,
+        // if any.
+        stringCpInfo.referencedClassAccept(classFileVisitor);
     }
 }
diff --git a/src/proguard/classfile/visitor/ClassPoolFiller.java b/src/proguard/classfile/visitor/ClassPoolFiller.java
index eda6aeb..9e332c6 100644
--- a/src/proguard/classfile/visitor/ClassPoolFiller.java
+++ b/src/proguard/classfile/visitor/ClassPoolFiller.java
@@ -1,8 +1,8 @@
-/* $Id: ClassPoolFiller.java,v 1.9 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassPoolFiller.java,v 1.9.2.3 2006/11/26 15:29:20 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -21,7 +21,7 @@
 package proguard.classfile.visitor;
 
 import proguard.classfile.*;
-import proguard.classfile.util.ClassUtil;
+import proguard.classfile.util.*;
 
 
 /**
@@ -33,14 +33,14 @@ import proguard.classfile.util.ClassUtil;
 public class ClassPoolFiller implements ClassFileVisitor
 {
     private ClassPool classPool;
-    private boolean   note;
 
 
-    public ClassPoolFiller(ClassPool classPool,
-                           boolean   note)
+    /**
+     * Creates a new ClassPoolFiller.
+     */
+    public ClassPoolFiller(ClassPool classPool)
     {
         this.classPool = classPool;
-        this.note      = note;
     }
 
 
@@ -48,22 +48,12 @@ public class ClassPoolFiller implements ClassFileVisitor
 
     public void visitProgramClassFile(ProgramClassFile programClassFile)
     {
-        ClassFile previousClassFile = classPool.addClass(programClassFile);
-        if (previousClassFile != null &&
-            note)
-        {
-            System.err.println("Note: duplicate definition of program class [" + ClassUtil.externalClassName(programClassFile.getName()) + "]");
-        }
+        classPool.addClass(programClassFile);
     }
 
 
     public void visitLibraryClassFile(LibraryClassFile libraryClassFile)
     {
-        ClassFile previousClassFile = classPool.addClass(libraryClassFile);
-        if (previousClassFile != null &&
-            note)
-        {
-            System.err.println("Note: duplicate definition of library class [" + ClassUtil.externalClassName(libraryClassFile.getName()) + "]");
-        }
+        classPool.addClass(libraryClassFile);
     }
 }
diff --git a/src/proguard/classfile/visitor/ClassPoolVisitor.java b/src/proguard/classfile/visitor/ClassPoolVisitor.java
index 8b00c02..f091789 100644
--- a/src/proguard/classfile/visitor/ClassPoolVisitor.java
+++ b/src/proguard/classfile/visitor/ClassPoolVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: ClassPoolVisitor.java,v 1.10 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassPoolVisitor.java,v 1.10.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ConcreteClassFileDownTraveler.java b/src/proguard/classfile/visitor/ConcreteClassFileDownTraveler.java
index 331367f..4eb7071 100644
--- a/src/proguard/classfile/visitor/ConcreteClassFileDownTraveler.java
+++ b/src/proguard/classfile/visitor/ConcreteClassFileDownTraveler.java
@@ -1,8 +1,8 @@
-/* $Id: ConcreteClassFileDownTraveler.java,v 1.8 2005/06/11 13:13:15 eric Exp $
+/* $Id: ConcreteClassFileDownTraveler.java,v 1.8.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/CpInfoVisitor.java b/src/proguard/classfile/visitor/CpInfoVisitor.java
index 17b6ee6..49a7153 100644
--- a/src/proguard/classfile/visitor/CpInfoVisitor.java
+++ b/src/proguard/classfile/visitor/CpInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: CpInfoVisitor.java,v 1.8 2005/06/11 13:13:15 eric Exp $
+/* $Id: CpInfoVisitor.java,v 1.8.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/DotClassClassFileVisitor.java b/src/proguard/classfile/visitor/DotClassClassFileVisitor.java
new file mode 100644
index 0000000..38d9535
--- /dev/null
+++ b/src/proguard/classfile/visitor/DotClassClassFileVisitor.java
@@ -0,0 +1,99 @@
+/* $Id: DotClassClassFileVisitor.java,v 1.1.2.1 2006/02/13 00:19:28 eric Exp $
+ *
+ * ProGuard -- shrinking, optimization, and obfuscation of Java bytecode.
+ *
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.attribute.CodeAttrInfo;
+import proguard.classfile.instruction.*;
+import proguard.classfile.util.*;
+
+/**
+ * This InstructionVisitor lets a given <code>ClassFileVisitor</code> visit all
+ * classes involved in any <code>.class</code> constructs that it visits.
+ * <p>
+ * Note that before JDK 1.5, <code>.class</code> constructs are actually
+ * compiled differently, using <code>Class.forName</code> constructs.
+ *
+ * @see ClassForNameClassFileVisitor
+ *
+ * @author Eric Lafortune
+ */
+public class DotClassClassFileVisitor
+  implements InstructionVisitor,
+             CpInfoVisitor
+{
+    private ClassFileVisitor classFileVisitor;
+
+
+    /**
+     * Creates a new DotClassClassFileVisitor.
+     * @param classFileVisitor the <code>ClassFileVisitor</code> to which
+     *                         visits will be delegated.
+     */
+    public DotClassClassFileVisitor(ClassFileVisitor classFileVisitor)
+    {
+        this.classFileVisitor = classFileVisitor;
+    }
+
+
+    // Implementations for InstructionVisitor.
+
+    public void visitSimpleInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, SimpleInstruction simpleInstruction) {}
+    public void visitVariableInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, VariableInstruction variableInstruction) {}
+    public void visitBranchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, BranchInstruction branchInstruction) {}
+    public void visitTableSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, TableSwitchInstruction tableSwitchInstruction) {}
+    public void visitLookUpSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) {}
+
+
+    public void visitCpInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, CpInstruction cpInstruction)
+    {
+        byte opcode = cpInstruction.opcode;
+
+        // Could this instruction be a .class construct?
+        if (opcode == InstructionConstants.OP_LDC ||
+            opcode == InstructionConstants.OP_LDC_W)
+        {
+            classFile.constantPoolEntryAccept(cpInstruction.cpIndex,
+                                              this);
+        }
+    }
+
+
+    // Implementations for CpInfoVisitor.
+
+    public void visitIntegerCpInfo(ClassFile classFile, IntegerCpInfo integerCpInfo) {}
+    public void visitLongCpInfo(ClassFile classFile, LongCpInfo longCpInfo) {}
+    public void visitFloatCpInfo(ClassFile classFile, FloatCpInfo floatCpInfo) {}
+    public void visitDoubleCpInfo(ClassFile classFile, DoubleCpInfo doubleCpInfo) {}
+    public void visitStringCpInfo(ClassFile classFile, StringCpInfo stringCpInfo) {}
+    public void visitUtf8CpInfo(ClassFile classFile, Utf8CpInfo utf8CpInfo) {}
+    public void visitFieldrefCpInfo(ClassFile classFile, FieldrefCpInfo fieldrefCpInfo) {}
+    public void visitInterfaceMethodrefCpInfo(ClassFile classFile, InterfaceMethodrefCpInfo interfaceMethodrefCpInfo) {}
+    public void visitMethodrefCpInfo(ClassFile classFile, MethodrefCpInfo methodrefCpInfo) {}
+    public void visitNameAndTypeCpInfo(ClassFile classFile, NameAndTypeCpInfo nameAndTypeCpInfo) {}
+
+
+    public void visitClassCpInfo(ClassFile classFile, ClassCpInfo classCpInfo)
+    {
+        // Visit the referenced class from the .class construct.
+        classCpInfo.referencedClassAccept(classFileVisitor);
+    }
+}
diff --git a/src/proguard/classfile/visitor/LibraryClassFileFilter.java b/src/proguard/classfile/visitor/LibraryClassFileFilter.java
index 9da5cdb..c932c5f 100644
--- a/src/proguard/classfile/visitor/LibraryClassFileFilter.java
+++ b/src/proguard/classfile/visitor/LibraryClassFileFilter.java
@@ -1,8 +1,8 @@
-/* $Id: LibraryClassFileFilter.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: LibraryClassFileFilter.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/LibraryMemberInfoFilter.java b/src/proguard/classfile/visitor/LibraryMemberInfoFilter.java
index dd32a42..9e68190 100644
--- a/src/proguard/classfile/visitor/LibraryMemberInfoFilter.java
+++ b/src/proguard/classfile/visitor/LibraryMemberInfoFilter.java
@@ -1,8 +1,8 @@
-/* $Id: LibraryMemberInfoFilter.java,v 1.5 2005/06/11 13:13:15 eric Exp $
+/* $Id: LibraryMemberInfoFilter.java,v 1.5.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/LineNumberInfoVisitor.java b/src/proguard/classfile/visitor/LineNumberInfoVisitor.java
index 770390a..766aa91 100644
--- a/src/proguard/classfile/visitor/LineNumberInfoVisitor.java
+++ b/src/proguard/classfile/visitor/LineNumberInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: LineNumberInfoVisitor.java,v 1.10 2005/06/11 13:13:15 eric Exp $
+/* $Id: LineNumberInfoVisitor.java,v 1.10.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberCounter.java b/src/proguard/classfile/visitor/MemberCounter.java
index 49e4d2e..e6ab989 100644
--- a/src/proguard/classfile/visitor/MemberCounter.java
+++ b/src/proguard/classfile/visitor/MemberCounter.java
@@ -1,8 +1,8 @@
-/* $Id: MemberCounter.java,v 1.1 2005/07/31 18:50:05 eric Exp $
+/* $Id: MemberCounter.java,v 1.1.2.3 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -25,23 +25,23 @@ import proguard.classfile.visitor.*;
 
 /**
  * This MemberInfoVisitor counts the number of class members that has been visited.
- * 
+ *
  * @author Eric Lafortune
  */
 public class MemberCounter implements MemberInfoVisitor
 {
     private int count;
-    
-    
+
+
     /**
      * Returns the number of class members that has been visited so far.
      */
     public int getCount()
     {
-        return count++;
+        return count;
     }
-    
-    
+
+
     // Implementations for MemberInfoVisitor.
 
     public void visitLibraryFieldInfo(LibraryClassFile libraryClassFile,
@@ -50,21 +50,21 @@ public class MemberCounter implements MemberInfoVisitor
         count++;
     }
 
-    
+
     public void visitLibraryMethodInfo(LibraryClassFile libraryClassFile,
                                        LibraryMethodInfo libraryMethodInfo)
     {
         count++;
     }
 
-    
+
     public void visitProgramFieldInfo(ProgramClassFile programClassFile,
                                       ProgramFieldInfo programFieldInfo)
     {
         count++;
     }
 
-    
+
     public void visitProgramMethodInfo(ProgramClassFile programClassFile,
                                        ProgramMethodInfo programMethodInfo)
     {
diff --git a/src/proguard/classfile/visitor/MemberInfoAccessFilter.java b/src/proguard/classfile/visitor/MemberInfoAccessFilter.java
index 8b89470..6464512 100644
--- a/src/proguard/classfile/visitor/MemberInfoAccessFilter.java
+++ b/src/proguard/classfile/visitor/MemberInfoAccessFilter.java
@@ -1,8 +1,8 @@
-/* $Id: MemberInfoAccessFilter.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: MemberInfoAccessFilter.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberInfoClassFileAccessFilter.java b/src/proguard/classfile/visitor/MemberInfoClassFileAccessFilter.java
new file mode 100644
index 0000000..e8cdc92
--- /dev/null
+++ b/src/proguard/classfile/visitor/MemberInfoClassFileAccessFilter.java
@@ -0,0 +1,106 @@
+/* $Id: MemberInfoClassFileAccessFilter.java,v 1.1.2.3 2006/02/13 00:20:43 eric Exp $
+ *
+ * ProGuard -- shrinking, optimization, and obfuscation of Java bytecode.
+ *
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.classfile.visitor;
+
+import proguard.classfile.*;
+import proguard.classfile.util.*;
+
+/**
+ * This <code>MemberInfoVisitor</code> delegates its visits to another given
+ * <code>MemberInfoVisitor</code>, but only when the visited memberInfo is
+ * accessible from the given referencing classFile.
+ *
+ * @author Eric Lafortune
+ */
+public class MemberInfoClassFileAccessFilter
+implements   MemberInfoVisitor
+{
+    private ClassFile         referencingClassFile;
+    private MemberInfoVisitor memberInfoVisitor;
+
+
+    /**
+     * Creates a new MemberInfoAccessFilter.
+     * @param referencingClassFile the classFile that is accessing the member.
+     * @param memberInfoVisitor    the <code>MemberInfoVisitor</code> to which
+     *                             visits will be delegated.
+     */
+    public MemberInfoClassFileAccessFilter(ClassFile         referencingClassFile,
+                                           MemberInfoVisitor memberInfoVisitor)
+    {
+        this.referencingClassFile = referencingClassFile;
+        this.memberInfoVisitor    = memberInfoVisitor;
+    }
+
+
+    // Implementations for MemberInfoVisitor.
+
+    public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo)
+    {
+        if (accepted(programClassFile, programFieldInfo.getAccessFlags()))
+        {
+            memberInfoVisitor.visitProgramFieldInfo(programClassFile, programFieldInfo);
+        }
+    }
+
+
+    public void visitProgramMethodInfo(ProgramClassFile programClassFile, ProgramMethodInfo programMethodInfo)
+    {
+        if (accepted(programClassFile, programMethodInfo.getAccessFlags()))
+        {
+            memberInfoVisitor.visitProgramMethodInfo(programClassFile, programMethodInfo);
+        }
+    }
+
+
+    public void visitLibraryFieldInfo(LibraryClassFile libraryClassFile, LibraryFieldInfo libraryFieldInfo)
+    {
+        if (accepted(libraryClassFile, libraryFieldInfo.getAccessFlags()))
+        {
+            memberInfoVisitor.visitLibraryFieldInfo(libraryClassFile, libraryFieldInfo);
+        }
+    }
+
+
+    public void visitLibraryMethodInfo(LibraryClassFile libraryClassFile, LibraryMethodInfo libraryMethodInfo)
+    {
+        if (accepted(libraryClassFile, libraryMethodInfo.getAccessFlags()))
+        {
+            memberInfoVisitor.visitLibraryMethodInfo(libraryClassFile, libraryMethodInfo);
+        }
+    }
+
+
+    // Small utility methodInfos.
+
+    private boolean accepted(ClassFile classFile, int memberInfoAccessFlags)
+    {
+        int accessLevel = AccessUtil.accessLevel(memberInfoAccessFlags);
+
+        return
+            (accessLevel >= AccessUtil.PUBLIC                                                              ) ||
+            (accessLevel >= AccessUtil.PRIVATE         && referencingClassFile.equals(classFile)                   ) ||
+            (accessLevel >= AccessUtil.PACKAGE_VISIBLE && (ClassUtil.internalPackageName(referencingClassFile.getName()).equals(
+                                                           ClassUtil.internalPackageName(classFile.getName())))) ||
+            (accessLevel >= AccessUtil.PROTECTED       && (referencingClassFile.extends_(classFile)                  ||
+                                                           referencingClassFile.implements_(classFile))            );
+    }
+}
diff --git a/src/proguard/classfile/visitor/MemberInfoDescriptorFilter.java b/src/proguard/classfile/visitor/MemberInfoDescriptorFilter.java
index 4c0e37c..367b0bb 100644
--- a/src/proguard/classfile/visitor/MemberInfoDescriptorFilter.java
+++ b/src/proguard/classfile/visitor/MemberInfoDescriptorFilter.java
@@ -1,8 +1,8 @@
-/* $Id: MemberInfoDescriptorFilter.java,v 1.10 2005/06/11 13:13:15 eric Exp $
+/* $Id: MemberInfoDescriptorFilter.java,v 1.10.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberInfoNameFilter.java b/src/proguard/classfile/visitor/MemberInfoNameFilter.java
index 8e1daaa..2985455 100644
--- a/src/proguard/classfile/visitor/MemberInfoNameFilter.java
+++ b/src/proguard/classfile/visitor/MemberInfoNameFilter.java
@@ -1,8 +1,8 @@
-/* $Id: MemberInfoNameFilter.java,v 1.10 2005/06/11 13:13:15 eric Exp $
+/* $Id: MemberInfoNameFilter.java,v 1.10.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MemberInfoVisitor.java b/src/proguard/classfile/visitor/MemberInfoVisitor.java
index c178174..8f74fe7 100644
--- a/src/proguard/classfile/visitor/MemberInfoVisitor.java
+++ b/src/proguard/classfile/visitor/MemberInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: MemberInfoVisitor.java,v 1.11 2005/06/11 13:13:15 eric Exp $
+/* $Id: MemberInfoVisitor.java,v 1.11.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MethodImplementationFilter.java b/src/proguard/classfile/visitor/MethodImplementationFilter.java
index 7660040..ec0236a 100644
--- a/src/proguard/classfile/visitor/MethodImplementationFilter.java
+++ b/src/proguard/classfile/visitor/MethodImplementationFilter.java
@@ -1,8 +1,8 @@
-/* $Id: MethodImplementationFilter.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: MethodImplementationFilter.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MethodImplementationTraveler.java b/src/proguard/classfile/visitor/MethodImplementationTraveler.java
index f881fde..2557abe 100644
--- a/src/proguard/classfile/visitor/MethodImplementationTraveler.java
+++ b/src/proguard/classfile/visitor/MethodImplementationTraveler.java
@@ -1,8 +1,8 @@
-/* $Id: MethodImplementationTraveler.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: MethodImplementationTraveler.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MultiClassFileVisitor.java b/src/proguard/classfile/visitor/MultiClassFileVisitor.java
index 2235dd7..0670f7e 100644
--- a/src/proguard/classfile/visitor/MultiClassFileVisitor.java
+++ b/src/proguard/classfile/visitor/MultiClassFileVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: MultiClassFileVisitor.java,v 1.9 2005/06/11 13:13:15 eric Exp $
+/* $Id: MultiClassFileVisitor.java,v 1.9.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/MultiMemberInfoVisitor.java b/src/proguard/classfile/visitor/MultiMemberInfoVisitor.java
index 812449a..0dc7ae2 100644
--- a/src/proguard/classfile/visitor/MultiMemberInfoVisitor.java
+++ b/src/proguard/classfile/visitor/MultiMemberInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: MultiMemberInfoVisitor.java,v 1.12 2005/06/11 13:13:15 eric Exp $
+/* $Id: MultiMemberInfoVisitor.java,v 1.12.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/NamedClassFileVisitor.java b/src/proguard/classfile/visitor/NamedClassFileVisitor.java
index 726034b..a23152e 100644
--- a/src/proguard/classfile/visitor/NamedClassFileVisitor.java
+++ b/src/proguard/classfile/visitor/NamedClassFileVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: NamedClassFileVisitor.java,v 1.9 2005/06/11 13:13:15 eric Exp $
+/* $Id: NamedClassFileVisitor.java,v 1.9.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/NamedFieldVisitor.java b/src/proguard/classfile/visitor/NamedFieldVisitor.java
index 4f8e917..2e840c6 100644
--- a/src/proguard/classfile/visitor/NamedFieldVisitor.java
+++ b/src/proguard/classfile/visitor/NamedFieldVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: NamedFieldVisitor.java,v 1.12 2005/06/11 13:13:15 eric Exp $
+/* $Id: NamedFieldVisitor.java,v 1.12.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/NamedMethodVisitor.java b/src/proguard/classfile/visitor/NamedMethodVisitor.java
index 8933ba8..5aa4798 100644
--- a/src/proguard/classfile/visitor/NamedMethodVisitor.java
+++ b/src/proguard/classfile/visitor/NamedMethodVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: NamedMethodVisitor.java,v 1.12 2005/06/11 13:13:15 eric Exp $
+/* $Id: NamedMethodVisitor.java,v 1.12.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ProgramClassFileFilter.java b/src/proguard/classfile/visitor/ProgramClassFileFilter.java
index 69f2fb7..2c6e67b 100644
--- a/src/proguard/classfile/visitor/ProgramClassFileFilter.java
+++ b/src/proguard/classfile/visitor/ProgramClassFileFilter.java
@@ -1,8 +1,8 @@
-/* $Id: ProgramClassFileFilter.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: ProgramClassFileFilter.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ProgramMemberInfoFilter.java b/src/proguard/classfile/visitor/ProgramMemberInfoFilter.java
index 9212352..afafeb6 100644
--- a/src/proguard/classfile/visitor/ProgramMemberInfoFilter.java
+++ b/src/proguard/classfile/visitor/ProgramMemberInfoFilter.java
@@ -1,8 +1,8 @@
-/* $Id: ProgramMemberInfoFilter.java,v 1.5 2005/06/11 13:13:15 eric Exp $
+/* $Id: ProgramMemberInfoFilter.java,v 1.5.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/ReferencedClassFileVisitor.java b/src/proguard/classfile/visitor/ReferencedClassFileVisitor.java
index 95edea9..1f28d45 100644
--- a/src/proguard/classfile/visitor/ReferencedClassFileVisitor.java
+++ b/src/proguard/classfile/visitor/ReferencedClassFileVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: ReferencedClassFileVisitor.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: ReferencedClassFileVisitor.java,v 1.6.2.3 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -21,16 +21,26 @@
 package proguard.classfile.visitor;
 
 import proguard.classfile.*;
-
+import proguard.classfile.attribute.*;
+import proguard.classfile.attribute.annotation.*;
+import proguard.classfile.visitor.*;
 
 /**
- * This CpInfoVisitor lets a given ClassFileVisitor visit all the referenced
- * class files of the constant pool entries that it visits.
+ * This ClassFileVisitor, MmemberInfoVisitor, CpInfoVisitor, AttrInfoVisitor,
+ * etc. lets a given ClassFileVisitor visit all the referenced classes of the
+ * elements that it visits.
  *
  * @author Eric Lafortune
  */
 public class ReferencedClassFileVisitor
-  implements CpInfoVisitor
+  implements ClassFileVisitor,
+             MemberInfoVisitor,
+             CpInfoVisitor,
+             AttrInfoVisitor,
+             LocalVariableInfoVisitor,
+             LocalVariableTypeInfoVisitor,
+             AnnotationVisitor,
+             ElementValueVisitor
 {
     private ClassFileVisitor classFileVisitor;
 
@@ -41,6 +51,66 @@ public class ReferencedClassFileVisitor
     }
 
 
+    // Implementations for ClassFileVisitor.
+
+    public void visitProgramClassFile(ProgramClassFile programClassFile)
+    {
+        // Visit the constant pool entries.
+        programClassFile.constantPoolEntriesAccept(this);
+
+        // Visit the fields and methods.
+        programClassFile.fieldsAccept(this);
+        programClassFile.methodsAccept(this);
+
+        // Visit the attributes.
+        programClassFile.attributesAccept(this);
+    }
+
+
+    public void visitLibraryClassFile(LibraryClassFile libraryClassFile)
+    {
+        // Visit the fields and methods.
+        libraryClassFile.fieldsAccept(this);
+        libraryClassFile.methodsAccept(this);
+    }
+
+
+    // Implementations for MemberInfoVisitor.
+
+    public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo)
+    {
+        // Let the visitor visit the classes referenced in the descriptor string.
+        programFieldInfo.referencedClassesAccept(classFileVisitor);
+
+        // Visit the attributes.
+        programFieldInfo.attributesAccept(programClassFile, this);
+    }
+
+
+    public void visitProgramMethodInfo(ProgramClassFile programClassFile, ProgramMethodInfo programMethodInfo)
+    {
+        // Let the visitor visit the classes referenced in the descriptor string.
+        programMethodInfo.referencedClassesAccept(classFileVisitor);
+
+        // Visit the attributes.
+        programMethodInfo.attributesAccept(programClassFile, this);
+    }
+
+
+    public void visitLibraryFieldInfo(LibraryClassFile libraryClassFile, LibraryFieldInfo libraryFieldInfo)
+    {
+        // Let the visitor visit the classes referenced in the descriptor string.
+        libraryFieldInfo.referencedClassesAccept(classFileVisitor);
+    }
+
+
+    public void visitLibraryMethodInfo(LibraryClassFile libraryClassFile, LibraryMethodInfo libraryMethodInfo)
+    {
+        // Let the visitor visit the classes referenced in the descriptor string.
+        libraryMethodInfo.referencedClassesAccept(classFileVisitor);
+    }
+
+
     // Implementations for CpInfoVisitor.
 
     public void visitIntegerCpInfo(ClassFile classFile, IntegerCpInfo integerCpInfo) {}
@@ -81,6 +151,147 @@ public class ReferencedClassFileVisitor
     }
 
 
+    // Implementations for AttrInfoVisitor.
+
+    public void visitUnknownAttrInfo(ClassFile classFile, UnknownAttrInfo unknownAttrInfo) {}
+    public void visitInnerClassesAttrInfo(ClassFile classFile, InnerClassesAttrInfo innerClassesAttrInfo) {}
+    public void visitConstantValueAttrInfo(ClassFile classFile, FieldInfo fieldInfo, ConstantValueAttrInfo constantValueAttrInfo) {}
+    public void visitExceptionsAttrInfo(ClassFile classFile, MethodInfo methodInfo, ExceptionsAttrInfo exceptionsAttrInfo) {}
+    public void visitLineNumberTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LineNumberTableAttrInfo lineNumberTableAttrInfo) {}
+    public void visitSourceFileAttrInfo(ClassFile classFile, SourceFileAttrInfo sourceFileAttrInfo) {}
+    public void visitSourceDirAttrInfo(ClassFile classFile, SourceDirAttrInfo sourceDirAttrInfo) {}
+    public void visitDeprecatedAttrInfo(ClassFile classFile, DeprecatedAttrInfo deprecatedAttrInfo) {}
+    public void visitSyntheticAttrInfo(ClassFile classFile, SyntheticAttrInfo syntheticAttrInfo) {}
+    public void visitAnnotationDefaultAttrInfo(ClassFile classFile, AnnotationDefaultAttrInfo annotationDefaultAttrInfo) {}
+
+
+    public void visitCodeAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo)
+    {
+        // Visit the attributes of the code attribute.
+        codeAttrInfo.attributesAccept(classFile, methodInfo, this);
+    }
+
+
+    public void visitEnclosingMethodAttrInfo(ClassFile classFile, EnclosingMethodAttrInfo enclosingMethodAttrInfo)
+    {
+        // Let the visitor visit the class of the enclosing method.
+        visitReferencedClassFile(enclosingMethodAttrInfo.referencedClassFile);
+    }
+
+
+    public void visitLocalVariableTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTableAttrInfo localVariableTableAttrInfo)
+    {
+        // Visit the local variables.
+        localVariableTableAttrInfo.localVariablesAccept(classFile, methodInfo, codeAttrInfo, this);
+    }
+
+
+    public void visitLocalVariableTypeTableAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTypeTableAttrInfo localVariableTypeTableAttrInfo)
+    {
+        // Visit the local variable types.
+        localVariableTypeTableAttrInfo.localVariablesAccept(classFile, methodInfo, codeAttrInfo, this);
+    }
+
+
+    public void visitSignatureAttrInfo(ClassFile classFile, SignatureAttrInfo signatureAttrInfo)
+    {
+        // Let the visitor visit the classes referenced in the signature string.
+        signatureAttrInfo.referencedClassesAccept(classFileVisitor);
+    }
+
+
+    public void visitRuntimeVisibleAnnotationAttrInfo(ClassFile classFile, RuntimeVisibleAnnotationsAttrInfo runtimeVisibleAnnotationsAttrInfo)
+    {
+        // Visit the annotations.
+        runtimeVisibleAnnotationsAttrInfo.annotationsAccept(classFile, this);
+    }
+
+
+    public void visitRuntimeInvisibleAnnotationAttrInfo(ClassFile classFile, RuntimeInvisibleAnnotationsAttrInfo runtimeInvisibleAnnotationsAttrInfo)
+    {
+        // Visit the annotations.
+        runtimeInvisibleAnnotationsAttrInfo.annotationsAccept(classFile, this);
+    }
+
+
+    public void visitRuntimeVisibleParameterAnnotationAttrInfo(ClassFile classFile, RuntimeVisibleParameterAnnotationsAttrInfo runtimeVisibleParameterAnnotationsAttrInfo)
+    {
+        // Visit the annotations.
+        runtimeVisibleParameterAnnotationsAttrInfo.annotationsAccept(classFile, this);
+    }
+
+
+    public void visitRuntimeInvisibleParameterAnnotationAttrInfo(ClassFile classFile, RuntimeInvisibleParameterAnnotationsAttrInfo runtimeInvisibleParameterAnnotationsAttrInfo)
+    {
+        // Visit the annotations.
+        runtimeInvisibleParameterAnnotationsAttrInfo.annotationsAccept(classFile, this);
+    }
+
+
+    public void visitAnnotationDefaultAttrInfo(ClassFile classFile, MethodInfo methodInfo, AnnotationDefaultAttrInfo annotationDefaultAttrInfo)
+    {
+        // Visit the default element value.
+        annotationDefaultAttrInfo.defaultValueAccept(classFile, this);
+    }
+
+
+    // Implementations for LocalVariableInfoVisitor.
+
+    public void visitLocalVariableInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableInfo localVariableInfo)
+    {
+        // Let the visitor visit the class referenced in the local variable.
+        visitReferencedClassFile(localVariableInfo.referencedClassFile);
+    }
+
+
+    // Implementations for LocalVariableTypeInfoVisitor.
+
+    public void visitLocalVariableTypeInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, LocalVariableTypeInfo localVariableTypeInfo)
+    {
+        // Let the visitor visit the classes referenced in the local variable type.
+        visitReferencedClassFiles(localVariableTypeInfo.referencedClassFiles);
+    }
+
+
+    // Implementations for AnnotationVisitor.
+
+    public void visitAnnotation(ClassFile classFile, Annotation annotation)
+    {
+        // Let the visitor visit the classes referenced in the annotation.
+        visitReferencedClassFiles(annotation.referencedClassFiles);
+
+        // Visit the element values.
+        annotation.elementValuesAccept(classFile, this);
+    }
+
+
+    // Implementations for ElementValueVisitor.
+
+    public void visitConstantElementValue(ClassFile classFile, Annotation annotation, ConstantElementValue constantElementValue) {}
+    public void visitAnnotationElementValue(ClassFile classFile, Annotation annotation, AnnotationElementValue annotationElementValue) {}
+
+
+    public void visitEnumConstantElementValue(ClassFile classFile, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
+    {
+        // Let the visitor visit the classes referenced in the constant element value.
+        visitReferencedClassFiles(enumConstantElementValue.referencedClassFiles);
+    }
+
+
+    public void visitClassElementValue(ClassFile classFile, Annotation annotation, ClassElementValue classElementValue)
+    {
+        // Let the visitor visit the classes referenced in the class element value.
+        visitReferencedClassFiles(classElementValue.referencedClassFiles);
+    }
+
+
+    public void visitArrayElementValue(ClassFile classFile, Annotation annotation, ArrayElementValue arrayElementValue)
+    {
+        // Visit the element values.
+        arrayElementValue.elementValuesAccept(classFile, annotation, this);
+    }
+
+
     // Small utility methods.
 
     private void visitReferencedClassFiles(ClassFile[] referencedClassFiles)
diff --git a/src/proguard/classfile/visitor/SimpleClassFilePrinter.java b/src/proguard/classfile/visitor/SimpleClassFilePrinter.java
index 7b7206f..20cb3c8 100644
--- a/src/proguard/classfile/visitor/SimpleClassFilePrinter.java
+++ b/src/proguard/classfile/visitor/SimpleClassFilePrinter.java
@@ -1,8 +1,8 @@
-/* $Id: SimpleClassFilePrinter.java,v 1.18 2005/06/11 13:13:15 eric Exp $
+/* $Id: SimpleClassFilePrinter.java,v 1.18.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/VariableClassFileVisitor.java b/src/proguard/classfile/visitor/VariableClassFileVisitor.java
index 803136b..68d0c7c 100644
--- a/src/proguard/classfile/visitor/VariableClassFileVisitor.java
+++ b/src/proguard/classfile/visitor/VariableClassFileVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: VariableClassFileVisitor.java,v 1.8 2005/06/11 13:13:15 eric Exp $
+/* $Id: VariableClassFileVisitor.java,v 1.8.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/classfile/visitor/VariableMemberInfoVisitor.java b/src/proguard/classfile/visitor/VariableMemberInfoVisitor.java
index a4d716a..5c7f85b 100644
--- a/src/proguard/classfile/visitor/VariableMemberInfoVisitor.java
+++ b/src/proguard/classfile/visitor/VariableMemberInfoVisitor.java
@@ -1,8 +1,8 @@
-/* $Id: VariableMemberInfoVisitor.java,v 1.12 2005/06/11 13:13:15 eric Exp $
+/* $Id: VariableMemberInfoVisitor.java,v 1.12.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ClassMemberSpecificationDialog.java b/src/proguard/gui/ClassMemberSpecificationDialog.java
index 3c121b5..e1d9048 100644
--- a/src/proguard/gui/ClassMemberSpecificationDialog.java
+++ b/src/proguard/gui/ClassMemberSpecificationDialog.java
@@ -1,8 +1,8 @@
-/* $Id: ClassMemberSpecificationDialog.java,v 1.5 2005/08/21 19:28:04 eric Exp $
+/* $Id: ClassMemberSpecificationDialog.java,v 1.5.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ClassMemberSpecificationsPanel.java b/src/proguard/gui/ClassMemberSpecificationsPanel.java
index 90154a4..871aa79 100644
--- a/src/proguard/gui/ClassMemberSpecificationsPanel.java
+++ b/src/proguard/gui/ClassMemberSpecificationsPanel.java
@@ -1,8 +1,8 @@
-/* $Id: ClassMemberSpecificationsPanel.java,v 1.7 2005/08/21 19:28:04 eric Exp $
+/* $Id: ClassMemberSpecificationsPanel.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ClassPathPanel.java b/src/proguard/gui/ClassPathPanel.java
index aa7ce86..69de554 100644
--- a/src/proguard/gui/ClassPathPanel.java
+++ b/src/proguard/gui/ClassPathPanel.java
@@ -1,8 +1,8 @@
-/* $Id: ClassPathPanel.java,v 1.16 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassPathPanel.java,v 1.16.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ClassSpecificationDialog.java b/src/proguard/gui/ClassSpecificationDialog.java
index 834b583..c63825c 100644
--- a/src/proguard/gui/ClassSpecificationDialog.java
+++ b/src/proguard/gui/ClassSpecificationDialog.java
@@ -1,8 +1,8 @@
-/* $Id: ClassSpecificationDialog.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassSpecificationDialog.java,v 1.4.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ClassSpecificationsPanel.java b/src/proguard/gui/ClassSpecificationsPanel.java
index 568c486..15cc007 100644
--- a/src/proguard/gui/ClassSpecificationsPanel.java
+++ b/src/proguard/gui/ClassSpecificationsPanel.java
@@ -1,8 +1,8 @@
-/* $Id: ClassSpecificationsPanel.java,v 1.5 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassSpecificationsPanel.java,v 1.5.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ExtensionFileFilter.java b/src/proguard/gui/ExtensionFileFilter.java
index 5b8ef1d..d5462aa 100644
--- a/src/proguard/gui/ExtensionFileFilter.java
+++ b/src/proguard/gui/ExtensionFileFilter.java
@@ -1,8 +1,8 @@
-/* $Id: ExtensionFileFilter.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: ExtensionFileFilter.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/FilterDialog.java b/src/proguard/gui/FilterDialog.java
index c92e28b..5d249b8 100644
--- a/src/proguard/gui/FilterDialog.java
+++ b/src/proguard/gui/FilterDialog.java
@@ -1,8 +1,8 @@
-/* $Id: FilterDialog.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: FilterDialog.java,v 1.4.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/GUIResources.java b/src/proguard/gui/GUIResources.java
index 8f895f3..b31c7df 100644
--- a/src/proguard/gui/GUIResources.java
+++ b/src/proguard/gui/GUIResources.java
@@ -1,8 +1,8 @@
-/* $Id: GUIResources.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: GUIResources.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/GUIResources.properties b/src/proguard/gui/GUIResources.properties
index d8880f3..69dbbd1 100644
--- a/src/proguard/gui/GUIResources.properties
+++ b/src/proguard/gui/GUIResources.properties
@@ -1,5 +1,5 @@
 # ProGuard -- shrinking, optimization, and obfuscation of Java class files.
-# Copyright (c) 1999-2005 Eric Lafortune (eric at graphics.cornell.edu)
+# Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
 
 #
 # Tab names.
@@ -24,7 +24,7 @@ obfuscation  = Obfuscation
 #
 # Panel titles.
 #
-welcome                       = Welcome to ProGuard, version 3.4
+welcome                       = Welcome to ProGuard, version 3.7
 options                       = Options
 keepAdditional                = Keep additional classes and class members
 keepNamesAdditional           = Keep additional class names and class member names
@@ -57,7 +57,7 @@ proGuardInfo = \
   \n\n\
   Distributed under the GNU General Public License.\
   \n\
-  Copyright (c) 1999-2005.
+  Copyright (c) 1999-2006.
 
 processingInfo = \
   You can now start processing your code, \
@@ -91,6 +91,7 @@ printMapping                     = Print mapping
 applyMapping                     = Apply mapping
 obfuscationDictionary            = Obfuscation dictionary
 overloadAggressively             = Overload aggressively
+useUniqueClassMemberNames        = Use unique class member names
 defaultPackage                   = Default package
 useMixedCaseClassNames           = Use mixed-case class names
 keepAttributes                   = Keep attributes
@@ -118,6 +119,8 @@ boilerplate_enumerations        = Enumerations
 boilerplate_serialization_code  = Serialization code
 boilerplate_beaninfo_classes    = BeanInfo classes
 boilerplate_bean_classes        = Bean classes
+boilerplate_database_drivers    = Database drivers
+boilerplate_swing_ui_l&f        = Swing UI L&F
 boilerplate_rmi_interfaces      = RMI interfaces
 boilerplate_rmi_implementations = RMI implementations
 
diff --git a/src/proguard/gui/ListPanel.java b/src/proguard/gui/ListPanel.java
index 8dffcd1..d1f2fa1 100644
--- a/src/proguard/gui/ListPanel.java
+++ b/src/proguard/gui/ListPanel.java
@@ -1,8 +1,8 @@
-/* $Id: ListPanel.java,v 1.9 2005/06/11 13:13:15 eric Exp $
+/* $Id: ListPanel.java,v 1.9.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/MessageDialogRunnable.java b/src/proguard/gui/MessageDialogRunnable.java
index 323a38f..a08be38 100644
--- a/src/proguard/gui/MessageDialogRunnable.java
+++ b/src/proguard/gui/MessageDialogRunnable.java
@@ -1,8 +1,8 @@
-/* $Id: MessageDialogRunnable.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: MessageDialogRunnable.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ProGuardGUI.java b/src/proguard/gui/ProGuardGUI.java
index ecabbaa..0954e57 100644
--- a/src/proguard/gui/ProGuardGUI.java
+++ b/src/proguard/gui/ProGuardGUI.java
@@ -1,8 +1,8 @@
-/* $Id: ProGuardGUI.java,v 1.35 2005/08/21 20:25:33 eric Exp $
+/* $Id: ProGuardGUI.java,v 1.35.2.2 2006/06/07 22:36:52 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -93,6 +93,7 @@ public class ProGuardGUI extends JFrame
     private JCheckBox applyMappingCheckBox                     = new JCheckBox(msg("applyMapping"));
     private JCheckBox obfuscationDictionaryCheckBox            = new JCheckBox(msg("obfuscationDictionary"));
     private JCheckBox overloadAggressivelyCheckBox             = new JCheckBox(msg("overloadAggressively"));
+    private JCheckBox useUniqueClassMemberNamesCheckBox        = new JCheckBox(msg("useUniqueClassMemberNames"));
     private JCheckBox defaultPackageCheckBox                   = new JCheckBox(msg("defaultPackage"));
     private JCheckBox useMixedCaseClassNamesCheckBox           = new JCheckBox(msg("useMixedCaseClassNames"));
     private JCheckBox keepAttributesCheckBox                   = new JCheckBox(msg("keepAttributes"));
@@ -338,24 +339,25 @@ public class ProGuardGUI extends JFrame
         JPanel obfuscationOptionsPanel = new JPanel(layout);
         addBorder(obfuscationOptionsPanel, "options");
 
-        obfuscationOptionsPanel.add(obfuscateCheckBox,                constraintsLastStretch);
-        obfuscationOptionsPanel.add(printMappingCheckBox,             constraints);
-        obfuscationOptionsPanel.add(printMappingTextField,            constraintsStretch);
-        obfuscationOptionsPanel.add(printMappingBrowseButton,         constraintsLast);
-        obfuscationOptionsPanel.add(applyMappingCheckBox,             constraints);
-        obfuscationOptionsPanel.add(applyMappingTextField,            constraintsStretch);
-        obfuscationOptionsPanel.add(applyMappingBrowseButton,         constraintsLast);
-        obfuscationOptionsPanel.add(obfuscationDictionaryCheckBox,    constraints);
-        obfuscationOptionsPanel.add(obfuscationDictionaryTextField,   constraintsStretch);
-        obfuscationOptionsPanel.add(obfucationDictionaryBrowseButton, constraintsLast);
-        obfuscationOptionsPanel.add(overloadAggressivelyCheckBox,     constraintsLastStretch);
-        obfuscationOptionsPanel.add(defaultPackageCheckBox,           constraints);
-        obfuscationOptionsPanel.add(defaultPackageTextField,          constraintsLastStretch);
-        obfuscationOptionsPanel.add(useMixedCaseClassNamesCheckBox,   constraintsLastStretch);
-        obfuscationOptionsPanel.add(keepAttributesCheckBox,           constraints);
-        obfuscationOptionsPanel.add(keepAttributesTextField,          constraintsLastStretch);
-        obfuscationOptionsPanel.add(newSourceFileAttributeCheckBox,   constraints);
-        obfuscationOptionsPanel.add(newSourceFileAttributeTextField,  constraintsLastStretch);
+        obfuscationOptionsPanel.add(obfuscateCheckBox,                 constraintsLastStretch);
+        obfuscationOptionsPanel.add(printMappingCheckBox,              constraints);
+        obfuscationOptionsPanel.add(printMappingTextField,             constraintsStretch);
+        obfuscationOptionsPanel.add(printMappingBrowseButton,          constraintsLast);
+        obfuscationOptionsPanel.add(applyMappingCheckBox,              constraints);
+        obfuscationOptionsPanel.add(applyMappingTextField,             constraintsStretch);
+        obfuscationOptionsPanel.add(applyMappingBrowseButton,          constraintsLast);
+        obfuscationOptionsPanel.add(obfuscationDictionaryCheckBox,     constraints);
+        obfuscationOptionsPanel.add(obfuscationDictionaryTextField,    constraintsStretch);
+        obfuscationOptionsPanel.add(obfucationDictionaryBrowseButton,  constraintsLast);
+        obfuscationOptionsPanel.add(overloadAggressivelyCheckBox,      constraintsLastStretch);
+        obfuscationOptionsPanel.add(useUniqueClassMemberNamesCheckBox, constraintsLastStretch);
+        obfuscationOptionsPanel.add(defaultPackageCheckBox,            constraints);
+        obfuscationOptionsPanel.add(defaultPackageTextField,           constraintsLastStretch);
+        obfuscationOptionsPanel.add(useMixedCaseClassNamesCheckBox,    constraintsLastStretch);
+        obfuscationOptionsPanel.add(keepAttributesCheckBox,            constraints);
+        obfuscationOptionsPanel.add(keepAttributesTextField,           constraintsLastStretch);
+        obfuscationOptionsPanel.add(newSourceFileAttributeCheckBox,    constraints);
+        obfuscationOptionsPanel.add(newSourceFileAttributeTextField,   constraintsLastStretch);
 
         JPanel obfuscationPanel = new JPanel(layout);
 
@@ -844,6 +846,7 @@ public class ProGuardGUI extends JFrame
         applyMappingCheckBox                    .setSelected(configuration.applyMapping != null);
         obfuscationDictionaryCheckBox           .setSelected(configuration.obfuscationDictionary != null);
         overloadAggressivelyCheckBox            .setSelected(configuration.overloadAggressively);
+        useUniqueClassMemberNamesCheckBox       .setSelected(configuration.useUniqueClassMemberNames);
         defaultPackageCheckBox                  .setSelected(configuration.defaultPackage != null);
         useMixedCaseClassNamesCheckBox          .setSelected(configuration.useMixedCaseClassNames);
         keepAttributesCheckBox                  .setSelected(configuration.keepAttributes != null);
@@ -977,6 +980,7 @@ public class ProGuardGUI extends JFrame
         configuration.applyMapping                     = applyMappingCheckBox                    .isSelected() ? new File(applyMappingTextField                     .getText()) : null;
         configuration.obfuscationDictionary            = obfuscationDictionaryCheckBox           .isSelected() ? new File(obfuscationDictionaryTextField            .getText()) : null;
         configuration.overloadAggressively             = overloadAggressivelyCheckBox            .isSelected();
+        configuration.useUniqueClassMemberNames        = useUniqueClassMemberNamesCheckBox       .isSelected();
         configuration.defaultPackage                   = defaultPackageCheckBox                  .isSelected() ?          defaultPackageTextField                   .getText()  : null;
         configuration.useMixedCaseClassNames           = useMixedCaseClassNamesCheckBox          .isSelected();
         configuration.keepAttributes                   = keepAttributesCheckBox                  .isSelected() ? ListUtil.commaSeparatedList(keepAttributesTextField.getText()) : null;
diff --git a/src/proguard/gui/ProGuardRunnable.java b/src/proguard/gui/ProGuardRunnable.java
index c75a636..acd075e 100644
--- a/src/proguard/gui/ProGuardRunnable.java
+++ b/src/proguard/gui/ProGuardRunnable.java
@@ -1,8 +1,8 @@
-/* $Id: ProGuardRunnable.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: ProGuardRunnable.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/ReTraceRunnable.java b/src/proguard/gui/ReTraceRunnable.java
index 960699b..5b7e620 100644
--- a/src/proguard/gui/ReTraceRunnable.java
+++ b/src/proguard/gui/ReTraceRunnable.java
@@ -1,8 +1,8 @@
-/* $Id: ReTraceRunnable.java,v 1.8 2005/06/11 13:13:15 eric Exp $
+/* $Id: ReTraceRunnable.java,v 1.8.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/SwingUtil.java b/src/proguard/gui/SwingUtil.java
index ddfca3a..044a03f 100644
--- a/src/proguard/gui/SwingUtil.java
+++ b/src/proguard/gui/SwingUtil.java
@@ -1,8 +1,8 @@
-/* $Id: SwingUtil.java,v 1.5 2005/06/11 13:13:15 eric Exp $
+/* $Id: SwingUtil.java,v 1.5.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/TabbedPane.java b/src/proguard/gui/TabbedPane.java
index e06aa80..a8f6adb 100644
--- a/src/proguard/gui/TabbedPane.java
+++ b/src/proguard/gui/TabbedPane.java
@@ -1,8 +1,8 @@
-/* $Id: TabbedPane.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: TabbedPane.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/TextAreaOutputStream.java b/src/proguard/gui/TextAreaOutputStream.java
index 2d42e4d..0d1675f 100644
--- a/src/proguard/gui/TextAreaOutputStream.java
+++ b/src/proguard/gui/TextAreaOutputStream.java
@@ -1,8 +1,8 @@
-/* $Id: TextAreaOutputStream.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: TextAreaOutputStream.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/boilerplate.pro b/src/proguard/gui/boilerplate.pro
index ee270c7..100d806 100644
--- a/src/proguard/gui/boilerplate.pro
+++ b/src/proguard/gui/boilerplate.pro
@@ -18,10 +18,11 @@
     public protected <methods>;
 }
 
-# Also keep - Enumerations. Keep a method that is required in enumeration
-# classes.
+# Also keep - Enumerations. Keep special static methods that are required in
+# enumeration classes.
 -keepclassmembers class * extends java.lang.Enum {
-    public **[] values();
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
 }
 
 # Also keep - Serialization code. Keep all fields and methods that are
@@ -56,6 +57,15 @@
     **   get*(int);
 }
 
+# Also keep - Database drivers. Keep any implementations of java.sql.Driver.
+-keep class * implements java.sql.Driver
+
+# Also keep - Swing UI L&F. Keep all classes that extend the ComponentUI class,
+# along with the special static method that is required.
+-keep class * extends javax.swing.plaf.ComponentUI {
+    public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent);
+}
+
 # Also keep - RMI interfaces. Keep all Remote interfaces and their methods.
 -keep interface * extends java.rmi.Remote {
     <methods>;
diff --git a/src/proguard/gui/default.pro b/src/proguard/gui/default.pro
index 540e6b7..a2038e5 100644
--- a/src/proguard/gui/default.pro
+++ b/src/proguard/gui/default.pro
@@ -14,10 +14,20 @@
     native <methods>;
 }
 
-# Also keep - Enumerations. Keep a method that is required in enumeration
-# classes.
+# Also keep - Enumerations. Keep special static methods that are required in
+# enumeration classes.
 -keepclassmembers class * extends java.lang.Enum {
-    public **[] values();
+    public static **[] values();
+    public static ** valueOf(java.lang.String);
+}
+
+# Also keep - Database drivers. Keep any implementations of java.sql.Driver.
+-keep class * implements java.sql.Driver
+
+# Also keep - Swing UI L&F. Keep all classes that extend the ComponentUI class,
+# along with the special static method that is required.
+-keep class * extends javax.swing.plaf.ComponentUI {
+    public static javax.swing.plaf.ComponentUI createUI(javax.swing.JComponent);
 }
 
 # Remove - System method calls. Remove all invocations of System
diff --git a/src/proguard/gui/splash/BufferedSprite.java b/src/proguard/gui/splash/BufferedSprite.java
index 2972056..190c5ca 100644
--- a/src/proguard/gui/splash/BufferedSprite.java
+++ b/src/proguard/gui/splash/BufferedSprite.java
@@ -1,8 +1,8 @@
-/* $Id: BufferedSprite.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: BufferedSprite.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/CircleSprite.java b/src/proguard/gui/splash/CircleSprite.java
index e3aa48f..2fa63c0 100644
--- a/src/proguard/gui/splash/CircleSprite.java
+++ b/src/proguard/gui/splash/CircleSprite.java
@@ -1,8 +1,8 @@
-/* $Id: CircleSprite.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: CircleSprite.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ClipSprite.java b/src/proguard/gui/splash/ClipSprite.java
index 6a6e9a5..a9693ff 100644
--- a/src/proguard/gui/splash/ClipSprite.java
+++ b/src/proguard/gui/splash/ClipSprite.java
@@ -1,8 +1,8 @@
-/* $Id: ClipSprite.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClipSprite.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/CompositeSprite.java b/src/proguard/gui/splash/CompositeSprite.java
index 1c9475d..09424d4 100644
--- a/src/proguard/gui/splash/CompositeSprite.java
+++ b/src/proguard/gui/splash/CompositeSprite.java
@@ -1,8 +1,8 @@
-/* $Id: CompositeSprite.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: CompositeSprite.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ImageSprite.java b/src/proguard/gui/splash/ImageSprite.java
index feecbe7..d7b14f9 100644
--- a/src/proguard/gui/splash/ImageSprite.java
+++ b/src/proguard/gui/splash/ImageSprite.java
@@ -1,8 +1,8 @@
-/* $Id: ImageSprite.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: ImageSprite.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/LinearColor.java b/src/proguard/gui/splash/LinearColor.java
index f450d69..bdafb2e 100644
--- a/src/proguard/gui/splash/LinearColor.java
+++ b/src/proguard/gui/splash/LinearColor.java
@@ -1,8 +1,8 @@
-/* $Id: LinearColor.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: LinearColor.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/LinearDouble.java b/src/proguard/gui/splash/LinearDouble.java
index c48b99f..e9fda12 100644
--- a/src/proguard/gui/splash/LinearDouble.java
+++ b/src/proguard/gui/splash/LinearDouble.java
@@ -1,8 +1,8 @@
-/* $Id: LinearDouble.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: LinearDouble.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/LinearInt.java b/src/proguard/gui/splash/LinearInt.java
index ca7cca4..69d3d9a 100644
--- a/src/proguard/gui/splash/LinearInt.java
+++ b/src/proguard/gui/splash/LinearInt.java
@@ -1,8 +1,8 @@
-/* $Id: LinearInt.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: LinearInt.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/LinearTiming.java b/src/proguard/gui/splash/LinearTiming.java
index d2d8197..270d3aa 100644
--- a/src/proguard/gui/splash/LinearTiming.java
+++ b/src/proguard/gui/splash/LinearTiming.java
@@ -1,8 +1,8 @@
-/* $Id: LinearTiming.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: LinearTiming.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/OverrideGraphics2D.java b/src/proguard/gui/splash/OverrideGraphics2D.java
index c3955f4..cf4ae7e 100644
--- a/src/proguard/gui/splash/OverrideGraphics2D.java
+++ b/src/proguard/gui/splash/OverrideGraphics2D.java
@@ -1,8 +1,8 @@
-/* $Id: OverrideGraphics2D.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: OverrideGraphics2D.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/RectangleSprite.java b/src/proguard/gui/splash/RectangleSprite.java
index 7f2006f..32244e9 100644
--- a/src/proguard/gui/splash/RectangleSprite.java
+++ b/src/proguard/gui/splash/RectangleSprite.java
@@ -1,8 +1,8 @@
-/* $Id: RectangleSprite.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: RectangleSprite.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/SawToothTiming.java b/src/proguard/gui/splash/SawToothTiming.java
index 96ff02e..4257a66 100644
--- a/src/proguard/gui/splash/SawToothTiming.java
+++ b/src/proguard/gui/splash/SawToothTiming.java
@@ -1,8 +1,8 @@
-/* $Id: SawToothTiming.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: SawToothTiming.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/ShadowedSprite.java b/src/proguard/gui/splash/ShadowedSprite.java
index 365482f..b292bde 100644
--- a/src/proguard/gui/splash/ShadowedSprite.java
+++ b/src/proguard/gui/splash/ShadowedSprite.java
@@ -1,8 +1,8 @@
-/* $Id: ShadowedSprite.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: ShadowedSprite.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/SineTiming.java b/src/proguard/gui/splash/SineTiming.java
index 1dabdab..762be91 100644
--- a/src/proguard/gui/splash/SineTiming.java
+++ b/src/proguard/gui/splash/SineTiming.java
@@ -1,8 +1,8 @@
-/* $Id: SineTiming.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: SineTiming.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/SmoothTiming.java b/src/proguard/gui/splash/SmoothTiming.java
index b31af7a..7287c90 100644
--- a/src/proguard/gui/splash/SmoothTiming.java
+++ b/src/proguard/gui/splash/SmoothTiming.java
@@ -1,8 +1,8 @@
-/* $Id: SmoothTiming.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: SmoothTiming.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/SplashPanel.java b/src/proguard/gui/splash/SplashPanel.java
index 505376e..fe75824 100644
--- a/src/proguard/gui/splash/SplashPanel.java
+++ b/src/proguard/gui/splash/SplashPanel.java
@@ -1,8 +1,8 @@
-/* $Id: SplashPanel.java,v 1.11 2005/06/11 13:13:15 eric Exp $
+/* $Id: SplashPanel.java,v 1.11.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/Sprite.java b/src/proguard/gui/splash/Sprite.java
index 18c66cc..0b75a3a 100644
--- a/src/proguard/gui/splash/Sprite.java
+++ b/src/proguard/gui/splash/Sprite.java
@@ -1,8 +1,8 @@
-/* $Id: Sprite.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: Sprite.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/TextSprite.java b/src/proguard/gui/splash/TextSprite.java
index 0090440..57eb1b7 100644
--- a/src/proguard/gui/splash/TextSprite.java
+++ b/src/proguard/gui/splash/TextSprite.java
@@ -1,8 +1,8 @@
-/* $Id: TextSprite.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: TextSprite.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/TimeSwitchSprite.java b/src/proguard/gui/splash/TimeSwitchSprite.java
index c84921f..92b8082 100644
--- a/src/proguard/gui/splash/TimeSwitchSprite.java
+++ b/src/proguard/gui/splash/TimeSwitchSprite.java
@@ -1,8 +1,8 @@
-/* $Id: TimeSwitchSprite.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: TimeSwitchSprite.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/Timing.java b/src/proguard/gui/splash/Timing.java
index 5fcc165..c64c8bd 100644
--- a/src/proguard/gui/splash/Timing.java
+++ b/src/proguard/gui/splash/Timing.java
@@ -1,8 +1,8 @@
-/* $Id: Timing.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: Timing.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/TypeWriterString.java b/src/proguard/gui/splash/TypeWriterString.java
index b8b2ff9..3495598 100644
--- a/src/proguard/gui/splash/TypeWriterString.java
+++ b/src/proguard/gui/splash/TypeWriterString.java
@@ -1,8 +1,8 @@
-/* $Id: TypeWriterString.java,v 1.7 2005/06/11 13:13:15 eric Exp $
+/* $Id: TypeWriterString.java,v 1.7.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableColor.java b/src/proguard/gui/splash/VariableColor.java
index c8b5b43..123924c 100644
--- a/src/proguard/gui/splash/VariableColor.java
+++ b/src/proguard/gui/splash/VariableColor.java
@@ -1,8 +1,8 @@
-/* $Id: VariableColor.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: VariableColor.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableDouble.java b/src/proguard/gui/splash/VariableDouble.java
index a795a2d..2872f60 100644
--- a/src/proguard/gui/splash/VariableDouble.java
+++ b/src/proguard/gui/splash/VariableDouble.java
@@ -1,8 +1,8 @@
-/* $Id: VariableDouble.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: VariableDouble.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableFont.java b/src/proguard/gui/splash/VariableFont.java
index f6aef05..35c6298 100644
--- a/src/proguard/gui/splash/VariableFont.java
+++ b/src/proguard/gui/splash/VariableFont.java
@@ -1,8 +1,8 @@
-/* $Id: VariableFont.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: VariableFont.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableInt.java b/src/proguard/gui/splash/VariableInt.java
index 59d6711..8bffb6d 100644
--- a/src/proguard/gui/splash/VariableInt.java
+++ b/src/proguard/gui/splash/VariableInt.java
@@ -1,8 +1,8 @@
-/* $Id: VariableInt.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: VariableInt.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableSizeFont.java b/src/proguard/gui/splash/VariableSizeFont.java
index 0455003..719efd0 100644
--- a/src/proguard/gui/splash/VariableSizeFont.java
+++ b/src/proguard/gui/splash/VariableSizeFont.java
@@ -1,8 +1,8 @@
-/* $Id: VariableSizeFont.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: VariableSizeFont.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/gui/splash/VariableString.java b/src/proguard/gui/splash/VariableString.java
index 6198160..340627b 100644
--- a/src/proguard/gui/splash/VariableString.java
+++ b/src/proguard/gui/splash/VariableString.java
@@ -1,8 +1,8 @@
-/* $Id: VariableString.java,v 1.6 2005/06/11 13:13:15 eric Exp $
+/* $Id: VariableString.java,v 1.6.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/CascadingDataEntryWriter.java b/src/proguard/io/CascadingDataEntryWriter.java
index f1d8ffe..a3a22de 100644
--- a/src/proguard/io/CascadingDataEntryWriter.java
+++ b/src/proguard/io/CascadingDataEntryWriter.java
@@ -1,8 +1,8 @@
-/* $Id: CascadingDataEntryWriter.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: CascadingDataEntryWriter.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/ClassFileFilter.java b/src/proguard/io/ClassFileFilter.java
index cd81dbf..fc37a10 100644
--- a/src/proguard/io/ClassFileFilter.java
+++ b/src/proguard/io/ClassFileFilter.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileFilter.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassFileFilter.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/ClassFileReader.java b/src/proguard/io/ClassFileReader.java
index a6e8ab5..fea012d 100644
--- a/src/proguard/io/ClassFileReader.java
+++ b/src/proguard/io/ClassFileReader.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileReader.java,v 1.6 2005/06/11 13:21:35 eric Exp $
+/* $Id: ClassFileReader.java,v 1.6.2.3 2006/11/26 15:29:20 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -21,7 +21,7 @@
 package proguard.io;
 
 import proguard.classfile.*;
-import proguard.classfile.util.ClassUtil;
+import proguard.classfile.util.*;
 import proguard.classfile.visitor.*;
 
 import java.io.*;
@@ -43,7 +43,7 @@ public class ClassFileReader implements DataEntryReader
     private boolean          isLibrary;
     private boolean          skipNonPublicLibraryClasses;
     private boolean          skipNonPublicLibraryClassMembers;
-    private boolean          note;
+    private WarningPrinter   warningPrinter;
     private ClassFileVisitor classFileVisitor;
 
 
@@ -54,13 +54,13 @@ public class ClassFileReader implements DataEntryReader
     public ClassFileReader(boolean          isLibrary,
                            boolean          skipNonPublicLibraryClasses,
                            boolean          skipNonPublicLibraryClassMembers,
-                           boolean          note,
+                           WarningPrinter   warningPrinter,
                            ClassFileVisitor classFileVisitor)
     {
         this.isLibrary                        = isLibrary;
         this.skipNonPublicLibraryClasses      = skipNonPublicLibraryClasses;
         this.skipNonPublicLibraryClassMembers = skipNonPublicLibraryClassMembers;
-        this.note                             = note;
+        this.warningPrinter                   = warningPrinter;
         this.classFileVisitor                 = classFileVisitor;
     }
 
@@ -85,10 +85,10 @@ public class ClassFileReader implements DataEntryReader
             // Apply the visitor.
             if (classFile != null)
             {
-                if (note &&
-                    !dataEntry.getName().equals(classFile.getName()+ClassConstants.CLASS_FILE_EXTENSION))
+                if (!dataEntry.getName().replace(File.pathSeparatorChar, ClassConstants.INTERNAL_PACKAGE_SEPARATOR).equals(classFile.getName()+ClassConstants.CLASS_FILE_EXTENSION) &&
+                    warningPrinter != null)
                 {
-                    System.err.println("Note: class file [" + dataEntry.getName() + "] unexpectedly contains class [" + ClassUtil.externalClassName(classFile.getName()) + "]");
+                    warningPrinter.print("Warning: class file [" + dataEntry.getName() + "] unexpectedly contains class [" + ClassUtil.externalClassName(classFile.getName()) + "]");
                 }
 
                 classFile.accept(classFileVisitor);
diff --git a/src/proguard/io/ClassFileRewriter.java b/src/proguard/io/ClassFileRewriter.java
index 4d95b35..51542a1 100644
--- a/src/proguard/io/ClassFileRewriter.java
+++ b/src/proguard/io/ClassFileRewriter.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileRewriter.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassFileRewriter.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntry.java b/src/proguard/io/DataEntry.java
index 28fb994..b1b8b2b 100644
--- a/src/proguard/io/DataEntry.java
+++ b/src/proguard/io/DataEntry.java
@@ -1,8 +1,8 @@
-/* $Id: DataEntry.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: DataEntry.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryCopier.java b/src/proguard/io/DataEntryCopier.java
index 125be44..9d8886f 100644
--- a/src/proguard/io/DataEntryCopier.java
+++ b/src/proguard/io/DataEntryCopier.java
@@ -1,8 +1,8 @@
-/* $Id: DataEntryCopier.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: DataEntryCopier.java,v 1.4.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryPump.java b/src/proguard/io/DataEntryPump.java
index afb813c..0558450 100644
--- a/src/proguard/io/DataEntryPump.java
+++ b/src/proguard/io/DataEntryPump.java
@@ -1,8 +1,8 @@
-/* $Id: DataEntryPump.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: DataEntryPump.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryReader.java b/src/proguard/io/DataEntryReader.java
index 7c456a9..497e91a 100644
--- a/src/proguard/io/DataEntryReader.java
+++ b/src/proguard/io/DataEntryReader.java
@@ -1,8 +1,8 @@
-/* $Id: DataEntryReader.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: DataEntryReader.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DataEntryWriter.java b/src/proguard/io/DataEntryWriter.java
index ee5ecaf..add4b00 100644
--- a/src/proguard/io/DataEntryWriter.java
+++ b/src/proguard/io/DataEntryWriter.java
@@ -1,8 +1,8 @@
-/* $Id: DataEntryWriter.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: DataEntryWriter.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/DirectoryPump.java b/src/proguard/io/DirectoryPump.java
index c3076b5..d39a4d7 100644
--- a/src/proguard/io/DirectoryPump.java
+++ b/src/proguard/io/DirectoryPump.java
@@ -1,8 +1,8 @@
-/* $Id: DirectoryPump.java,v 1.4 2005/08/21 20:24:12 eric Exp $
+/* $Id: DirectoryPump.java,v 1.4.2.2 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -49,7 +49,7 @@ public class DirectoryPump implements DataEntryPump
         {
             throw new IOException("No such file or directory");
         }
-        
+
         readFiles(directory, dataEntryReader);
     }
 
diff --git a/src/proguard/io/DirectoryWriter.java b/src/proguard/io/DirectoryWriter.java
index 1df75a6..664d66a 100644
--- a/src/proguard/io/DirectoryWriter.java
+++ b/src/proguard/io/DirectoryWriter.java
@@ -1,8 +1,8 @@
-/* $Id: DirectoryWriter.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: DirectoryWriter.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/FileDataEntry.java b/src/proguard/io/FileDataEntry.java
index 8250e91..2b5fe2c 100644
--- a/src/proguard/io/FileDataEntry.java
+++ b/src/proguard/io/FileDataEntry.java
@@ -1,8 +1,8 @@
-/* $Id: FileDataEntry.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: FileDataEntry.java,v 1.3.2.1 2006/01/16 22:57:55 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/FilteredDataEntryReader.java b/src/proguard/io/FilteredDataEntryReader.java
index 6e82a04..60842ae 100644
--- a/src/proguard/io/FilteredDataEntryReader.java
+++ b/src/proguard/io/FilteredDataEntryReader.java
@@ -1,8 +1,8 @@
-/* $Id: FilteredDataEntryReader.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: FilteredDataEntryReader.java,v 1.3.2.2 2006/11/26 15:29:20 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -78,19 +78,13 @@ public class FilteredDataEntryReader implements DataEntryReader
     public void read(DataEntry dataEntry)
     throws IOException
     {
-        if (dataEntryFilter.accepts(dataEntry))
-        {
-            if (acceptedDataEntryReader != null)
-            {
-                acceptedDataEntryReader.read(dataEntry);
-            }
-        }
-        else
+        DataEntryReader dataEntryReader = dataEntryFilter.accepts(dataEntry) ?
+            acceptedDataEntryReader :
+            rejectedDataEntryReader;
+
+        if (dataEntryReader != null)
         {
-            if (rejectedDataEntryReader != null)
-            {
-                rejectedDataEntryReader.read(dataEntry);
-            }
+            dataEntryReader.read(dataEntry);
         }
     }
 }
diff --git a/src/proguard/io/FilteredDataEntryWriter.java b/src/proguard/io/FilteredDataEntryWriter.java
index e6bfb0c..77da91a 100644
--- a/src/proguard/io/FilteredDataEntryWriter.java
+++ b/src/proguard/io/FilteredDataEntryWriter.java
@@ -1,8 +1,8 @@
-/* $Id: FilteredDataEntryWriter.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: FilteredDataEntryWriter.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/Finisher.java b/src/proguard/io/Finisher.java
index 9538136..3cdfbcd 100644
--- a/src/proguard/io/Finisher.java
+++ b/src/proguard/io/Finisher.java
@@ -1,8 +1,8 @@
-/* $Id: Finisher.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: Finisher.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/JarReader.java b/src/proguard/io/JarReader.java
index 388a565..4be0588 100644
--- a/src/proguard/io/JarReader.java
+++ b/src/proguard/io/JarReader.java
@@ -1,8 +1,8 @@
-/* $Id: JarReader.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: JarReader.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/JarWriter.java b/src/proguard/io/JarWriter.java
index 7f79e51..f675566 100644
--- a/src/proguard/io/JarWriter.java
+++ b/src/proguard/io/JarWriter.java
@@ -1,8 +1,8 @@
-/* $Id: JarWriter.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: JarWriter.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/ParentDataEntryWriter.java b/src/proguard/io/ParentDataEntryWriter.java
index 874f367..b50feea 100644
--- a/src/proguard/io/ParentDataEntryWriter.java
+++ b/src/proguard/io/ParentDataEntryWriter.java
@@ -1,8 +1,8 @@
-/* $Id: ParentDataEntryWriter.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: ParentDataEntryWriter.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/RenamedDataEntry.java b/src/proguard/io/RenamedDataEntry.java
index cfc6864..1ea9ce0 100644
--- a/src/proguard/io/RenamedDataEntry.java
+++ b/src/proguard/io/RenamedDataEntry.java
@@ -1,8 +1,8 @@
-/* $Id: RenamedDataEntry.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: RenamedDataEntry.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/io/ZipDataEntry.java b/src/proguard/io/ZipDataEntry.java
index 352d135..f1de752 100644
--- a/src/proguard/io/ZipDataEntry.java
+++ b/src/proguard/io/ZipDataEntry.java
@@ -1,8 +1,8 @@
-/* $Id: ZipDataEntry.java,v 1.4 2005/06/11 13:13:15 eric Exp $
+/* $Id: ZipDataEntry.java,v 1.4.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/AttributeShrinker.java b/src/proguard/obfuscate/AttributeShrinker.java
index 5e80339..d125a44 100644
--- a/src/proguard/obfuscate/AttributeShrinker.java
+++ b/src/proguard/obfuscate/AttributeShrinker.java
@@ -1,8 +1,8 @@
-/* $Id: AttributeShrinker.java,v 1.17 2005/06/11 13:13:15 eric Exp $
+/* $Id: AttributeShrinker.java,v 1.17.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/AttributeUsageMarker.java b/src/proguard/obfuscate/AttributeUsageMarker.java
index 102c1a2..836d4eb 100644
--- a/src/proguard/obfuscate/AttributeUsageMarker.java
+++ b/src/proguard/obfuscate/AttributeUsageMarker.java
@@ -1,8 +1,8 @@
-/* $Id: AttributeUsageMarker.java,v 1.24 2005/06/11 13:13:15 eric Exp $
+/* $Id: AttributeUsageMarker.java,v 1.24.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/ClassFileObfuscator.java b/src/proguard/obfuscate/ClassFileObfuscator.java
index dd65f96..b5e927b 100644
--- a/src/proguard/obfuscate/ClassFileObfuscator.java
+++ b/src/proguard/obfuscate/ClassFileObfuscator.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileObfuscator.java,v 1.24 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassFileObfuscator.java,v 1.24.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/ClassFileOpener.java b/src/proguard/obfuscate/ClassFileOpener.java
index 133ec94..cc18bb8 100644
--- a/src/proguard/obfuscate/ClassFileOpener.java
+++ b/src/proguard/obfuscate/ClassFileOpener.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileOpener.java,v 1.2 2005/06/11 13:13:15 eric Exp $
+/* $Id: ClassFileOpener.java,v 1.2.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/ClassFileRenamer.java b/src/proguard/obfuscate/ClassFileRenamer.java
index 0a3c856..8814eea 100644
--- a/src/proguard/obfuscate/ClassFileRenamer.java
+++ b/src/proguard/obfuscate/ClassFileRenamer.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileRenamer.java,v 1.42 2005/06/25 22:06:31 eric Exp $
+/* $Id: ClassFileRenamer.java,v 1.42.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/DictionaryNameFactory.java b/src/proguard/obfuscate/DictionaryNameFactory.java
index 4ef37eb..33f507b 100644
--- a/src/proguard/obfuscate/DictionaryNameFactory.java
+++ b/src/proguard/obfuscate/DictionaryNameFactory.java
@@ -1,8 +1,8 @@
-/* $Id: DictionaryNameFactory.java,v 1.3 2005/06/11 13:13:15 eric Exp $
+/* $Id: DictionaryNameFactory.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MapCleaner.java b/src/proguard/obfuscate/MapCleaner.java
index a123e76..2480245 100644
--- a/src/proguard/obfuscate/MapCleaner.java
+++ b/src/proguard/obfuscate/MapCleaner.java
@@ -1,8 +1,8 @@
-/* $Id: MapCleaner.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: MapCleaner.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MappingKeeper.java b/src/proguard/obfuscate/MappingKeeper.java
index 6c77290..32602c5 100644
--- a/src/proguard/obfuscate/MappingKeeper.java
+++ b/src/proguard/obfuscate/MappingKeeper.java
@@ -1,8 +1,8 @@
-/* $Id: MappingKeeper.java,v 1.10 2005/06/11 13:13:16 eric Exp $
+/* $Id: MappingKeeper.java,v 1.10.2.2 2006/11/25 16:56:11 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -21,7 +21,7 @@
 package proguard.obfuscate;
 
 import proguard.classfile.*;
-import proguard.classfile.util.ClassUtil;
+import proguard.classfile.util.*;
 
 
 /**
@@ -32,7 +32,8 @@ import proguard.classfile.util.ClassUtil;
  */
 public class MappingKeeper implements MappingProcessor
 {
-    private ClassPool classPool;
+    private ClassPool      classPool;
+    private WarningPrinter warningPrinter;
 
     // A field acting as a parameter.
     private ClassFile classFile;
@@ -40,12 +41,16 @@ public class MappingKeeper implements MappingProcessor
 
     /**
      * Creates a new MappingKeeper.
-     * @param classPool the class pool in which class names and class member names
-     *                  have to be mapped.
+     * @param classPool      the class pool in which class names and class
+     *                       member names have to be mapped.
+     * @param warningPrinter the optional warning printer to which warnings
+     *                       can be printed.
      */
-    public MappingKeeper(ClassPool classPool)
+    public MappingKeeper(ClassPool      classPool,
+                         WarningPrinter warningPrinter)
     {
-        this.classPool = classPool;
+        this.classPool      = classPool;
+        this.warningPrinter = warningPrinter;
     }
 
 
@@ -60,9 +65,26 @@ public class MappingKeeper implements MappingProcessor
         classFile = classPool.getClass(name);
         if (classFile != null)
         {
-            // Make sure the mapping name will be kept.
             String newName = ClassUtil.internalClassName(newClassName);
 
+            // Print out a warning if the mapping conflicts with a name that
+            // was set before.
+            if (warningPrinter != null)
+            {
+                String currentNewName = ClassFileObfuscator.newClassName(classFile);
+                if (currentNewName != null &&
+                    !currentNewName.equals(newName))
+                {
+                    warningPrinter.print("Warning: " +
+                                         className +
+                                         " is not being kept as '" +
+                                         ClassUtil.externalClassName(currentNewName) +
+                                         "', but remapped to '" +
+                                         newClassName + "'");
+                }
+            }
+
+            // Make sure the mapping name will be kept.
             ClassFileObfuscator.setNewClassName(classFile, newName);
 
             // The class members have to be kept as well.
@@ -87,6 +109,22 @@ public class MappingKeeper implements MappingProcessor
             FieldInfo fieldInfo = classFile.findField(name, descriptor);
             if (fieldInfo != null)
             {
+                // Print out a warning if the mapping conflicts with a name that
+                // was set before.
+                if (warningPrinter != null)
+                {
+                    String currentNewName = MemberInfoObfuscator.newMemberName(fieldInfo);
+                    if (currentNewName != null &&
+                        !currentNewName.equals(newFieldName))
+                    {
+                        warningPrinter.print("Warning: " +
+                                             className +
+                                             ": field '" + fieldType + " " + fieldName +
+                                             "' is not being kept as '" + currentNewName +
+                                             "', but remapped to '" + newFieldName + "'");
+                    }
+                }
+
                 // Make sure the mapping name will be kept.
                 MemberInfoObfuscator.setFixedNewMemberName(fieldInfo, newFieldName);
             }
@@ -111,6 +149,22 @@ public class MappingKeeper implements MappingProcessor
             MethodInfo methodInfo = classFile.findMethod(name, descriptor);
             if (methodInfo != null)
             {
+                // Print out a warning if the mapping conflicts with a name that
+                // was set before.
+                if (warningPrinter != null)
+                {
+                    String currentNewName = MemberInfoObfuscator.newMemberName(methodInfo);
+                    if (currentNewName != null &&
+                        !currentNewName.equals(newMethodName))
+                    {
+                        warningPrinter.print("Warning: " +
+                                             className +
+                                             ": method '" + methodReturnType + " " + methodNameAndArguments +
+                                             "' is not being kept as '" + currentNewName +
+                                             "', but remapped to '" + newMethodName + "'");
+                    }
+                }
+
                 // Make sure the mapping name will be kept.
                 MemberInfoObfuscator.setFixedNewMemberName(methodInfo, newMethodName);
             }
diff --git a/src/proguard/obfuscate/MappingPrinter.java b/src/proguard/obfuscate/MappingPrinter.java
index c7639fd..d4a1145 100644
--- a/src/proguard/obfuscate/MappingPrinter.java
+++ b/src/proguard/obfuscate/MappingPrinter.java
@@ -1,8 +1,8 @@
-/* $Id: MappingPrinter.java,v 1.19 2005/06/25 22:06:06 eric Exp $
+/* $Id: MappingPrinter.java,v 1.19.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MappingProcessor.java b/src/proguard/obfuscate/MappingProcessor.java
index e700036..b5b3272 100644
--- a/src/proguard/obfuscate/MappingProcessor.java
+++ b/src/proguard/obfuscate/MappingProcessor.java
@@ -1,8 +1,8 @@
-/* $Id: MappingProcessor.java,v 1.5 2005/06/11 13:13:16 eric Exp $
+/* $Id: MappingProcessor.java,v 1.5.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MappingReader.java b/src/proguard/obfuscate/MappingReader.java
index 4b358fd..f5fb978 100644
--- a/src/proguard/obfuscate/MappingReader.java
+++ b/src/proguard/obfuscate/MappingReader.java
@@ -1,8 +1,8 @@
-/* $Id: MappingReader.java,v 1.10 2005/06/11 13:13:16 eric Exp $
+/* $Id: MappingReader.java,v 1.10.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MemberInfoNameCleaner.java b/src/proguard/obfuscate/MemberInfoNameCleaner.java
index 8e563dc..add4264 100644
--- a/src/proguard/obfuscate/MemberInfoNameCleaner.java
+++ b/src/proguard/obfuscate/MemberInfoNameCleaner.java
@@ -1,8 +1,8 @@
-/* $Id: MemberInfoNameCleaner.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: MemberInfoNameCleaner.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MemberInfoNameCollector.java b/src/proguard/obfuscate/MemberInfoNameCollector.java
index ab887b3..bc4e49a 100644
--- a/src/proguard/obfuscate/MemberInfoNameCollector.java
+++ b/src/proguard/obfuscate/MemberInfoNameCollector.java
@@ -1,8 +1,8 @@
-/* $Id: MemberInfoNameCollector.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: MemberInfoNameCollector.java,v 1.3.2.2 2006/06/07 22:36:52 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -21,17 +21,16 @@
 package proguard.obfuscate;
 
 import proguard.classfile.*;
-import proguard.classfile.visitor.*;
-
-import java.io.IOException;
-import java.util.*;
+import proguard.classfile.util.MethodInfoLinker;
+import proguard.classfile.visitor.MemberInfoVisitor;
 
+import java.util.Map;
 
 /**
  * This MemberInfoVisitor collects all new (obfuscation) names of the members
  * that it visits.
  *
- * @see MemberInfoLinker
+ * @see MethodInfoLinker
  * @see MemberInfoObfuscator
  *
  * @author Eric Lafortune
@@ -118,14 +117,14 @@ public class MemberInfoNameCollector implements MemberInfoVisitor
 
             // Put the [descriptor - new name] in the map,
             // creating a new [new name - old name] map if necessary.
-            Map newNameMap = MemberInfoObfuscator.retrieveNameMap(descriptorMap, descriptor);
+            Map nameMap = MemberInfoObfuscator.retrieveNameMap(descriptorMap, descriptor);
 
             // Is the other original name different from this original name?
-            if (newNameMap.get(newName) == null ||
+            if (nameMap.get(newName) == null ||
                 MemberInfoObfuscator.hasFixedNewMemberName(memberInfo))
             {
                 // Remember not to use the new name again in this name space.
-                newNameMap.put(newName, name);
+                nameMap.put(newName, name);
             }
         }
     }
diff --git a/src/proguard/obfuscate/MemberInfoNameConflictFilter.java b/src/proguard/obfuscate/MemberInfoNameConflictFilter.java
index 7a8ef62..880fd4b 100644
--- a/src/proguard/obfuscate/MemberInfoNameConflictFilter.java
+++ b/src/proguard/obfuscate/MemberInfoNameConflictFilter.java
@@ -1,8 +1,8 @@
-/* $Id: MemberInfoNameConflictFilter.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: MemberInfoNameConflictFilter.java,v 1.3.2.2 2006/11/25 16:56:11 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -30,7 +30,6 @@ import java.util.*;
  * <code>MemberInfoVisitor</code>, but only when the visited member has been
  * marked as having a conflicting name.
  *
- * @see MemberInfoLinker
  * @see MemberInfoObfuscator
  *
  * @author Eric Lafortune
diff --git a/src/proguard/obfuscate/MemberInfoObfuscator.java b/src/proguard/obfuscate/MemberInfoObfuscator.java
index a693363..cb54d59 100644
--- a/src/proguard/obfuscate/MemberInfoObfuscator.java
+++ b/src/proguard/obfuscate/MemberInfoObfuscator.java
@@ -1,8 +1,8 @@
-/* $Id: MemberInfoObfuscator.java,v 1.14 2005/06/11 13:13:16 eric Exp $
+/* $Id: MemberInfoObfuscator.java,v 1.14.2.3 2006/11/25 16:56:11 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -21,7 +21,7 @@
 package proguard.obfuscate;
 
 import proguard.classfile.*;
-import proguard.classfile.util.MethodInfoLinker;
+import proguard.classfile.util.*;
 import proguard.classfile.visitor.MemberInfoVisitor;
 
 import java.util.*;
@@ -30,6 +30,7 @@ import java.util.*;
  * This MemberInfoVisitor obfuscates all class members that it visits.
  * It uses names from the given name factory. At the same time, it avoids names
  * from the given descriptor map.
+ * <p>
  * The class members must have been linked before applying this visitor.
  *
  * @see MethodInfoLinker
@@ -38,9 +39,10 @@ import java.util.*;
  */
 public class MemberInfoObfuscator implements MemberInfoVisitor
 {
-    private boolean     allowAggressiveOverloading;
-    private NameFactory nameFactory;
-    private Map         descriptorMap;
+    private boolean        allowAggressiveOverloading;
+    private NameFactory    nameFactory;
+    private Map            descriptorMap;
+    private WarningPrinter warningPrinter;
 
 
     /**
@@ -49,16 +51,21 @@ public class MemberInfoObfuscator implements MemberInfoVisitor
      *                                   members can be overloaded aggressively.
      * @param nameFactory                the factory that can produce
      *                                   obfuscated member names.
-     * @param descriptorMap              the map of names to avoid:
-     *                                   [member descriptor - new name - old name].
+     * @param descriptorMap              the map of descriptors to
+     *                                   [new name - old name] maps.
+     * @param warningPrinter             an optional warning printer to which
+     *                                   warnings about conflicting name
+     *                                   mappings can be printed.
      */
-    public MemberInfoObfuscator(boolean     allowAggressiveOverloading,
-                                NameFactory nameFactory,
-                                Map         descriptorMap)
+    public MemberInfoObfuscator(boolean        allowAggressiveOverloading,
+                                NameFactory    nameFactory,
+                                Map            descriptorMap,
+                                WarningPrinter warningPrinter)
     {
         this.allowAggressiveOverloading = allowAggressiveOverloading;
         this.nameFactory                = nameFactory;
         this.descriptorMap              = descriptorMap;
+        this.warningPrinter             = warningPrinter;
     }
 
 
@@ -68,7 +75,7 @@ public class MemberInfoObfuscator implements MemberInfoVisitor
 
     public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo)
     {
-        visitMemberInfo(programClassFile, programFieldInfo);
+        visitMemberInfo(programClassFile, programFieldInfo, true);
     }
 
 
@@ -83,7 +90,7 @@ public class MemberInfoObfuscator implements MemberInfoVisitor
             return;
         }
 
-        visitMemberInfo(programClassFile, programMethodInfo);
+        visitMemberInfo(programClassFile, programMethodInfo, false);
     }
 
 
@@ -92,11 +99,14 @@ public class MemberInfoObfuscator implements MemberInfoVisitor
 
 
     /**
-     * Inserts the given class member into the main map.
+     * Obfuscates the given class member.
      * @param classFile  the class file of the given member.
-     * @param memberInfo the class member to be linked.
+     * @param memberInfo the class member to be obfuscated.
+     * @param isField    speficies whether the class member is a field.
      */
-    private void visitMemberInfo(ClassFile classFile, MemberInfo memberInfo)
+    private void visitMemberInfo(ClassFile  classFile,
+                                 MemberInfo memberInfo,
+                                 boolean    isField)
     {
         // Get the member's name and descriptor.
         String name       = memberInfo.getName(classFile);
@@ -110,9 +120,8 @@ public class MemberInfoObfuscator implements MemberInfoVisitor
             descriptor = descriptor.substring(0, descriptor.indexOf(')')+1);
         }
 
-        // Put the [descriptor - new name] in the map,
-        // creating a new [new name - old name] map if necessary.
-        Map newNameMap = retrieveNameMap(descriptorMap, descriptor);
+        // Get the name map, creating a new one if necessary.
+        Map nameMap = retrieveNameMap(descriptorMap, descriptor);
 
         // Get the member's new name.
         String newName = newMemberName(memberInfo);
@@ -127,26 +136,44 @@ public class MemberInfoObfuscator implements MemberInfoVisitor
             {
                 newName = nameFactory.nextName();
             }
-            while (newNameMap.containsKey(newName));
+            while (nameMap.containsKey(newName));
+
+            // Remember not to use the new name again in this name space.
+            nameMap.put(newName, name);
 
             // Assign the new name.
             setNewMemberName(memberInfo, newName);
-
-            // Remember not to use the new name again in this name space.
-            newNameMap.put(newName, name);
         }
-        else if (!name.equals(newNameMap.get(newName)))
+        else
         {
-            // TODO: Preferentially keep the library method's name.
-            // TODO: Detect conflicting library member names.
-
-            // There's a conflict! A member (with a given old name) in a
-            // first namespace has received the same new name as this
-            // member (with a different old name) in a second name space,
-            // and now these two have to live together in this name space.
-
-            // Mark the name as conflicting.
-            MemberInfoNameConflictFilter.markConflictingName(memberInfo);
+            String previousName = (String)nameMap.get(newName);
+            if (!name.equals(previousName))
+            {
+                // There's a conflict! A member (with a given old name) in a
+                // first namespace has received the same new name as this
+                // member (with a different old name) in a second name space,
+                // and now these two have to live together in this name space.
+                if (hasFixedNewMemberName(memberInfo) &&
+                    warningPrinter != null)
+                {
+                    descriptor = memberInfo.getDescriptor(classFile);
+                    warningPrinter.print("Warning: " + ClassUtil.externalClassName(classFile.getName()) +
+                                         (isField ?
+                                             ": field '" + ClassUtil.externalFullFieldDescription(0, name, descriptor) :
+                                             ": method '" + ClassUtil.externalFullMethodDescription(classFile.getName(), 0, name, descriptor)) +
+                                         "' can't be mapped to '" + newName +
+                                         "' because it would conflict with " +
+                                         (isField ?
+                                             "field '" :
+                                             "method '" ) + previousName +
+                                         "', which is already being mapped to '" + newName + "'");
+                }
+
+                // TODO: Preferentially keep the fixed name.
+
+                // Mark the name as conflicting.
+                MemberInfoNameConflictFilter.markConflictingName(memberInfo);
+            }
         }
     }
 
@@ -154,12 +181,11 @@ public class MemberInfoObfuscator implements MemberInfoVisitor
     // Small utility methods.
 
     /**
-     * Gets the [new name - old name] map, based on the given map
-     * [descriptor - new name - old name] and a given descriptor.
+     * Gets the name map, based on the given map and a given descriptor.
      * A new empty map is created if necessary.
      * @param descriptorMap the map of descriptors to [new name - old name] maps.
      * @param descriptor    the class member descriptor.
-     * @return the corresponding [new name - old name] map.
+     * @return the corresponding name map.
      */
     static Map retrieveNameMap(Map descriptorMap, String descriptor)
     {
@@ -211,7 +237,7 @@ public class MemberInfoObfuscator implements MemberInfoVisitor
 
     /**
      * Returns whether the new name of the given class member is fixed.
-     * @param memberInfo the given class member.
+     * @param memberInfo the class member.
      * @return whether its new name is fixed.
      */
     static boolean hasFixedNewMemberName(MemberInfo memberInfo)
diff --git a/src/proguard/obfuscate/MemberInfoSpecialNameFilter.java b/src/proguard/obfuscate/MemberInfoSpecialNameFilter.java
index e7c18ca..1267dbc 100644
--- a/src/proguard/obfuscate/MemberInfoSpecialNameFilter.java
+++ b/src/proguard/obfuscate/MemberInfoSpecialNameFilter.java
@@ -1,8 +1,8 @@
-/* $Id: MemberInfoSpecialNameFilter.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: MemberInfoSpecialNameFilter.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/MultiMappingProcessor.java b/src/proguard/obfuscate/MultiMappingProcessor.java
index 7f0c36d..69b591d 100644
--- a/src/proguard/obfuscate/MultiMappingProcessor.java
+++ b/src/proguard/obfuscate/MultiMappingProcessor.java
@@ -1,8 +1,8 @@
-/* $Id: MultiMappingProcessor.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: MultiMappingProcessor.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/NameAndTypeShrinker.java b/src/proguard/obfuscate/NameAndTypeShrinker.java
index 299f51d..b4c1cbb 100644
--- a/src/proguard/obfuscate/NameAndTypeShrinker.java
+++ b/src/proguard/obfuscate/NameAndTypeShrinker.java
@@ -1,8 +1,8 @@
-/* $Id: NameAndTypeShrinker.java,v 1.24 2005/06/11 13:13:16 eric Exp $
+/* $Id: NameAndTypeShrinker.java,v 1.24.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/NameAndTypeUsageMarker.java b/src/proguard/obfuscate/NameAndTypeUsageMarker.java
index 1d29836..b0b1c30 100644
--- a/src/proguard/obfuscate/NameAndTypeUsageMarker.java
+++ b/src/proguard/obfuscate/NameAndTypeUsageMarker.java
@@ -1,8 +1,8 @@
-/* $Id: NameAndTypeUsageMarker.java,v 1.14 2005/06/11 13:13:16 eric Exp $
+/* $Id: NameAndTypeUsageMarker.java,v 1.14.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/NameFactory.java b/src/proguard/obfuscate/NameFactory.java
index 1fc0d4d..2eff8e2 100644
--- a/src/proguard/obfuscate/NameFactory.java
+++ b/src/proguard/obfuscate/NameFactory.java
@@ -1,8 +1,8 @@
-/* $Id: NameFactory.java,v 1.14 2005/06/11 13:13:16 eric Exp $
+/* $Id: NameFactory.java,v 1.14.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/NameFactoryResetter.java b/src/proguard/obfuscate/NameFactoryResetter.java
index 0fa5ba0..6deb6f0 100644
--- a/src/proguard/obfuscate/NameFactoryResetter.java
+++ b/src/proguard/obfuscate/NameFactoryResetter.java
@@ -1,8 +1,8 @@
-/* $Id: NameFactoryResetter.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: NameFactoryResetter.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/NameMarker.java b/src/proguard/obfuscate/NameMarker.java
index 86fb925..056833a 100644
--- a/src/proguard/obfuscate/NameMarker.java
+++ b/src/proguard/obfuscate/NameMarker.java
@@ -1,8 +1,8 @@
-/* $Id: NameMarker.java,v 1.17 2005/08/13 20:57:55 eric Exp $
+/* $Id: NameMarker.java,v 1.17.2.2 2006/05/06 13:50:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -57,18 +57,12 @@ public class NameMarker
     public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo)
     {
         keepFieldName(programClassFile, programFieldInfo);
-
-        // Mark the class names referenced in the descriptor string.
-        programFieldInfo.referencedClassesAccept(this);
     }
 
 
     public void visitProgramMethodInfo(ProgramClassFile programClassFile, ProgramMethodInfo programMethodInfo)
     {
         keepMethodName(programClassFile, programMethodInfo);
-
-        // Mark the class names referenced in the descriptor string.
-        programMethodInfo.referencedClassesAccept(this);
     }
 
 
diff --git a/src/proguard/obfuscate/Obfuscator.java b/src/proguard/obfuscate/Obfuscator.java
index fd20eff..fa5066f 100644
--- a/src/proguard/obfuscate/Obfuscator.java
+++ b/src/proguard/obfuscate/Obfuscator.java
@@ -1,8 +1,8 @@
-/* $Id: Obfuscator.java,v 1.2 2005/07/30 12:14:27 eric Exp $
+/* $Id: Obfuscator.java,v 1.2.2.4 2006/11/25 16:56:11 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -24,7 +24,7 @@ package proguard.obfuscate;
 import proguard.*;
 import proguard.classfile.*;
 import proguard.classfile.editor.*;
-import proguard.classfile.util.MethodInfoLinker;
+import proguard.classfile.util.*;
 import proguard.classfile.visitor.*;
 
 import java.io.*;
@@ -69,9 +69,22 @@ public class Obfuscator
         programClassPool.classFilesAccept(new ClassFileCleaner());
         libraryClassPool.classFilesAccept(new ClassFileCleaner());
 
-        // Link all methods that should get the same names.
-        programClassPool.classFilesAccept(new BottomClassFileFilter(
-                                          new MethodInfoLinker()));
+        // Do the class member names have to correspond globally?
+        if (configuration.useUniqueClassMemberNames)
+        {
+            // Link all class members in all classes.
+            ClassFileVisitor memberInfoLinker =
+                new AllMemberInfoVisitor(new MethodInfoLinker());
+
+            programClassPool.classFilesAccept(memberInfoLinker);
+            libraryClassPool.classFilesAccept(memberInfoLinker);
+        }
+        else
+        {
+            // Link all non-private methods in all class hierarchies.
+            programClassPool.classFilesAccept(new BottomClassFileFilter(
+                                              new MethodInfoLinker()));
+        }
 
         // Create a visitor for marking the seeds.
         NameMarker nameMarker = new NameMarker();
@@ -98,22 +111,46 @@ public class Obfuscator
         // override the names of library classes and of library class members.
         if (configuration.applyMapping != null)
         {
-            MappingReader    reader = new MappingReader(configuration.applyMapping);
+            WarningPrinter warningPrinter = configuration.warn ?
+                new WarningPrinter(System.err) :
+                null;
+
+            MappingReader reader = new MappingReader(configuration.applyMapping);
+
             MappingProcessor keeper =
                 new MultiMappingProcessor(new MappingProcessor[]
                 {
-                    new MappingKeeper(programClassPool),
-                    new MappingKeeper(libraryClassPool),
+                    new MappingKeeper(programClassPool, warningPrinter),
+                    new MappingKeeper(libraryClassPool, null),
                 });
 
             reader.pump(keeper);
+
+            if (configuration.warn)
+            {
+                // Print out a summary of the warnings if necessary.
+                int mappingWarningCount = warningPrinter.getWarningCount();
+                if (mappingWarningCount > 0)
+                {
+                    System.err.println("Warning: there were " + mappingWarningCount +
+                                       " kept classes and class members that were remapped anyway.");
+                    System.err.println("         You should adapt your configuration or edit the mapping file.");
+
+                    if (!configuration.ignoreWarnings)
+                    {
+                        System.err.println("         If you are sure this remapping won't hurt,");
+                        System.err.println("         you could try your luck using the '-ignorewarnings' option.");
+                        throw new IOException("Please correct the above warnings first.");
+                    }
+                }
+            }
         }
 
         // Mark attributes that have to be kept.
         AttributeUsageMarker attributeUsageMarker = new AttributeUsageMarker();
         if (configuration.keepAttributes != null)
         {
-            if (configuration.keepAttributes.size() != 0)
+            if (!configuration.keepAttributes.isEmpty())
             {
                 attributeUsageMarker.setKeepAttributes(configuration.keepAttributes);
             }
@@ -127,69 +164,106 @@ public class Obfuscator
         // Remove the attributes that can be discarded.
         programClassPool.classFilesAccept(new AttributeShrinker());
 
-        // Come up with new names for all class files.
-        programClassPool.classFilesAccept(new ClassFileObfuscator(programClassPool,
-                                                                  configuration.defaultPackage,
-                                                                  configuration.useMixedCaseClassNames));
+        // Come up with new names for all classes.
+        programClassPool.classFilesAccept(
+            new ClassFileObfuscator(programClassPool,
+                                    configuration.defaultPackage,
+                                    configuration.useMixedCaseClassNames));
 
+        // Come up with new names for all class members.
         NameFactory nameFactory = new SimpleNameFactory();
 
         if (configuration.obfuscationDictionary != null)
         {
-            nameFactory = new DictionaryNameFactory(configuration.obfuscationDictionary, nameFactory);
+            nameFactory = new DictionaryNameFactory(configuration.obfuscationDictionary,
+                                                    nameFactory);
         }
 
-        Map descriptorMap = new HashMap();
-
-        // Come up with new names for all non-private class members.
-        programClassPool.classFilesAccept(
-            new BottomClassFileFilter(
-            new MultiClassFileVisitor(new ClassFileVisitor[]
-            {
-                // Collect all member names in this name space.
-                new ClassFileHierarchyTraveler(true, true, true, false,
-                new AllMemberInfoVisitor(
-                new MemberInfoNameCollector(configuration.overloadAggressively,
-                                            descriptorMap))),
-
-                // Assign new names to all non-private members in this name space.
-                new ClassFileHierarchyTraveler(true, true, true, false,
-                new AllMemberInfoVisitor(
-                new MemberInfoAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE,
-                new MemberInfoObfuscator(configuration.overloadAggressively,
-                                         nameFactory,
-                                         descriptorMap)))),
-
-                // Clear the collected names.
-                new MapCleaner(descriptorMap)
-            })));
+        WarningPrinter warningPrinter = configuration.warn ?
+            new WarningPrinter(System.err) :
+            null;
 
-        // Come up with new names for all private class members.
-        programClassPool.classFilesAccept(
-            new MultiClassFileVisitor(new ClassFileVisitor[]
-            {
-                // Collect all member names in this class.
-                new AllMemberInfoVisitor(
-                new MemberInfoNameCollector(configuration.overloadAggressively,
-                                            descriptorMap)),
+        // Maintain a map of names to avoid [descriptor - new name - old name].
+        Map descriptorMap = new HashMap();
 
-                // Collect all non-private member names higher up the hierarchy.
-                new ClassFileHierarchyTraveler(false, true, true, false,
+        // Do the class member names have to be globally unique?
+        if (configuration.useUniqueClassMemberNames)
+        {
+            // Collect all member names in all classes.
+            programClassPool.classFilesAccept(
                 new AllMemberInfoVisitor(
-                new MemberInfoAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE,
                 new MemberInfoNameCollector(configuration.overloadAggressively,
-                                            descriptorMap)))),
+                                            descriptorMap)));
 
-                // Assign new names to all private members in this class.
+            // Assign new names to all members in all classes.
+            programClassPool.classFilesAccept(
                 new AllMemberInfoVisitor(
-                new MemberInfoAccessFilter(ClassConstants.INTERNAL_ACC_PRIVATE, 0,
                 new MemberInfoObfuscator(configuration.overloadAggressively,
                                          nameFactory,
-                                         descriptorMap))),
-
-                // Clear the collected names.
-                new MapCleaner(descriptorMap)
-            }));
+                                         descriptorMap,
+                                         warningPrinter)));
+        }
+        else
+        {
+            // Come up with new names for all non-private class members.
+            programClassPool.classFilesAccept(
+                new MultiClassFileVisitor(new ClassFileVisitor[]
+                {
+                    // Collect all private member names in this class.
+                    new AllMemberInfoVisitor(
+                    new MemberInfoAccessFilter(ClassConstants.INTERNAL_ACC_PRIVATE, 0,
+                    new MemberInfoNameCollector(configuration.overloadAggressively,
+                                                descriptorMap))),
+
+                    // Collect all non-private member names anywhere in the hierarchy.
+                    new ClassFileHierarchyTraveler(true, false, false, true,
+                    new BottomClassFileFilter(
+                    new ClassFileHierarchyTraveler(true, true, true, false,
+                    new AllMemberInfoVisitor(
+                    new MemberInfoAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE,
+                    new MemberInfoNameCollector(configuration.overloadAggressively,
+                                                descriptorMap)))))),
+
+                    // Assign new names to all non-private members in this class.
+                    new AllMemberInfoVisitor(
+                    new MemberInfoAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE,
+                    new MemberInfoObfuscator(configuration.overloadAggressively,
+                                             nameFactory,
+                                             descriptorMap,
+                                             warningPrinter))),
+
+                    // Clear the collected names.
+                    new MapCleaner(descriptorMap)
+                }));
+
+            // Come up with new names for all private class members.
+            programClassPool.classFilesAccept(
+                new MultiClassFileVisitor(new ClassFileVisitor[]
+                {
+                    // Collect all member names in this class.
+                    new AllMemberInfoVisitor(
+                    new MemberInfoNameCollector(configuration.overloadAggressively,
+                                                descriptorMap)),
+
+                    // Collect all non-private member names higher up the hierarchy.
+                    new ClassFileHierarchyTraveler(false, true, true, false,
+                    new AllMemberInfoVisitor(
+                    new MemberInfoAccessFilter(0, ClassConstants.INTERNAL_ACC_PRIVATE,
+                    new MemberInfoNameCollector(configuration.overloadAggressively,
+                                                descriptorMap)))),
+
+                    // Assign new names to all private members in this class.
+                    new AllMemberInfoVisitor(
+                    new MemberInfoAccessFilter(ClassConstants.INTERNAL_ACC_PRIVATE, 0,
+                    new MemberInfoObfuscator(configuration.overloadAggressively,
+                                             nameFactory,
+                                             descriptorMap,
+                                             warningPrinter))),
+
+                    // Clear the collected names.
+                    new MapCleaner(descriptorMap)
+                }));
+        }
 
         // Some class members may have ended up with conflicting names.
         // Collect all special member names.
@@ -198,13 +272,15 @@ public class Obfuscator
             new MemberInfoSpecialNameFilter(
             new MemberInfoNameCollector(configuration.overloadAggressively,
                                         descriptorMap))));
+
         libraryClassPool.classFilesAccept(
             new AllMemberInfoVisitor(
             new MemberInfoSpecialNameFilter(
             new MemberInfoNameCollector(configuration.overloadAggressively,
                                         descriptorMap))));
 
-        // Replace the conflicting member names with special, globally unique names.
+        // Replace the conflicting member names with special, globally unique
+        // names.
         programClassPool.classFilesAccept(
             new AllMemberInfoVisitor(
             new MemberInfoNameConflictFilter(
@@ -213,10 +289,28 @@ public class Obfuscator
                 new MemberInfoNameCleaner(),
                 new MemberInfoObfuscator(configuration.overloadAggressively,
                                          new SpecialNameFactory(new SimpleNameFactory()),
-                                         descriptorMap),
+                                         descriptorMap,
+                                         warningPrinter),
             }))));
 
-        descriptorMap.clear();
+        // Print out any warnings about member name conflicts.
+        if (configuration.warn)
+        {
+            int warningCount = warningPrinter.getWarningCount();
+            if (warningCount > 0)
+            {
+                System.err.println("Warning: there were " + warningCount +
+                                   " conflicting class member name mappings.");
+                System.err.println("         Your configuration may be inconsistent.");
+
+                if (!configuration.ignoreWarnings)
+                {
+                    System.err.println("         If you are sure the conflicts are harmless,");
+                    System.err.println("         you could try your luck using the '-ignorewarnings' option.");
+                    throw new IOException("Please correct the above warnings first.");
+                }
+            }
+        }
 
         // Print out the mapping, if requested.
         if (configuration.printMapping != null)
@@ -239,8 +333,8 @@ public class Obfuscator
         libraryClassPool.classFilesAccept(new ClassFileRenamer());
 
         // Update all references to these new names.
-        programClassPool.classFilesAccept(new ClassFileReferenceFixer());
-        libraryClassPool.classFilesAccept(new ClassFileReferenceFixer());
+        programClassPool.classFilesAccept(new ClassFileReferenceFixer(false));
+        libraryClassPool.classFilesAccept(new ClassFileReferenceFixer(false));
         programClassPool.classFilesAccept(new MemberReferenceFixer(1024));
 
         // Make package visible elements public, if necessary.
diff --git a/src/proguard/obfuscate/SimpleNameFactory.java b/src/proguard/obfuscate/SimpleNameFactory.java
index bbfdb53..c28d79f 100644
--- a/src/proguard/obfuscate/SimpleNameFactory.java
+++ b/src/proguard/obfuscate/SimpleNameFactory.java
@@ -1,8 +1,8 @@
-/* $Id: SimpleNameFactory.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: SimpleNameFactory.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/SourceFileRenamer.java b/src/proguard/obfuscate/SourceFileRenamer.java
index 619a196..9e83f18 100644
--- a/src/proguard/obfuscate/SourceFileRenamer.java
+++ b/src/proguard/obfuscate/SourceFileRenamer.java
@@ -1,8 +1,8 @@
-/* $Id: SourceFileRenamer.java,v 1.2 2005/06/11 13:13:16 eric Exp $
+/* $Id: SourceFileRenamer.java,v 1.2.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/SpecialNameFactory.java b/src/proguard/obfuscate/SpecialNameFactory.java
index 90a3ae3..b911059 100644
--- a/src/proguard/obfuscate/SpecialNameFactory.java
+++ b/src/proguard/obfuscate/SpecialNameFactory.java
@@ -1,8 +1,8 @@
-/* $Id: SpecialNameFactory.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: SpecialNameFactory.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/Utf8Shrinker.java b/src/proguard/obfuscate/Utf8Shrinker.java
index 72dff91..6113cb1 100644
--- a/src/proguard/obfuscate/Utf8Shrinker.java
+++ b/src/proguard/obfuscate/Utf8Shrinker.java
@@ -1,8 +1,8 @@
-/* $Id: Utf8Shrinker.java,v 1.27 2005/06/11 13:13:16 eric Exp $
+/* $Id: Utf8Shrinker.java,v 1.27.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/obfuscate/Utf8UsageMarker.java b/src/proguard/obfuscate/Utf8UsageMarker.java
index fbc7c39..7b6dd1d 100644
--- a/src/proguard/obfuscate/Utf8UsageMarker.java
+++ b/src/proguard/obfuscate/Utf8UsageMarker.java
@@ -1,8 +1,8 @@
-/* $Id: Utf8UsageMarker.java,v 1.23 2005/06/11 13:13:16 eric Exp $
+/* $Id: Utf8UsageMarker.java,v 1.23.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/ChangedCodePrinter.java b/src/proguard/optimize/ChangedCodePrinter.java
index 013cb5f..e909002 100644
--- a/src/proguard/optimize/ChangedCodePrinter.java
+++ b/src/proguard/optimize/ChangedCodePrinter.java
@@ -1,8 +1,8 @@
-/* $Id: ChangedCodePrinter.java,v 1.7 2005/06/11 13:13:16 eric Exp $
+/* $Id: ChangedCodePrinter.java,v 1.7.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/KeepMarker.java b/src/proguard/optimize/KeepMarker.java
index 6024d1c..b29c5cc 100644
--- a/src/proguard/optimize/KeepMarker.java
+++ b/src/proguard/optimize/KeepMarker.java
@@ -1,4 +1,4 @@
-/* $Id: KeepMarker.java,v 1.7 2005/08/13 20:57:55 eric Exp $
+/* $Id: KeepMarker.java,v 1.7.2.3 2006/06/07 22:36:52 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
@@ -48,7 +48,10 @@ public class KeepMarker
     }
 
 
-    public void visitLibraryClassFile(LibraryClassFile libraryClassFile) {}
+    public void visitLibraryClassFile(LibraryClassFile libraryClassFile)
+    {
+        markAsKept(libraryClassFile);
+    }
 
 
     // Implementations for MemberInfoVisitor.
@@ -56,23 +59,25 @@ public class KeepMarker
     public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo)
     {
         markAsKept(programFieldInfo);
-
-        // Mark the classes referenced in the descriptor string.
-        programFieldInfo.referencedClassesAccept(this);
     }
 
 
     public void visitProgramMethodInfo(ProgramClassFile programClassFile, ProgramMethodInfo programMethodInfo)
     {
-        markAsKept(MethodInfoLinker.lastMethodInfo(programMethodInfo));
+        markAsKept(MethodInfoLinker.lastMemberInfo(programMethodInfo));
+    }
 
-        // Mark the classes referenced in the descriptor string.
-        programMethodInfo.referencedClassesAccept(this);
+
+    public void visitLibraryFieldInfo(LibraryClassFile libraryClassFile, LibraryFieldInfo libraryFieldInfo)
+    {
+        markAsKept(libraryFieldInfo);
     }
 
 
-    public void visitLibraryFieldInfo(LibraryClassFile libraryClassFile, LibraryFieldInfo libraryFieldInfo) {}
-    public void visitLibraryMethodInfo(LibraryClassFile libraryClassFile, LibraryMethodInfo libraryMethodInfo) {}
+    public void visitLibraryMethodInfo(LibraryClassFile libraryClassFile, LibraryMethodInfo libraryMethodInfo)
+    {
+        markAsKept(MethodInfoLinker.lastMemberInfo(libraryMethodInfo));
+    }
 
 
     // Small utility methods.
diff --git a/src/proguard/optimize/MethodOptimizationInfo.java b/src/proguard/optimize/MethodOptimizationInfo.java
index ecbe438..dd8bede 100644
--- a/src/proguard/optimize/MethodOptimizationInfo.java
+++ b/src/proguard/optimize/MethodOptimizationInfo.java
@@ -1,8 +1,8 @@
-/* $Id: MethodOptimizationInfo.java,v 1.4 2005/06/11 13:13:16 eric Exp $
+/* $Id: MethodOptimizationInfo.java,v 1.4.2.2 2006/06/07 22:36:52 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -99,13 +99,13 @@ public class MethodOptimizationInfo
 
     public static void setMethodOptimizationInfo(MethodInfo methodInfo)
     {
-        MethodInfoLinker.lastMethodInfo(methodInfo).setVisitorInfo(new MethodOptimizationInfo());
+        MethodInfoLinker.lastMemberInfo(methodInfo).setVisitorInfo(new MethodOptimizationInfo());
     }
 
 
     public static MethodOptimizationInfo getMethodOptimizationInfo(MethodInfo methodInfo)
     {
-        Object visitorInfo = MethodInfoLinker.lastMethodInfo(methodInfo).getVisitorInfo();
+        Object visitorInfo = MethodInfoLinker.lastMemberInfo(methodInfo).getVisitorInfo();
 
         return visitorInfo instanceof MethodOptimizationInfo ?
             (MethodOptimizationInfo)visitorInfo :
diff --git a/src/proguard/optimize/MethodOptimizationInfoSetter.java b/src/proguard/optimize/MethodOptimizationInfoSetter.java
index 6ca2d2f..eaeb562 100644
--- a/src/proguard/optimize/MethodOptimizationInfoSetter.java
+++ b/src/proguard/optimize/MethodOptimizationInfoSetter.java
@@ -1,8 +1,8 @@
-/* $Id: MethodOptimizationInfoSetter.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: MethodOptimizationInfoSetter.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/NoSideEffectMethodMarker.java b/src/proguard/optimize/NoSideEffectMethodMarker.java
index c5870d4..4714849 100644
--- a/src/proguard/optimize/NoSideEffectMethodMarker.java
+++ b/src/proguard/optimize/NoSideEffectMethodMarker.java
@@ -1,8 +1,8 @@
-/* $Id: NoSideEffectMethodMarker.java,v 1.5 2005/06/11 13:13:16 eric Exp $
+/* $Id: NoSideEffectMethodMarker.java,v 1.5.2.3 2006/06/07 22:36:52 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -21,8 +21,8 @@
 package proguard.optimize;
 
 import proguard.classfile.*;
-import proguard.classfile.instruction.*;
-import proguard.classfile.visitor.*;
+import proguard.classfile.util.MethodInfoLinker;
+import proguard.classfile.visitor.MemberInfoVisitor;
 
 /**
  * This MemberInfoVisitor marks all methods that it visits as not having any side
@@ -35,6 +35,11 @@ import proguard.classfile.visitor.*;
 public class NoSideEffectMethodMarker
   implements MemberInfoVisitor
 {
+    // A visitor info flag to indicate the visitor accepter is being kept,
+    // but that it doesn't have any side effects.
+    private static final Object KEPT_BUT_NO_SIDE_EFFECTS = new Object();
+
+
     // Implementations for MemberInfoVisitor.
 
     public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo) {}
@@ -62,11 +67,20 @@ public class NoSideEffectMethodMarker
         {
             info.setNoSideEffects();
         }
+        else
+        {
+            MethodInfoLinker.lastMemberInfo(methodInfo).setVisitorInfo(KEPT_BUT_NO_SIDE_EFFECTS);
+        }
     }
 
 
     public static boolean hasNoSideEffects(MethodInfo methodInfo)
     {
+        if (MethodInfoLinker.lastVisitorAccepter(methodInfo).getVisitorInfo() == KEPT_BUT_NO_SIDE_EFFECTS)
+        {
+            return true;
+        }
+
         MethodOptimizationInfo info = MethodOptimizationInfo.getMethodOptimizationInfo(methodInfo);
         return info != null &&
                info.hasNoSideEffects();
diff --git a/src/proguard/optimize/NonPrivateMethodMarker.java b/src/proguard/optimize/NonPrivateMethodMarker.java
index 74fbb36..6495525 100644
--- a/src/proguard/optimize/NonPrivateMethodMarker.java
+++ b/src/proguard/optimize/NonPrivateMethodMarker.java
@@ -1,8 +1,8 @@
-/* $Id: NonPrivateMethodMarker.java,v 1.7 2005/07/10 11:08:57 eric Exp $
+/* $Id: NonPrivateMethodMarker.java,v 1.7.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/Optimizer.java b/src/proguard/optimize/Optimizer.java
index bae56f6..f4e0859 100644
--- a/src/proguard/optimize/Optimizer.java
+++ b/src/proguard/optimize/Optimizer.java
@@ -1,8 +1,8 @@
-/* $Id: Optimizer.java,v 1.9 2005/10/22 11:55:29 eric Exp $
+/* $Id: Optimizer.java,v 1.9.2.4 2006/02/13 00:19:28 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -125,6 +125,20 @@ public class Optimizer
         programClassPool.accept(classPoolvisitor);
         libraryClassPool.accept(classPoolvisitor);
 
+        // All library classes and library class members remain unchanged.
+        libraryClassPool.classFilesAccept(keepMarker);
+        libraryClassPool.classFilesAccept(new AllMemberInfoVisitor(keepMarker));
+
+        // We also keep all classes that are involved in .class constructs.
+        programClassPool.classFilesAccept(new AllMethodVisitor(
+                                          new AllAttrInfoVisitor(
+                                          new AllInstructionVisitor(
+                                          new DotClassClassFileVisitor(keepMarker)))));
+
+        // We also keep all classes that are involved in Class.forName constructs.
+        programClassPool.classFilesAccept(new AllCpInfoVisitor(
+                                          new ClassForNameClassFileVisitor(keepMarker)));
+
         // Attach some optimization info to all methods, so it can be filled
         // out later.
         programClassPool.classFilesAccept(new AllMethodVisitor(
@@ -205,7 +219,7 @@ public class Optimizer
                                           new ParameterShrinker(1024, 64, parameterShrinkCounter, staticMethodCounter)));
 
         // Fix all references to class files.
-        programClassPool.classFilesAccept(new ClassFileReferenceFixer());
+        programClassPool.classFilesAccept(new ClassFileReferenceFixer(true));
 
         // Fix all references to class members.
         programClassPool.classFilesAccept(new MemberReferenceFixer(1024));
diff --git a/src/proguard/optimize/ParameterShrinker.java b/src/proguard/optimize/ParameterShrinker.java
index 97aa151..38a5752 100644
--- a/src/proguard/optimize/ParameterShrinker.java
+++ b/src/proguard/optimize/ParameterShrinker.java
@@ -1,8 +1,8 @@
-/* $Id: ParameterShrinker.java,v 1.6 2005/08/06 10:27:43 eric Exp $
+/* $Id: ParameterShrinker.java,v 1.6.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/ParameterUsageMarker.java b/src/proguard/optimize/ParameterUsageMarker.java
index ee8a7b6..3fc769a 100644
--- a/src/proguard/optimize/ParameterUsageMarker.java
+++ b/src/proguard/optimize/ParameterUsageMarker.java
@@ -1,8 +1,8 @@
-/* $Id: ParameterUsageMarker.java,v 1.4 2005/06/11 13:13:16 eric Exp $
+/* $Id: ParameterUsageMarker.java,v 1.4.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/SideEffectInstructionChecker.java b/src/proguard/optimize/SideEffectInstructionChecker.java
index 1eee8b4..0cdeed3 100644
--- a/src/proguard/optimize/SideEffectInstructionChecker.java
+++ b/src/proguard/optimize/SideEffectInstructionChecker.java
@@ -1,8 +1,8 @@
-/* $Id: SideEffectInstructionChecker.java,v 1.12 2005/06/11 13:13:16 eric Exp $
+/* $Id: SideEffectInstructionChecker.java,v 1.12.2.4 2006/04/17 02:19:37 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -41,6 +41,9 @@ public class SideEffectInstructionChecker
 {
     private boolean includeReturnInstructions;
 
+    // An argument for the visitor methods.
+    private boolean isReading;
+    
     // A return value for the visitor methods.
     private boolean hasSideEffects;
 
@@ -63,7 +66,6 @@ public class SideEffectInstructionChecker
 
     // Implementations for InstructionVisitor.
 
-    public void visitBranchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, BranchInstruction branchInstruction) {}
     public void visitTableSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, TableSwitchInstruction tableSwitchInstruction) {}
     public void visitLookUpSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, LookUpSwitchInstruction lookUpSwitchInstruction) {}
 
@@ -131,6 +133,20 @@ public class SideEffectInstructionChecker
     }
 
 
+    public void visitBranchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, BranchInstruction branchInstruction)
+    {
+        byte opcode = branchInstruction.opcode;
+
+        // Check for instructions that might cause side effects.
+        if (includeReturnInstructions &&
+            (opcode == InstructionConstants.OP_JSR ||
+             opcode == InstructionConstants.OP_JSR_W))
+        {
+            hasSideEffects = true;
+        }
+    }
+
+
     // Implementations for CpInfoVisitor.
 
     public void visitIntegerCpInfo(ClassFile classFile, IntegerCpInfo integerCpInfo) {}
@@ -145,7 +161,19 @@ public class SideEffectInstructionChecker
 
     public void visitFieldrefCpInfo(ClassFile classFile, FieldrefCpInfo fieldrefCpInfo)
     {
-        hasSideEffects = !WriteOnlyFieldMarker.isWriteOnly(fieldrefCpInfo.referencedMemberInfo);
+        MemberInfo referencedMember = fieldrefCpInfo.referencedMemberInfo;
+
+        // Do we have a reference to the field?
+        if (referencedMember == null)
+        {
+            // We'll have to assume accessing the unknown field has side effects.
+            hasSideEffects = true;
+        }
+        else
+        {
+            // Check the referenced field itself.
+            fieldrefCpInfo.referencedMemberInfoAccept(this);
+        }
     }
 
 
@@ -212,7 +240,13 @@ public class SideEffectInstructionChecker
 
     // Implementations for MemberInfoVisitor.
 
-    public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo) {}
+    public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo)
+    {
+        hasSideEffects = isReading ?
+            (programFieldInfo.getAccessFlags() & ClassConstants.INTERNAL_ACC_VOLATILE) != 0 :
+            !WriteOnlyFieldMarker.isWriteOnly(programFieldInfo);
+    }
+    
 
     public void visitProgramMethodInfo(ProgramClassFile programClassFile, ProgramMethodInfo programMethodInfo)
     {
@@ -221,7 +255,13 @@ public class SideEffectInstructionChecker
     }
 
 
-    public void visitLibraryFieldInfo(LibraryClassFile libraryClassFile, LibraryFieldInfo libraryFieldInfo) {}
+    public void visitLibraryFieldInfo(LibraryClassFile libraryClassFile, LibraryFieldInfo libraryFieldInfo)
+    {
+        hasSideEffects = isReading ?
+            (libraryFieldInfo.getAccessFlags() & ClassConstants.INTERNAL_ACC_VOLATILE) != 0 :
+            !WriteOnlyFieldMarker.isWriteOnly(libraryFieldInfo);
+    }
+        
 
     public void visitLibraryMethodInfo(LibraryClassFile libraryClassFile, LibraryMethodInfo libraryMethodInfo)
     {
diff --git a/src/proguard/optimize/SideEffectMethodMarker.java b/src/proguard/optimize/SideEffectMethodMarker.java
index 8f6068a..a1b19f0 100644
--- a/src/proguard/optimize/SideEffectMethodMarker.java
+++ b/src/proguard/optimize/SideEffectMethodMarker.java
@@ -1,8 +1,8 @@
-/* $Id: SideEffectMethodMarker.java,v 1.6 2005/06/11 13:13:16 eric Exp $
+/* $Id: SideEffectMethodMarker.java,v 1.6.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/VariableUsageMarker.java b/src/proguard/optimize/VariableUsageMarker.java
index b3f9858..ebbb83c 100644
--- a/src/proguard/optimize/VariableUsageMarker.java
+++ b/src/proguard/optimize/VariableUsageMarker.java
@@ -1,8 +1,8 @@
-/* $Id: VariableUsageMarker.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: VariableUsageMarker.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/WriteOnlyFieldFilter.java b/src/proguard/optimize/WriteOnlyFieldFilter.java
index 0ceccdd..87915c2 100644
--- a/src/proguard/optimize/WriteOnlyFieldFilter.java
+++ b/src/proguard/optimize/WriteOnlyFieldFilter.java
@@ -1,8 +1,8 @@
-/* $Id: WriteOnlyFieldFilter.java,v 1.1 2005/08/13 21:25:26 eric Exp $
+/* $Id: WriteOnlyFieldFilter.java,v 1.1.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/WriteOnlyFieldMarker.java b/src/proguard/optimize/WriteOnlyFieldMarker.java
index a054bca..ae3f25b 100644
--- a/src/proguard/optimize/WriteOnlyFieldMarker.java
+++ b/src/proguard/optimize/WriteOnlyFieldMarker.java
@@ -1,8 +1,8 @@
-/* $Id: WriteOnlyFieldMarker.java,v 1.7 2005/07/31 18:50:05 eric Exp $
+/* $Id: WriteOnlyFieldMarker.java,v 1.7.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/BranchUnit.java b/src/proguard/optimize/evaluation/BranchUnit.java
index 8f9a7ff..08c246f 100644
--- a/src/proguard/optimize/evaluation/BranchUnit.java
+++ b/src/proguard/optimize/evaluation/BranchUnit.java
@@ -1,8 +1,8 @@
-/* $Id: BranchUnit.java,v 1.4 2005/06/11 13:13:16 eric Exp $
+/* $Id: BranchUnit.java,v 1.4.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/EvaluationSimplifier.java b/src/proguard/optimize/evaluation/EvaluationSimplifier.java
index 1de4b8a..ef8e11f 100644
--- a/src/proguard/optimize/evaluation/EvaluationSimplifier.java
+++ b/src/proguard/optimize/evaluation/EvaluationSimplifier.java
@@ -1,8 +1,8 @@
-/* $Id: EvaluationSimplifier.java,v 1.4 2005/10/22 11:55:29 eric Exp $
+/* $Id: EvaluationSimplifier.java,v 1.4.2.15 2006/10/07 12:08:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -228,7 +228,15 @@ implements   MemberInfoVisitor,
                 {
                     markSuperOrThis = false;
 
-                    if (DEBUG_ANALYSIS) System.out.print(offset +",");
+                    if (DEBUG_ANALYSIS) System.out.print(offset+"(<init>),");
+                    isNecessary[offset] = true;
+                }
+
+                // Mark that the instruction is necessary if it is an infinite loop.
+                else if (instruction.opcode == InstructionConstants.OP_GOTO &&
+                         partialEvaluator.branchTargets(offset).instructionOffsetValue().instructionOffset(0) == offset)
+                {
+                    if (DEBUG_ANALYSIS) System.out.print(offset+"(infinite loop),");
                     isNecessary[offset] = true;
                 }
 
@@ -277,7 +285,8 @@ implements   MemberInfoVisitor,
                                                 nextOffset);
 
             // Mark the producers on which this instruction depends.
-            if (isNecessaryConsumer(offset))
+            if (isNecessary[offset] &&
+                !isSimplified[offset])
             {
                 nextOffset = markProducers(offset,
                                            nextOffset);
@@ -318,19 +327,39 @@ implements   MemberInfoVisitor,
         if (DEBUG_ANALYSIS) System.out.println();
 
 
-        // Insert pop instructions where necessary, to keep the stack consistent.
-        if (DEBUG_ANALYSIS) System.out.println("Stack consistency marking:");
+        // Insert pop instructions before unmarked popping instructions,
+        // if required to keep the stack consistent.
+        if (DEBUG_ANALYSIS) System.out.println("Unmarked pop fixing:");
+
+        // Also figure out the offset of the last dup/swap instruction.
+        int highestDupOffset = -1;
 
         offset = codeLength - 1;
         do
         {
             if (partialEvaluator.isTraced(offset) &&
-                !isDupOrSwap(codeAttrInfo.code[offset]))
+                !isNecessary[offset] &&
+                !isSimplified[offset])
             {
-                // Make sure the stack is always consistent at this offset.
-                fixStackConsistency(classFile,
-                                    codeAttrInfo,
-                                    offset);
+                Instruction instruction = InstructionFactory.create(codeAttrInfo.code,
+                                                                    offset);
+
+                // Make sure any non-dup/swap instructions are always consistent
+                // at this offset.
+                if (!isDupOrSwap(instruction))
+                {
+                    // Make sure any popping instructions are always
+                    // consistent after this offset.
+                    fixPopInstruction(classFile,
+                                      codeAttrInfo,
+                                      offset,
+                                      instruction);
+                }
+                else if (highestDupOffset < 0)
+                {
+                    // Remember the offset of the last dup/swap instruction.
+                    highestDupOffset = offset;
+                }
             }
 
             offset--;
@@ -339,18 +368,67 @@ implements   MemberInfoVisitor,
         if (DEBUG_ANALYSIS) System.out.println();
 
 
-        // Fix dup/swap instructions where necessary, to keep the stack consistent.
-        if (DEBUG_ANALYSIS) System.out.println("Dup/swap marking and fixing:");
+        // Insert dup instructions where necessary, to keep the stack consistent.
+        boolean updated;
+        do
+        {
+            if (DEBUG_ANALYSIS) System.out.println("Dup marking:");
+
+            // Repeat going over all instructions, as long as dup/swap
+            // instructions are updated.
+            updated = false;
+
+            offset = highestDupOffset;
+            while (offset >= 0)
+            {
+                if (partialEvaluator.isTraced(offset))
+                {
+                    Instruction instruction = InstructionFactory.create(codeAttrInfo.code,
+                                                                        offset);
+
+                    // Make sure any dup/swap instructions are always consistent
+                    // at this offset.
+                    if (isDupOrSwap(instruction))
+                    {
+                        updated |= fixDupInstruction(classFile,
+                                                     codeAttrInfo,
+                                                     offset,
+                                                     instruction);
+                    }
+                }
+
+                offset--;
+            }
+        }
+        while (updated);
+        if (DEBUG_ANALYSIS) System.out.println();
+
+
+        // Insert pop instructions after marked pushing instructions,
+        // if required to keep the stack consistent.
+        if (DEBUG_ANALYSIS) System.out.println("Marked push fixing:");
 
         offset = codeLength - 1;
         do
         {
-            if (partialEvaluator.isTraced(offset) &&
-                isDupOrSwap(codeAttrInfo.code[offset]))
+            if (//partialEvaluator.isTraced(offset) &&
+                isNecessary[offset] &&
+                !isSimplified[offset])
             {
-                // Make sure any dup/swap instructions are always consistent at this offset.
-                fixDupInstruction(codeAttrInfo,
-                                  offset);
+                Instruction instruction = InstructionFactory.create(codeAttrInfo.code,
+                                                                    offset);
+
+                // Make sure any non-dup/swap instructions are always consistent
+                // at this offset.
+                if (!isDupOrSwap(instruction))
+                {
+                    // Make sure any pushing instructions are always
+                    // consistent after this offset.
+                    fixPushInstruction(classFile,
+                                       codeAttrInfo,
+                                       offset,
+                                       instruction);
+                }
             }
 
             offset--;
@@ -433,7 +511,7 @@ implements   MemberInfoVisitor,
                 if (DEBUG_ANALYSIS) System.out.println(offset +",");
 
                 // Figure out what kind of initialization value has to be stored.
-                int pushComputationalType = partialEvaluator.variableValue(offset, variableIndex).computationalType();
+                int pushComputationalType = partialEvaluator.variableValueAfter(offset, variableIndex).computationalType();
                 increaseStackSize(offset, pushComputationalType, false);
             }
 
@@ -840,149 +918,20 @@ implements   MemberInfoVisitor,
 
 
     /**
-     * Inserts pop instructions where necessary, in order to make sure the
-     * stack is consistent at the given index.
-     * @param classFile      the class file that is being checked.
-     * @param codeAttrInfo   the code that is being checked.
-     * @param consumerOffset the offset of the consumer instruction.
-     */
-    private void fixStackConsistency(ClassFile    classFile,
-                                     CodeAttrInfo codeAttrInfo,
-                                     int          consumerOffset)
-    {
-        // See if we have any values pushed on the stack that we aren't using.
-        InstructionOffsetValue producerOffsets = partialEvaluator.unusedProducerOffsets(consumerOffset);
-
-        // This includes all values if the popping instruction isn't necessary at all.
-        boolean isNotNecessary = !isNecessaryConsumer(consumerOffset);
-        if (isNotNecessary)
-        {
-            producerOffsets = producerOffsets.generalize(partialEvaluator.stackProducerOffsets(consumerOffset)).instructionOffsetValue();
-        }
-
-        // Do we have any pushing instructions?
-        if (producerOffsets.instructionOffsetCount() > 0)
-        {
-            // Is this instruction really popping any values?
-            // Note that method invocations have their original pop counts,
-            // including any unused parameters.
-            Instruction popInstruction = InstructionFactory.create(codeAttrInfo.code,
-                                                                   consumerOffset);
-            int popCount = popInstruction.stackPopCount(classFile);
-            if (popCount > 0)
-            {
-                // Can we pop all values at the popping instruction?
-                if (isNotNecessary &&
-                    popCount <= 6  &&
-                    isAllNecessary(producerOffsets))
-                {
-                    // Is the popping instruction a simple pop or pop2 instruction?
-                    byte popOpcode = popInstruction.opcode;
-                    if (popOpcode == InstructionConstants.OP_POP ||
-                        popOpcode == InstructionConstants.OP_POP2)
-                    {
-                        if (DEBUG_ANALYSIS) System.out.println("  Popping value again at "+popInstruction.toString(consumerOffset)+" (pushed at all "+producerOffsets.instructionOffsetCount()+" offsets)");
-
-                        // Simply mark the pop or pop2 instruction.
-                        isNecessary[consumerOffset] = true;
-                    }
-                    else
-                    {
-                        if (DEBUG_ANALYSIS) System.out.println("  Popping value instead of "+popInstruction.toString(consumerOffset)+" (pushed at all "+producerOffsets.instructionOffsetCount()+" offsets)");
-
-                        // Make sure the pushed value is popped again,
-                        // right before this instruction.
-                        decreaseStackSize(consumerOffset, popCount, true, isNotNecessary);
-                    }
-                }
-                else if (isAnyNecessary(producerOffsets))
-                {
-                    // Pop the values right after the pushing instructions.
-                    if (DEBUG_ANALYSIS) System.out.println("  Popping value somewhere before "+consumerOffset+" (pushed at some of "+producerOffsets.instructionOffsetCount()+" offsets):");
-
-                    // Go over all stack pushing instructions.
-                    int producerCount = producerOffsets.instructionOffsetCount();
-                    for (int producerIndex = 0; producerIndex < producerCount; producerIndex++)
-                    {
-                        // Has the push instruction been marked?
-                        int producerOffset = producerOffsets.instructionOffset(producerIndex);
-                        if (producerOffset == PartialEvaluator.AT_METHOD_ENTRY)
-                        {
-                            Instruction pushInstruction = InstructionFactory.create(codeAttrInfo.code,
-                                                                                    producerOffset);
-
-                            if (DEBUG_ANALYSIS) System.out.println("    Popping value at start of method");
-
-                            // Pop it right at the beginning of the method.
-                            decreaseStackSize(0,
-                                              pushInstruction.stackPushCount(classFile),
-                                              true, false);
-                        }
-                        else if (isNecessaryProducer(producerOffset))
-                        {
-                            // Make sure the pushed value is popped again.
-                            Instruction pushInstruction = InstructionFactory.create(codeAttrInfo.code,
-                                                                                    producerOffset);
-
-                            // If there is another consumer, then leave it to
-                            // the dup instruction to fix the stack.
-                            if (!containsConsumer(producerOffset + 1,
-                                                  consumerOffset,
-                                                  producerOffset))
-                            {
-                                if (DEBUG_ANALYSIS) System.out.println("    Popping value right after "+producerOffset+", due to push at "+producerOffset);
-
-                                // Pop it right after the instruction that pushes it
-                                // (or after the dup instruction that still uses it).
-                                decreaseStackSize(producerOffset,
-                                                  pushInstruction.stackPushCount(classFile),
-                                                  false, false);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Returns the last offset of the necessary instruction that depends on the
-     * stack result of the instruction at the given index.
-     * @param startOffset    the start offset in the search.
-     * @param endOffset      the end offset in the search.
-     * @param producerOffset the offset of the instruction that pushes
-     *                              a result onto the stack.
-     * @return the last offset of the necessary instruction that uses the
-     *         above result.
-     */
-    private boolean containsConsumer(int startOffset,
-                                     int endOffset,
-                                     int producerOffset)
-    {
-        for (int consumerOffset = startOffset; consumerOffset < endOffset; consumerOffset++)
-        {
-            if (isNecessaryConsumer(consumerOffset)   &&
-                partialEvaluator.stackProducerOffsets(consumerOffset).contains(producerOffset))
-            {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-
-    /**
      * Marks the specified instruction if it is a required dup/swap instruction,
      * replacing it by an appropriate variant if necessary.
+     * @param classFile    the class that is being checked.
      * @param codeAttrInfo the code that is being checked.
-     * @param offset       the offset of the instruction.
+     * @param dupOffset    the offset of the dup/swap instruction.
+     * @param instruction  the dup/swap instruction.
+     * @return whether the instruction is updated.
      */
-    private void fixDupInstruction(CodeAttrInfo codeAttrInfo,
-                                   int          offset)
+    private boolean fixDupInstruction(ClassFile    classFile,
+                                      CodeAttrInfo codeAttrInfo,
+                                      int          dupOffset,
+                                      Instruction  instruction)
     {
-        byte    oldOpcode = codeAttrInfo.code[offset];
+        byte    oldOpcode = instruction.opcode;
         byte    newOpcode = 0;
         boolean present   = false;
 
@@ -991,8 +940,8 @@ implements   MemberInfoVisitor,
         {
             case InstructionConstants.OP_DUP:
             {
-                boolean stackEntryPresent0 = isStackEntryPresent(offset, 0);
-                boolean stackEntryPresent1 = isStackEntryPresent(offset, 1);
+                boolean stackEntryPresent0 = isStackEntryNecessaryAfter(dupOffset, 0, false);
+                boolean stackEntryPresent1 = isStackEntryNecessaryAfter(dupOffset, 1, false);
 
                 // Should either the original element or the copy be present?
                 if (stackEntryPresent0 ||
@@ -1011,9 +960,9 @@ implements   MemberInfoVisitor,
             }
             case InstructionConstants.OP_DUP_X1:
             {
-                boolean stackEntryPresent0 = isStackEntryPresent(offset, 0);
-                boolean stackEntryPresent1 = isStackEntryPresent(offset, 1);
-                boolean stackEntryPresent2 = isStackEntryPresent(offset, 2);
+                boolean stackEntryPresent0 = isStackEntryNecessaryAfter(dupOffset, 0, false);
+                boolean stackEntryPresent1 = isStackEntryNecessaryAfter(dupOffset, 1, false);
+                boolean stackEntryPresent2 = isStackEntryNecessaryAfter(dupOffset, 2, false);
 
                 // Should either the original element or the copy be present?
                 if (stackEntryPresent0 ||
@@ -1044,10 +993,10 @@ implements   MemberInfoVisitor,
             }
             case InstructionConstants.OP_DUP_X2:
             {
-                boolean stackEntryPresent0 = isStackEntryPresent(offset, 0);
-                boolean stackEntryPresent1 = isStackEntryPresent(offset, 1);
-                boolean stackEntryPresent2 = isStackEntryPresent(offset, 2);
-                boolean stackEntryPresent3 = isStackEntryPresent(offset, 3);
+                boolean stackEntryPresent0 = isStackEntryNecessaryAfter(dupOffset, 0, false);
+                boolean stackEntryPresent1 = isStackEntryNecessaryAfter(dupOffset, 1, false);
+                boolean stackEntryPresent2 = isStackEntryNecessaryAfter(dupOffset, 2, false);
+                boolean stackEntryPresent3 = isStackEntryNecessaryAfter(dupOffset, 3, false);
 
                 // Should either the original element or the copy be present?
                 if (stackEntryPresent0 ||
@@ -1075,7 +1024,7 @@ implements   MemberInfoVisitor,
                         else if (skipCount == 2)
                         {
                             // We can't easily move the original element.
-                            throw new IllegalArgumentException("Can't handle dup_x2 instruction moving original element across two elements");
+                            throw new IllegalArgumentException("Can't handle dup_x2 instruction moving original element across two elements at ["+dupOffset +"]");
                         }
                     }
                 }
@@ -1083,8 +1032,8 @@ implements   MemberInfoVisitor,
             }
             case InstructionConstants.OP_DUP2:
             {
-                boolean stackEntriesPresent01 = isStackEntriesPresent(offset, 0, 1);
-                boolean stackEntriesPresent23 = isStackEntriesPresent(offset, 2, 3);
+                boolean stackEntriesPresent01 = isStackEntriesNecessaryAfter(dupOffset, 0, 1, false);
+                boolean stackEntriesPresent23 = isStackEntriesNecessaryAfter(dupOffset, 2, 3, false);
 
                 // Should either the original element or the copy be present?
                 if (stackEntriesPresent01 ||
@@ -1103,9 +1052,9 @@ implements   MemberInfoVisitor,
             }
             case InstructionConstants.OP_DUP2_X1:
             {
-                boolean stackEntriesPresent01 = isStackEntriesPresent(offset, 0, 1);
-                boolean stackEntryPresent2    = isStackEntryPresent(offset, 2);
-                boolean stackEntriesPresent34 = isStackEntriesPresent(offset, 3, 4);
+                boolean stackEntriesPresent01 = isStackEntriesNecessaryAfter(dupOffset, 0, 1, false);
+                boolean stackEntryPresent2    = isStackEntryNecessaryAfter(dupOffset, 2, false);
+                boolean stackEntriesPresent34 = isStackEntriesNecessaryAfter(dupOffset, 3, 4, false);
 
                 // Should either the original element or the copy be present?
                 if (stackEntriesPresent01 ||
@@ -1127,7 +1076,7 @@ implements   MemberInfoVisitor,
                         else if (skipCount > 0)
                         {
                             // We can't easily move the original element.
-                            throw new IllegalArgumentException("Can't handle dup2_x1 instruction moving original element across "+skipCount+" elements");
+                            throw new IllegalArgumentException("Can't handle dup2_x1 instruction moving original element across "+skipCount+" elements at ["+dupOffset +"]");
                         }
                     }
                 }
@@ -1135,10 +1084,10 @@ implements   MemberInfoVisitor,
             }
             case InstructionConstants.OP_DUP2_X2:
             {
-                boolean stackEntriesPresent01 = isStackEntriesPresent(offset, 0, 1);
-                boolean stackEntryPresent2    = isStackEntryPresent(offset, 2);
-                boolean stackEntryPresent3    = isStackEntryPresent(offset, 3);
-                boolean stackEntriesPresent45 = isStackEntriesPresent(offset, 4, 5);
+                boolean stackEntriesPresent01 = isStackEntriesNecessaryAfter(dupOffset, 0, 1, false);
+                boolean stackEntryPresent2    = isStackEntryNecessaryAfter(dupOffset, 2, false);
+                boolean stackEntryPresent3    = isStackEntryNecessaryAfter(dupOffset, 3, false);
+                boolean stackEntriesPresent45 = isStackEntriesNecessaryAfter(dupOffset, 4, 5, false);
 
                 // Should either the original element or the copy be present?
                 if (stackEntriesPresent01 ||
@@ -1161,7 +1110,7 @@ implements   MemberInfoVisitor,
                         else if (skipCount > 0)
                         {
                             // We can't easily move the original element.
-                            throw new IllegalArgumentException("Can't handle dup2_x2 instruction moving original element across "+skipCount+" elements");
+                            throw new IllegalArgumentException("Can't handle dup2_x2 instruction moving original element across "+skipCount+" elements at ["+dupOffset +"]");
                         }
                     }
                 }
@@ -1169,8 +1118,8 @@ implements   MemberInfoVisitor,
             }
             case InstructionConstants.OP_SWAP:
             {
-                boolean stackEntryPresent0 = isStackEntryPresent(offset, 0);
-                boolean stackEntryPresent1 = isStackEntryPresent(offset, 1);
+                boolean stackEntryPresent0 = isStackEntryNecessaryAfter(dupOffset, 0, false);
+                boolean stackEntryPresent1 = isStackEntryNecessaryAfter(dupOffset, 1, false);
 
                 // Will either element be present?
                 if (stackEntryPresent0 ||
@@ -1189,32 +1138,121 @@ implements   MemberInfoVisitor,
             }
         }
 
+        boolean updated = false;
+
         // Actually replace the instruction with the new opcode, if any.
         if (present)
         {
-            // Mark that the instruction is necessary.
-            isNecessary[offset] = true;
+            // If this is the first pass, note that the instruction is updated.
+            if (!isNecessary[dupOffset])
+            {
+                updated = true;
+
+                // Mark that the instruction is necessary.
+                isNecessary[dupOffset]  = true;
+            }
 
             if      (newOpcode == 0)
             {
                 // Delete the instruction.
-                codeAttrInfoEditor.deleteInstruction(offset);
+                codeAttrInfoEditor.deleteInstruction(dupOffset);
 
-                if (DEBUG_ANALYSIS) System.out.println("  Marking but deleting instruction at ["+offset+"]");
+                if (DEBUG_ANALYSIS) System.out.println("  Marking but deleting instruction "+instruction.toString(dupOffset));
             }
             else if (newOpcode == oldOpcode)
             {
                 // Leave the instruction unchanged.
-                if (DEBUG_ANALYSIS) System.out.println("  Marking unchanged instruction at ["+offset+"]");
+                codeAttrInfoEditor.undeleteInstruction(dupOffset);
+
+                if (DEBUG_ANALYSIS) System.out.println("  Marking unchanged instruction "+instruction.toString(dupOffset));
             }
             else
             {
                 // Replace the instruction.
                 Instruction replacementInstruction = new SimpleInstruction(newOpcode);
-                codeAttrInfoEditor.replaceInstruction(offset,
+                codeAttrInfoEditor.replaceInstruction(dupOffset,
                                                       replacementInstruction);
 
-                if (DEBUG_ANALYSIS) System.out.println("  Replacing instruction at ["+offset+"] by "+replacementInstruction.toString());
+                if (DEBUG_ANALYSIS) System.out.println("  Replacing instruction "+instruction.toString(dupOffset)+" by "+replacementInstruction.toString());
+            }
+        }
+
+        return updated;
+    }
+
+
+    /**
+     * Pops the stack after the given necessary instruction, if it pushes an
+     * entry that is not used at all.
+     * @param classFile      the class that is being checked.
+     * @param codeAttrInfo   the code that is being checked.
+     * @param producerOffset the offset of the instruction.
+     * @param instruction    the instruction.
+     */
+    private void fixPushInstruction(ClassFile    classFile,
+                                    CodeAttrInfo codeAttrInfo,
+                                    int          producerOffset,
+                                    Instruction  instruction)
+    {
+        int pushCount = instruction.stackPushCount(classFile);
+        if (pushCount > 0)
+        {
+            boolean stackEntryPresent0 = isStackEntryNecessaryAfter(producerOffset, 0, false);
+
+            if (!stackEntryPresent0)
+            {
+                if (instruction.opcode != InstructionConstants.OP_JSR &&
+                    instruction.opcode != InstructionConstants.OP_JSR_W)
+                {
+                    // Make sure the pushed value is popped again,
+                    // right after this instruction.
+                    decreaseStackSize(producerOffset, pushCount, false, false);
+
+                    if (DEBUG_ANALYSIS) System.out.println("  Popping unused value right after "+instruction.toString(producerOffset));
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Pops the stack before the given unnecessary instruction, if the stack
+     * contains an entry that it would have popped.
+     * @param classFile      the class that is being checked.
+     * @param codeAttrInfo   the code that is being checked.
+     * @param consumerOffset the offset of the consumer instruction.
+     * @param instruction    the instruction.
+     */
+    private void fixPopInstruction(ClassFile    classFile,
+                                   CodeAttrInfo codeAttrInfo,
+                                   int          consumerOffset,
+                                   Instruction  instruction)
+    {
+        int popCount = instruction.stackPopCount(classFile);
+        if (popCount > 0)
+        {
+            if (partialEvaluator.stackProducerOffsets(consumerOffset).contains(PartialEvaluator.AT_CATCH_ENTRY) ||
+                isStackEntryNecessaryBefore(consumerOffset, 0, false) &&
+                !isStackEntryNecessaryBefore(consumerOffset, 0, true))
+            {
+                // Is the consumer a simple pop or pop2 instruction?
+                byte popOpcode = instruction.opcode;
+                if (popOpcode == InstructionConstants.OP_POP ||
+                    popOpcode == InstructionConstants.OP_POP2)
+                {
+                    if (DEBUG_ANALYSIS) System.out.println("  Popping value again at "+instruction.toString(consumerOffset));
+
+                    // Simply mark the pop or pop2 instruction.
+                    isNecessary[consumerOffset] = true;
+                }
+                else
+                {
+                    if (DEBUG_ANALYSIS) System.out.println("  Popping value instead of "+instruction.toString(consumerOffset));
+
+                    // Make sure the pushed value is popped again,
+                    // right before this instruction.
+                    decreaseStackSize(consumerOffset, popCount, true, true);
+                }
             }
         }
     }
@@ -1343,7 +1381,7 @@ implements   MemberInfoVisitor,
 
         if (remainingPopCount > 0)
         {
-            throw new IllegalArgumentException("Unsupported stack size reduction ["+popCount+"]");
+            throw new IllegalArgumentException("Unsupported stack size reduction ["+popCount+"] at ["+offset+"]");
         }
     }
 
@@ -1493,7 +1531,22 @@ implements   MemberInfoVisitor,
 
     public void visitBranchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, BranchInstruction branchInstruction)
     {
-        replaceBranchInstruction(offset, branchInstruction);
+        switch (branchInstruction.opcode)
+        {
+            case InstructionConstants.OP_GOTO:
+            case InstructionConstants.OP_GOTO_W:
+                // Don't replace unconditional branches.
+                break;
+
+            case InstructionConstants.OP_JSR:
+            case InstructionConstants.OP_JSR_W:
+                replaceJsrInstruction(offset, branchInstruction);
+                break;
+
+            default:
+                replaceBranchInstruction(offset, branchInstruction);
+                break;
+        }
     }
 
 
@@ -1517,7 +1570,7 @@ implements   MemberInfoVisitor,
      */
     private void replaceIntegerPushInstruction(int offset, Instruction instruction)
     {
-        Value pushedValue = partialEvaluator.stackTopValue(offset, 0);
+        Value pushedValue = partialEvaluator.stackTopValueAfter(offset, 0);
         if (pushedValue.isSpecific())
         {
             int value = pushedValue.integerValue().value();
@@ -1537,7 +1590,7 @@ implements   MemberInfoVisitor,
      */
     private void replaceLongPushInstruction(int offset, Instruction instruction)
     {
-        Value pushedValue = partialEvaluator.stackTopValue(offset, 0);
+        Value pushedValue = partialEvaluator.stackTopValueAfter(offset, 0);
         if (pushedValue.isSpecific())
         {
             long value = pushedValue.longValue().value();
@@ -1558,7 +1611,7 @@ implements   MemberInfoVisitor,
      */
     private void replaceFloatPushInstruction(int offset, Instruction instruction)
     {
-        Value pushedValue = partialEvaluator.stackTopValue(offset, 0);
+        Value pushedValue = partialEvaluator.stackTopValueAfter(offset, 0);
         if (pushedValue.isSpecific())
         {
             float value = pushedValue.floatValue().value();
@@ -1580,7 +1633,7 @@ implements   MemberInfoVisitor,
      */
     private void replaceDoublePushInstruction(int offset, Instruction instruction)
     {
-        Value pushedValue = partialEvaluator.stackTopValue(offset, 0);
+        Value pushedValue = partialEvaluator.stackTopValueAfter(offset, 0);
         if (pushedValue.isSpecific())
         {
             double value = pushedValue.doubleValue().value();
@@ -1601,7 +1654,7 @@ implements   MemberInfoVisitor,
      */
     private void replaceReferencePushInstruction(int offset, Instruction instruction)
     {
-        Value pushedValue = partialEvaluator.stackTopValue(offset, 0);
+        Value pushedValue = partialEvaluator.stackTopValueAfter(offset, 0);
         if (pushedValue.isSpecific())
         {
             ReferenceValue value = pushedValue.referenceValue();
@@ -1642,6 +1695,31 @@ implements   MemberInfoVisitor,
 
 
     /**
+     * Replaces the given 'jsr' instruction by a simpler branch instruction,
+     * if possible.
+     */
+    private void replaceJsrInstruction(int offset, BranchInstruction branchInstruction)
+    {
+        if (partialEvaluator.isTraced(offset))
+        {
+            // Is the subroutine ever returning?
+            if (!isReturningFromSubroutine(offset + branchInstruction.branchOffset))
+            {
+                // All 'jsr' instructions to this subroutine can be replaced
+                // by unconditional branch instructions.
+                replaceBranchInstruction(offset, branchInstruction);
+            }
+            else if (!partialEvaluator.isTraced(offset + branchInstruction.length(offset)))
+            {
+                // We have to make sure the instruction after this 'jsr'
+                // instruction is valid, even if it is never reached.
+                insertInfiniteLoop(offset + branchInstruction.length(offset));
+            }
+        }
+    }
+
+
+    /**
      * Deletes the given branch instruction, or replaces it by a simpler branch
      * instruction, if possible.
      */
@@ -1653,11 +1731,7 @@ implements   MemberInfoVisitor,
 
             // Is there exactly one branch target (not from a goto or jsr)?
             if (branchTargets != null &&
-                branchTargets.instructionOffsetCount() == 1      &&
-                instruction.opcode != InstructionConstants.OP_GOTO   &&
-                instruction.opcode != InstructionConstants.OP_GOTO_W &&
-                instruction.opcode != InstructionConstants.OP_JSR    &&
-                instruction.opcode != InstructionConstants.OP_JSR_W)
+                branchTargets.instructionOffsetCount() == 1)
             {
                 // Is it branching to the next instruction?
                 int branchOffset = branchTargets.instructionOffset(0) - offset;
@@ -1670,7 +1744,7 @@ implements   MemberInfoVisitor,
                 }
                 else
                 {
-                    // Replace the branch instruction by a simple branch instrucion.
+                    // Replace the branch instruction by a simple branch instruction.
                     Instruction replacementInstruction =
                         new BranchInstruction(InstructionConstants.OP_GOTO_W,
                                               branchOffset).shrink();
@@ -1680,6 +1754,9 @@ implements   MemberInfoVisitor,
                     codeAttrInfoEditor.replaceInstruction(offset,
                                                           replacementInstruction);
 
+                    // Mark that the instruction has been simplified.
+                    isSimplified[offset] = true;
+
                     // Visit the instruction, if required.
                     if (extraBranchInstructionVisitor != null)
                     {
@@ -1693,6 +1770,26 @@ implements   MemberInfoVisitor,
     }
 
 
+    /**
+     * Puts an infinite loop at the given offset.
+     */
+    private void insertInfiniteLoop(int offset)
+    {
+        // Replace the branch instruction by a simple branch instruction.
+        Instruction replacementInstruction =
+            new BranchInstruction(InstructionConstants.OP_GOTO, 0);
+
+        if (DEBUG_ANALYSIS) System.out.println("  Inserting infinite loop at unreachable instruction at ["+offset+"]");
+
+        codeAttrInfoEditor.replaceInstruction(offset,
+                                              replacementInstruction);
+
+        // Mark that the instruction has been simplified.
+        isNecessary[offset]  = true;
+        isSimplified[offset] = true;
+    }
+
+
     // Small utility methods.
 
     /**
@@ -1767,40 +1864,25 @@ implements   MemberInfoVisitor,
 
 
     /**
-     * Returns whether the given opcode represents a dup or swap instruction
+     * Returns whether the given instruction is a dup or swap instruction
      * (dup, dup_x1, dup_x2, dup2, dup2_x1, dup2_x1, swap).
      */
-    private boolean isDupOrSwap(byte opcode) {
-        return opcode >= InstructionConstants.OP_DUP &&
-               opcode <= InstructionConstants.OP_SWAP;
-    }
-
-
-    /**
-     * Returns whether the given stack entry is present after execution of the
-     * instruction at the given offset.
-     */
-    private boolean isStackEntriesPresent(int instructionOffset, int stackIndex1, int stackIndex2)
+    private boolean isDupOrSwap(Instruction instruction)
     {
-        boolean present1 = isStackEntryPresent(instructionOffset, stackIndex1);
-        boolean present2 = isStackEntryPresent(instructionOffset, stackIndex2);
-
-        if (present1 ^ present2)
-        {
-            throw new IllegalArgumentException("Can't handle partial use of dup2 instructions");
-        }
-
-        return present1 || present2;
+        return instruction.opcode >= InstructionConstants.OP_DUP &&
+               instruction.opcode <= InstructionConstants.OP_SWAP;
     }
 
 
     /**
-     * Returns whether the given stack entry is present after execution of the
-     * instruction at the given offset.
+     * Returns whether the subroutine starting at the given offset is ever
+     * returning.
      */
-    private boolean isStackEntryPresent(int instructionOffset, int stackIndex)
+    private boolean isReturningFromSubroutine(int subroutineOffset)
     {
-        return isAnyNecessary(partialEvaluator.stackTopConsumerOffsets(instructionOffset, stackIndex));
+        int subroutineEnd = partialEvaluator.subroutineEnd(subroutineOffset);
+        return partialEvaluator.isSubroutineEnd(subroutineEnd) &&
+               partialEvaluator.isTraced(subroutineEnd);
     }
 
 
@@ -1813,11 +1895,12 @@ implements   MemberInfoVisitor,
     {
         int codeLength = codeAttrInfo.u4codeLength;
 
-        for (int consumerOffset = 0; consumerOffset < codeLength; consumerOffset++)
+        for (int offset = 0; offset < codeLength; offset++)
         {
-            if (isNecessaryConsumer(consumerOffset)                                   &&
-                partialEvaluator.variableValue(consumerOffset, variableIndex) != null &&
-                isAnyNecessary(partialEvaluator.variableProducerOffsets(consumerOffset, variableIndex)))
+            if (isNecessary[offset]   &&
+                !isSimplified[offset] &&
+                partialEvaluator.variableValueBefore(offset, variableIndex) != null &&
+                isVariableNecessaryBefore(offset, variableIndex, false))
             {
                 return true;
             }
@@ -1828,30 +1911,71 @@ implements   MemberInfoVisitor,
 
 
     /**
-     * Returns whether any of the instructions at the given offsets are marked as
-     * necessary.
+     * Returns whether the given variable is present before execution of the
+     * instruction at the given offset.
      */
-    private boolean isAnyNecessary(InstructionOffsetValue offsets)
+    private boolean isVariableNecessaryBefore(int     instructionOffset,
+                                              int     variableIndex,
+                                              boolean all)
     {
-        return isNecessary(offsets, false);
+        return isNecessary(partialEvaluator.variableProducerOffsetsBefore(instructionOffset, variableIndex),
+                           true,
+                           all);
     }
 
 
     /**
-     * Returns whether all of the instructions at the given offsets are marked as
-     * necessary.
+     * Returns whether the given stack entry is present after execution of the
+     * instruction at the given offset.
      */
-    private boolean isAllNecessary(InstructionOffsetValue offsets)
+    private boolean isStackEntriesNecessaryAfter(int instructionOffset, int stackIndex1, int stackIndex2, boolean all)
     {
-        return isNecessary(offsets, true);
+        boolean present1 = isStackEntryNecessaryAfter(instructionOffset, stackIndex1, all);
+        boolean present2 = isStackEntryNecessaryAfter(instructionOffset, stackIndex2, all);
+
+//        if (present1 ^ present2)
+//        {
+//            throw new IllegalArgumentException("Can't handle partial use of dup2 instructions at ["+instructionOffset+"]");
+//        }
+
+        return present1 || present2;
     }
 
 
     /**
-     * Returns whether any of the instructions at the given offsets are marked as
-     * necessary.
+     * Returns whether the given stack entry is present before execution of the
+     * instruction at the given offset.
+     */
+    private boolean isStackEntryNecessaryBefore(int     instructionOffset,
+                                                int     stackIndex,
+                                                boolean all)
+    {
+        return isNecessary(partialEvaluator.stackTopConsumerOffsetsBefore(instructionOffset, stackIndex),
+                           false,
+                           all);
+    }
+
+
+    /**
+     * Returns whether the given stack entry is present after execution of the
+     * instruction at the given offset.
+     */
+    private boolean isStackEntryNecessaryAfter(int     instructionOffset,
+                                               int     stackIndex,
+                                               boolean all)
+    {
+        return isNecessary(partialEvaluator.stackTopConsumerOffsetsAfter(instructionOffset, stackIndex),
+                           false,
+                           all);
+    }
+
+
+    /**
+     * Returns whether any or all of the instructions at the given offsets are
+     * marked as necessary.
      */
     private boolean isNecessary(InstructionOffsetValue offsets,
+                                boolean                producer,
                                 boolean                all)
     {
         int offsetCount = offsets.instructionOffsetCount();
@@ -1860,7 +1984,7 @@ implements   MemberInfoVisitor,
         {
             int offset = offsets.instructionOffset(offsetIndex);
 
-            if (all ^ isNecessaryProducer(offset))
+            if (all ^ (isNecessary[offset] && (producer || !isSimplified[offset])))
             {
                 return !all;
             }
@@ -1868,26 +1992,4 @@ implements   MemberInfoVisitor,
 
         return all;
     }
-
-
-    /**
-     * Returns whether the instructions at the given offset is marked as
-     * necessary, as a producer.
-     */
-    private boolean isNecessaryProducer(int producerOffset)
-    {
-        return producerOffset == PartialEvaluator.AT_METHOD_ENTRY ||
-               isNecessary[producerOffset];
-    }
-
-
-    /**
-     * Returns whether the instructions at the given offset is marked as
-     * necessary, as a consumer.
-     */
-    private boolean isNecessaryConsumer(int consumerOffset)
-    {
-        return isNecessary[consumerOffset] &&
-               !isSimplified[consumerOffset];
-    }
 }
diff --git a/src/proguard/optimize/evaluation/PartialEvaluator.java b/src/proguard/optimize/evaluation/PartialEvaluator.java
index 526be5b..cf18331 100644
--- a/src/proguard/optimize/evaluation/PartialEvaluator.java
+++ b/src/proguard/optimize/evaluation/PartialEvaluator.java
@@ -1,8 +1,8 @@
-/* $Id: PartialEvaluator.java,v 1.37 2005/10/22 11:55:29 eric Exp $
+/* $Id: PartialEvaluator.java,v 1.37.2.5 2006/06/12 20:50:39 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -47,7 +47,7 @@ implements   ExceptionInfoVisitor,
     private static final int INITIAL_CODE_LENGTH = 1024;
     private static final int INITIAL_VALUE_COUNT = 32;
 
-    //private static final int MAXIMUM_EVALUATION_COUNT = 100;
+    private static final int MAXIMUM_EVALUATION_COUNT = 5;
 
     public static final int AT_METHOD_ENTRY = -1;
     public static final int AT_CATCH_ENTRY  = -1;
@@ -60,8 +60,11 @@ implements   ExceptionInfoVisitor,
     private InstructionOffsetValue[] unusedProducerValues = new InstructionOffsetValue[INITIAL_CODE_LENGTH];
     private InstructionOffsetValue[] branchOriginValues   = new InstructionOffsetValue[INITIAL_CODE_LENGTH];
     private InstructionOffsetValue[] branchTargetValues   = new InstructionOffsetValue[INITIAL_CODE_LENGTH];
-    private TracedVariables[]        vars                 = new TracedVariables[INITIAL_CODE_LENGTH];
-    private TracedStack[]            stacks               = new TracedStack[INITIAL_CODE_LENGTH];
+    private TracedVariables[]        variablesBefore      = new TracedVariables[INITIAL_CODE_LENGTH];
+    private TracedStack[]            stacksBefore         = new TracedStack[INITIAL_CODE_LENGTH];
+    private TracedVariables[]        variablesAfter       = new TracedVariables[INITIAL_CODE_LENGTH];
+    private TracedStack[]            stacksAfter          = new TracedStack[INITIAL_CODE_LENGTH];
+    private boolean[]                generalizedContexts  = new boolean[INITIAL_CODE_LENGTH];
     private int[]                    evaluationCounts     = new int[INITIAL_CODE_LENGTH];
     private int[]                    initializedVariables = new int[INITIAL_CODE_LENGTH];
     private boolean                  evaluateExceptions;
@@ -84,6 +87,10 @@ implements   ExceptionInfoVisitor,
                           CodeAttrInfo codeAttrInfo,
                           Variables    parameters)
     {
+//        DEBUG = DEBUG_RESULTS =
+//            classFile.getName().equals("abc/Def") &&
+//            methodInfo.getName(classFile).equals("abc");
+
         // Initialize the reusable arrays and variables.
         initializeVariables(codeAttrInfo, parameters);
 
@@ -151,8 +158,8 @@ implements   ExceptionInfoVisitor,
                         System.out.println("     has overall been branching to "+branchTargets);
                     }
 
-                    System.out.println("     Vars:  "+vars[offset]);
-                    System.out.println("     Stack: "+stacks[offset]);
+                    System.out.println("     Vars:  "+variablesAfter[offset]);
+                    System.out.println("     Stack: "+stacksAfter[offset]);
                 }
 
                 offset += instruction.length(offset);
@@ -210,24 +217,66 @@ implements   ExceptionInfoVisitor,
 
 
     /**
-     * Returns the variable value at the given instruction offset and variable
-     * index.
+     * Returns whether the instruction at the given offset is the end of a
+     * subroutine.
+     */
+    public boolean isSubroutineEnd(int instructionOffset)
+    {
+        return branchTargetFinder.isSubroutineEnd(instructionOffset);
+    }
+
+
+    /**
+     * Returns the offset of the end of the subroutine that starts at the given
+     * offset.
+     */
+    public int subroutineEnd(int instructionOffset)
+    {
+        return branchTargetFinder.subroutineEnd(instructionOffset);
+    }
+
+
+    /**
+     * Returns the value of the given variable before the given instruction
+     * offset.
+     */
+    public Value variableValueBefore(int instructionOffset,
+                                     int variableIndex)
+    {
+        return variablesBefore[instructionOffset].load(variableIndex);
+    }
+
+
+    /**
+     * Returns the value of the given variable after the given instruction
+     * offset.
      */
-    public Value variableValue(int instructionOffset,
-                               int variableIndex)
+    public Value variableValueAfter(int instructionOffset,
+                                    int variableIndex)
     {
-        return vars[instructionOffset].load(variableIndex);
+        return variablesAfter[instructionOffset].load(variableIndex);
     }
 
 
     /**
-     * Returns the instruction offsets that set the variable value at at the given
-     * instruction offset and variable index.
+     * Returns the instruction offsets that set the value of the given variable
+     * before the given instruction offset.
      */
-    public InstructionOffsetValue variableProducerOffsets(int instructionOffset,
-                                                          int variableIndex)
+    public InstructionOffsetValue variableProducerOffsetsBefore(int instructionOffset,
+                                                                int variableIndex)
     {
-        return vars[instructionOffset].getStoredTraceValue(variableIndex).instructionOffsetValue();
+        return variablesBefore[instructionOffset].getStoredTraceValue(variableIndex).instructionOffsetValue();
+    }
+
+
+    /**
+     * Returns the instruction offsets that set the value of the given variable
+     * after the given instruction offset.
+     */
+    public InstructionOffsetValue variableProducerOffsetsAfter(int instructionOffset,
+                                                               int variableIndex)
+    {
+        return variablesAfter[instructionOffset].getStoredTraceValue(variableIndex).instructionOffsetValue();
     }
 
 
@@ -242,23 +291,46 @@ implements   ExceptionInfoVisitor,
 
 
     /**
-     * Returns the stack value at the given instruction offset and stack index.
+     * Returns the value of the given stack entry before the given instruction
+     * offset.
+     */
+    public Value stackTopValueBefore(int instructionOffset,
+                                     int stackIndex)
+    {
+        return stacksBefore[instructionOffset].getTop(stackIndex);
+    }
+
+
+    /**
+     * Returns the value of the given stack entry after the given instruction
+     * offset.
      */
-    public Value stackTopValue(int instructionOffset,
-                               int stackIndex)
+    public Value stackTopValueAfter(int instructionOffset,
+                                    int stackIndex)
     {
-        return stacks[instructionOffset].getTop(stackIndex);
+        return stacksAfter[instructionOffset].getTop(stackIndex);
     }
 
 
     /**
-     * Returns the instruction offsets that set the stack value at at the given
-     * instruction offset and stack index.
+     * Returns the instruction offsets that set the value of the given stack
+     * entry before the given instruction offset.
      */
-    public InstructionOffsetValue stackTopProducerOffsets(int instructionOffset,
-                                                          int stackIndex)
+    public InstructionOffsetValue stackTopProducerOffsetsBefore(int instructionOffset,
+                                                                int stackIndex)
     {
-        return stacks[instructionOffset].getTopProducerValue(stackIndex).instructionOffsetValue();
+        return stacksAfter[instructionOffset].getTopProducerValue(stackIndex).instructionOffsetValue();
+    }
+
+
+    /**
+     * Returns the instruction offsets that set the value of the given stack
+     * entry after the given instruction offset.
+     */
+    public InstructionOffsetValue stackTopProducerOffsetsAfter(int instructionOffset,
+                                                               int stackIndex)
+    {
+        return stacksAfter[instructionOffset].getTopProducerValue(stackIndex).instructionOffsetValue();
     }
 
 
@@ -273,13 +345,24 @@ implements   ExceptionInfoVisitor,
 
 
     /**
-     * Returns the instruction offsets that use the stack value at at the given
-     * instruction offset and stack index.
+     * Returns the instruction offsets that use the value of the given stack
+     * entry before the given instruction offset.
+     */
+    public InstructionOffsetValue stackTopConsumerOffsetsBefore(int instructionOffset,
+                                                               int stackIndex)
+    {
+        return stacksBefore[instructionOffset].getTopConsumerValue(stackIndex).instructionOffsetValue();
+    }
+
+
+    /**
+     * Returns the instruction offsets that use the value of the given stack
+     * entry after the given instruction offset.
      */
-    public InstructionOffsetValue stackTopConsumerOffsets(int instructionOffset,
-                                                          int stackIndex)
+    public InstructionOffsetValue stackTopConsumerOffsetsAfter(int instructionOffset,
+                                                               int stackIndex)
     {
-        return stacks[instructionOffset].getTopConsumerValue(stackIndex).instructionOffsetValue();
+        return stacksAfter[instructionOffset].getTopConsumerValue(stackIndex).instructionOffsetValue();
     }
 
 
@@ -415,11 +498,11 @@ implements   ExceptionInfoVisitor,
             }
 
             // Compute the stack index of the uninitialized object.
-            int stackIndex = stacks[offset].size();
+            int stackIndex = stacksAfter[offset].size();
 
             // Get the (first and presumably only) offset of the instruction
             // that put it there. This is typically a dup instruction.
-            int newOffset = stacks[previousOffset].getBottomProducerValue(stackIndex).instructionOffsetValue().instructionOffset(0);
+            int newOffset = stacksAfter[previousOffset].getBottomProducerValue(stackIndex).instructionOffsetValue().instructionOffset(0);
 
             // Add a reverse dependency. The source instruction depends on
             // the initializer instruction, thus making sure that the latter
@@ -463,17 +546,69 @@ implements   ExceptionInfoVisitor,
         // Evaluate the subsequent instructions.
         while (true)
         {
-            // Maintain a generalized trace instruction offset.
+            // Maintain a generalized local variable frame and stack at this
+            // instruction offset, before execution.
             int evaluationCount = evaluationCounts[instructionOffset]++;
             if (evaluationCount == 0)
             {
-                varProducerValues[instructionOffset]    = InstructionOffsetValueFactory.create();
-                stackProducerValues[instructionOffset]  = InstructionOffsetValueFactory.create();
-                unusedProducerValues[instructionOffset] = InstructionOffsetValueFactory.create();
+                // First time we're passing by this instruction.
+                if (variablesBefore[instructionOffset] == null)
+                {
+                    // There's not even a context at this index yet.
+                    variablesBefore[instructionOffset] = new TracedVariables(variables);
+                    stacksBefore[instructionOffset]    = new TracedStack(stack);
+                }
+                else
+                {
+                    // Reuse the context objects at this index.
+                    variablesBefore[instructionOffset].initialize(variables);
+                    stacksBefore[instructionOffset].copy(stack);
+                }
+
+                // We'll execute in the generalized context, because it is
+                // the same as the current context.
+                generalizedContexts[instructionOffset] = true;
+            }
+            else
+            {
+                // Merge in the current context.
+                boolean variablesChanged = variablesBefore[instructionOffset].generalize(variables);
+                boolean stackChanged     = stacksBefore[instructionOffset].generalize(stack);
+
+                // Bail out if the current context is the same as last time.
+                if (!variablesChanged &&
+                    !stackChanged     &&
+                    generalizedContexts[instructionOffset])
+                {
+                    if (DEBUG) System.out.println("Repeated variables, stack, and branch targets");
+
+                    break;
+                }
+
+                // See if this instruction has been evaluated an excessive number
+                // of times.
+                if (evaluationCount >= MAXIMUM_EVALUATION_COUNT)
+                {
+
+                    // Continue, but generalize the current context.
+                    // Note that the most recent variable values have to remain
+                    // last in the generalizations, for the sake of the ret
+                    // instruction.
+                    variables.generalize(variablesBefore[instructionOffset]);
+                    stack.generalize(stacksBefore[instructionOffset]);
+
+                    // We'll execute in the generalized context.
+                    generalizedContexts[instructionOffset] = true;
+                }
+                else
+                {
+                    // We'll execute in the current context.
+                    generalizedContexts[instructionOffset] = false;
+                }
             }
 
             // Remember this instruction's offset with any stored value.
-            Value storeValue = InstructionOffsetValueFactory.create(instructionOffset);
+            Value storeValue = new InstructionOffsetValue(instructionOffset);
             variables.setProducerValue(storeValue);
             stack.setProducerValue(storeValue);
 
@@ -493,7 +628,7 @@ implements   ExceptionInfoVisitor,
             // instruction.
             int nextInstructionOffset = instructionOffset +
                                         instruction.length(instructionOffset);
-            InstructionOffsetValue nextInstructionOffsetValue = InstructionOffsetValueFactory.create(nextInstructionOffset);
+            InstructionOffsetValue nextInstructionOffsetValue = new InstructionOffsetValue(nextInstructionOffset);
             branchUnit.resetCalled();
             branchUnit.setTraceBranchTargets(nextInstructionOffsetValue);
 
@@ -512,10 +647,9 @@ implements   ExceptionInfoVisitor,
 
             try
             {
-                // Process the instruction. The processor may call
-                // the Variables methods of 'variables',
-                // the Stack methods of 'stack', and
-                // the BranchUnit methods of 'branchUnit'.
+                // Process the instruction. The processor may modify the
+                // variables and the stack, and it may call the branch unit
+                // and the invocation unit.
                 instruction.accept(classFile,
                                    methodInfo,
                                    codeAttrInfo,
@@ -525,9 +659,10 @@ implements   ExceptionInfoVisitor,
             catch (RuntimeException ex)
             {
                 System.err.println("Unexpected error while performing partial evaluation:");
-                System.err.println("  ClassFile   = ["+classFile.getName()+"]");
+                System.err.println("  Class       = ["+classFile.getName()+"]");
                 System.err.println("  Method      = ["+methodInfo.getName(classFile)+methodInfo.getDescriptor(classFile)+"]");
                 System.err.println("  Instruction = "+instruction.toString(instructionOffset));
+                System.err.println("  Exception   = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")");
 
                 throw ex;
             }
@@ -570,7 +705,7 @@ implements   ExceptionInfoVisitor,
 
                 if (varProducerValues[instructionOffset].instructionOffsetCount() > 0)
                 {
-                    System.out.println("     has up til now been using information from instructions setting vars: "+varProducerValues[instructionOffset]);
+                    System.out.println("     has up till now been using information from instructions setting vars: "+varProducerValues[instructionOffset]);
                 }
                 if (stackProducerValues[instructionOffset].instructionOffsetCount() > 0)
                 {
@@ -585,57 +720,33 @@ implements   ExceptionInfoVisitor,
                     System.out.println("     has up till now been branching to "+branchTargetValues[instructionOffset]);
                 }
 
-                System.out.println("     Vars:  "+variables);
-                System.out.println("     Stack: "+stack);
+                System.out.println(" Vars:  "+variables);
+                System.out.println(" Stack: "+stack);
             }
 
             // Maintain a generalized local variable frame and stack at this
-            // branch instruction offset.
-            if (vars[instructionOffset] == null)
-            {
-                // First time we're passing by this instruction.
-                // There's not even a context at this index yet.
-                vars[instructionOffset]   = new TracedVariables(variables);
-                stacks[instructionOffset] = new TracedStack(stack);
-            }
-            else if (evaluationCount == 0)
+            // instruction offset, after execution.
+            if (evaluationCount == 0)
             {
                 // First time we're passing by this instruction.
-                // Reuse the context objects at this index.
-                vars[instructionOffset].initialize(variables);
-                stacks[instructionOffset].copy(stack);
+                if (variablesAfter[instructionOffset] == null)
+                {
+                    // There's not even a context at this index yet.
+                    variablesAfter[instructionOffset] = new TracedVariables(variables);
+                    stacksAfter[instructionOffset]    = new TracedStack(stack);
+                }
+                else
+                {
+                    // Reuse the context objects at this index.
+                    variablesAfter[instructionOffset].initialize(variables);
+                    stacksAfter[instructionOffset].copy(stack);
+                }
             }
             else
             {
-                // If there are multiple alternative branches, or if this
-                // instruction has been evaluated an excessive number of
-                // times, then generalize the current context.
-                // TODO: See if we can avoid generalizing the current context.
-                //if (branchTargetCount > 1 ||
-                //    evaluationCount > MAXIMUM_EVALUATION_COUNT)
-                //{
-                //    variables.generalize(vars[instructionOffset]);
-                //    stack.generalize(stacks[instructionOffset]);
-                //}
-
-                boolean vars_changed  = vars[instructionOffset].generalize(variables);
-                boolean stack_changed = stacks[instructionOffset].generalize(stack);
-
-                // Bail out if the current context is the same as last time.
-                if (!vars_changed  &&
-                    !stack_changed &&
-                    branchTargets.equals(branchTargetValues[instructionOffset]))
-                {
-                    if (DEBUG) System.out.println("Repeated variables, stack, and branch targets");
-
-                    break;
-                }
-
-                // Generalize the current context. Note that the most recent
-                // variable values have to remain last in the generalizations,
-                // for the sake of the ret instruction.
-                variables.initialize(vars[instructionOffset]);
-                stack.copy(stacks[instructionOffset]);
+                // Merge in the current context.
+                variablesAfter[instructionOffset].generalize(variables);
+                stacksAfter[instructionOffset].generalize(stack);
             }
 
             // Did the branch unit get called?
@@ -654,7 +765,7 @@ implements   ExceptionInfoVisitor,
                 }
 
                 // Accumulate the branch origins at the branch target offsets.
-                InstructionOffsetValue instructionOffsetValue = InstructionOffsetValueFactory.create(instructionOffset);
+                InstructionOffsetValue instructionOffsetValue = new InstructionOffsetValue(instructionOffset);
                 for (int index = 0; index < branchTargetCount; index++)
                 {
                     int branchTarget = branchTargets.instructionOffset(index);
@@ -711,20 +822,26 @@ implements   ExceptionInfoVisitor,
         }
 
         // Create new arrays for storing information at each instruction offset.
-        if (vars.length < codeLength)
+        if (variablesAfter.length < codeLength)
         {
             varProducerValues    = new InstructionOffsetValue[codeLength];
             stackProducerValues  = new InstructionOffsetValue[codeLength];
             unusedProducerValues = new InstructionOffsetValue[codeLength];
             branchOriginValues   = new InstructionOffsetValue[codeLength];
             branchTargetValues   = new InstructionOffsetValue[codeLength];
-            vars                 = new TracedVariables[codeLength];
-            stacks               = new TracedStack[codeLength];
+            variablesBefore      = new TracedVariables[codeLength];
+            stacksBefore         = new TracedStack[codeLength];
+            variablesAfter       = new TracedVariables[codeLength];
+            stacksAfter          = new TracedStack[codeLength];
+            generalizedContexts  = new boolean[codeLength];
             evaluationCounts     = new int[codeLength];
             initializedVariables = new int[codeLength];
 
             for (int index = 0; index < codeLength; index++)
             {
+                varProducerValues[index]    = InstructionOffsetValueFactory.create();
+                stackProducerValues[index]  = InstructionOffsetValueFactory.create();
+                unusedProducerValues[index] = InstructionOffsetValueFactory.create();
                 initializedVariables[index] = NONE;
             }
         }
@@ -732,22 +849,33 @@ implements   ExceptionInfoVisitor,
         {
             for (int index = 0; index < codeLength; index++)
             {
-                varProducerValues[index]    = null;
-                stackProducerValues[index]  = null;
-                unusedProducerValues[index] = null;
+                varProducerValues[index]    = InstructionOffsetValueFactory.create();
+                stackProducerValues[index]  = InstructionOffsetValueFactory.create();
+                unusedProducerValues[index] = InstructionOffsetValueFactory.create();
                 branchOriginValues[index]   = null;
                 branchTargetValues[index]   = null;
+                generalizedContexts[index]  = false;
                 evaluationCounts[index]     = 0;
                 initializedVariables[index] = NONE;
 
-                if (vars[index] != null)
+                if (variablesBefore[index] != null)
+                {
+                    variablesBefore[index].reset(codeAttrInfo.u2maxLocals);
+                }
+
+                if (stacksBefore[index] != null)
+                {
+                    stacksBefore[index].reset(codeAttrInfo.u2maxStack);
+                }
+
+                if (variablesAfter[index] != null)
                 {
-                    vars[index].reset(codeAttrInfo.u2maxLocals);
+                    variablesAfter[index].reset(codeAttrInfo.u2maxLocals);
                 }
 
-                if (stacks[index] != null)
+                if (stacksAfter[index] != null)
                 {
-                    stacks[index].reset(codeAttrInfo.u2maxStack);
+                    stacksAfter[index].reset(codeAttrInfo.u2maxStack);
                 }
             }
         }
@@ -784,7 +912,7 @@ implements   ExceptionInfoVisitor,
                 // We can't use the return value, because local generalization
                 // can be different a couple of times, with the global
                 // generalization being the same.
-                generalizedVariables.generalize(vars[index]);
+                generalizedVariables.generalize(variablesBefore[index]);
             }
         }
     }
diff --git a/src/proguard/optimize/evaluation/Processor.java b/src/proguard/optimize/evaluation/Processor.java
index 3703855..66ba5e0 100644
--- a/src/proguard/optimize/evaluation/Processor.java
+++ b/src/proguard/optimize/evaluation/Processor.java
@@ -1,8 +1,8 @@
-/* $Id: Processor.java,v 1.13 2005/06/11 13:13:16 eric Exp $
+/* $Id: Processor.java,v 1.13.2.2 2006/04/01 12:40:37 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -758,23 +758,27 @@ implements   InstructionVisitor,
 
 
             case InstructionConstants.OP_IFICMPLT:
+                // Note that the stack entries are popped in reverse order.
                 branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget,
-                    -stack.ipop().lessThan(stack.ipop()));
+                    stack.ipop().greaterThan(stack.ipop()));
                 break;
 
             case InstructionConstants.OP_IFICMPGE:
+                // Note that the stack entries are popped in reverse order.
                 branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget,
-                    -stack.ipop().greaterThanOrEqual(stack.ipop()));
+                    stack.ipop().lessThanOrEqual(stack.ipop()));
                 break;
 
             case InstructionConstants.OP_IFICMPGT:
+                // Note that the stack entries are popped in reverse order.
                 branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget,
-                    -stack.ipop().greaterThan(stack.ipop()));
+                    stack.ipop().lessThan(stack.ipop()));
                 break;
 
             case InstructionConstants.OP_IFICMPLE:
+                // Note that the stack entries are popped in reverse order.
                 branchUnit.branchConditionally(classFile, codeAttrInfo, offset, branchTarget,
-                    -stack.ipop().lessThanOrEqual(stack.ipop()));
+                    stack.ipop().greaterThanOrEqual(stack.ipop()));
                 break;
 
             case InstructionConstants.OP_IFACMPEQ:
diff --git a/src/proguard/optimize/evaluation/Stack.java b/src/proguard/optimize/evaluation/Stack.java
index 0735010..0a94071 100644
--- a/src/proguard/optimize/evaluation/Stack.java
+++ b/src/proguard/optimize/evaluation/Stack.java
@@ -1,8 +1,8 @@
-/* $Id: Stack.java,v 1.8 2005/06/11 13:13:16 eric Exp $
+/* $Id: Stack.java,v 1.8.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/TracedBranchUnit.java b/src/proguard/optimize/evaluation/TracedBranchUnit.java
index 990f1f1..d0e4205 100644
--- a/src/proguard/optimize/evaluation/TracedBranchUnit.java
+++ b/src/proguard/optimize/evaluation/TracedBranchUnit.java
@@ -1,8 +1,8 @@
-/* $Id: TracedBranchUnit.java,v 1.5 2005/06/11 13:13:16 eric Exp $
+/* $Id: TracedBranchUnit.java,v 1.5.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/TracedStack.java b/src/proguard/optimize/evaluation/TracedStack.java
index f6db30c..327f2d8 100644
--- a/src/proguard/optimize/evaluation/TracedStack.java
+++ b/src/proguard/optimize/evaluation/TracedStack.java
@@ -1,8 +1,8 @@
-/* $Id: TracedStack.java,v 1.10 2005/10/22 11:55:29 eric Exp $
+/* $Id: TracedStack.java,v 1.10.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/TracedVariables.java b/src/proguard/optimize/evaluation/TracedVariables.java
index 8066508..436056c 100644
--- a/src/proguard/optimize/evaluation/TracedVariables.java
+++ b/src/proguard/optimize/evaluation/TracedVariables.java
@@ -1,8 +1,8 @@
-/* $Id: TracedVariables.java,v 1.10 2005/10/22 11:55:29 eric Exp $
+/* $Id: TracedVariables.java,v 1.10.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/UnusedParameterCleaner.java b/src/proguard/optimize/evaluation/UnusedParameterCleaner.java
index b4b5619..ac134fe 100644
--- a/src/proguard/optimize/evaluation/UnusedParameterCleaner.java
+++ b/src/proguard/optimize/evaluation/UnusedParameterCleaner.java
@@ -1,8 +1,8 @@
-/* $Id: UnusedParameterCleaner.java,v 1.5 2005/10/22 11:55:29 eric Exp $
+/* $Id: UnusedParameterCleaner.java,v 1.5.2.2 2006/08/10 20:53:12 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -141,7 +141,7 @@ implements   InstructionVisitor,
         // Loop over all parameters.
         for (int index = 0; index < parameterSize; index++)
         {
-            if ((usedParameters & (1 << index)) == 0)
+            if ((usedParameters & (1L << index)) == 0)
             {
                 int stackIndex = parameterSize - index - 1;
 
diff --git a/src/proguard/optimize/evaluation/Variables.java b/src/proguard/optimize/evaluation/Variables.java
index 40d5eb5..5bf4545 100644
--- a/src/proguard/optimize/evaluation/Variables.java
+++ b/src/proguard/optimize/evaluation/Variables.java
@@ -1,8 +1,8 @@
-/* $Id: Variables.java,v 1.7 2005/06/11 13:13:16 eric Exp $
+/* $Id: Variables.java,v 1.7.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/Category1Value.java b/src/proguard/optimize/evaluation/value/Category1Value.java
index feffd9b..e65d95c 100644
--- a/src/proguard/optimize/evaluation/value/Category1Value.java
+++ b/src/proguard/optimize/evaluation/value/Category1Value.java
@@ -1,8 +1,8 @@
-/* $Id: Category1Value.java,v 1.4 2005/10/22 11:55:29 eric Exp $
+/* $Id: Category1Value.java,v 1.4.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/Category2Value.java b/src/proguard/optimize/evaluation/value/Category2Value.java
index 3857132..69b78ca 100644
--- a/src/proguard/optimize/evaluation/value/Category2Value.java
+++ b/src/proguard/optimize/evaluation/value/Category2Value.java
@@ -1,8 +1,8 @@
-/* $Id: Category2Value.java,v 1.4 2005/10/22 11:55:29 eric Exp $
+/* $Id: Category2Value.java,v 1.4.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/DoubleValue.java b/src/proguard/optimize/evaluation/value/DoubleValue.java
index 8c90f8b..5b046d5 100644
--- a/src/proguard/optimize/evaluation/value/DoubleValue.java
+++ b/src/proguard/optimize/evaluation/value/DoubleValue.java
@@ -1,8 +1,8 @@
-/* $Id: DoubleValue.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: DoubleValue.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/DoubleValueFactory.java b/src/proguard/optimize/evaluation/value/DoubleValueFactory.java
index 46e19ea..172f0c6 100644
--- a/src/proguard/optimize/evaluation/value/DoubleValueFactory.java
+++ b/src/proguard/optimize/evaluation/value/DoubleValueFactory.java
@@ -1,8 +1,8 @@
-/* $Id: DoubleValueFactory.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: DoubleValueFactory.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/FloatValue.java b/src/proguard/optimize/evaluation/value/FloatValue.java
index 80ae8a6..9e66d86 100644
--- a/src/proguard/optimize/evaluation/value/FloatValue.java
+++ b/src/proguard/optimize/evaluation/value/FloatValue.java
@@ -1,8 +1,8 @@
-/* $Id: FloatValue.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: FloatValue.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/FloatValueFactory.java b/src/proguard/optimize/evaluation/value/FloatValueFactory.java
index b897f8c..5fb0141 100644
--- a/src/proguard/optimize/evaluation/value/FloatValueFactory.java
+++ b/src/proguard/optimize/evaluation/value/FloatValueFactory.java
@@ -1,8 +1,8 @@
-/* $Id: FloatValueFactory.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: FloatValueFactory.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/InstructionOffsetValue.java b/src/proguard/optimize/evaluation/value/InstructionOffsetValue.java
index 072be6d..c30b7b4 100644
--- a/src/proguard/optimize/evaluation/value/InstructionOffsetValue.java
+++ b/src/proguard/optimize/evaluation/value/InstructionOffsetValue.java
@@ -1,8 +1,8 @@
-/* $Id: InstructionOffsetValue.java,v 1.7 2005/06/11 13:13:16 eric Exp $
+/* $Id: InstructionOffsetValue.java,v 1.7.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/InstructionOffsetValueFactory.java b/src/proguard/optimize/evaluation/value/InstructionOffsetValueFactory.java
index dd0f114..3fdfe03 100644
--- a/src/proguard/optimize/evaluation/value/InstructionOffsetValueFactory.java
+++ b/src/proguard/optimize/evaluation/value/InstructionOffsetValueFactory.java
@@ -1,8 +1,8 @@
-/* $Id: InstructionOffsetValueFactory.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: InstructionOffsetValueFactory.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/IntegerValue.java b/src/proguard/optimize/evaluation/value/IntegerValue.java
index 24e3385..6f1016e 100644
--- a/src/proguard/optimize/evaluation/value/IntegerValue.java
+++ b/src/proguard/optimize/evaluation/value/IntegerValue.java
@@ -1,8 +1,8 @@
-/* $Id: IntegerValue.java,v 1.4 2005/06/11 13:13:16 eric Exp $
+/* $Id: IntegerValue.java,v 1.4.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/IntegerValueFactory.java b/src/proguard/optimize/evaluation/value/IntegerValueFactory.java
index b83a09c..13bc391 100644
--- a/src/proguard/optimize/evaluation/value/IntegerValueFactory.java
+++ b/src/proguard/optimize/evaluation/value/IntegerValueFactory.java
@@ -1,8 +1,8 @@
-/* $Id: IntegerValueFactory.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: IntegerValueFactory.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/LongValue.java b/src/proguard/optimize/evaluation/value/LongValue.java
index 1fc78e8..d7495dd 100644
--- a/src/proguard/optimize/evaluation/value/LongValue.java
+++ b/src/proguard/optimize/evaluation/value/LongValue.java
@@ -1,8 +1,8 @@
-/* $Id: LongValue.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: LongValue.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/LongValueFactory.java b/src/proguard/optimize/evaluation/value/LongValueFactory.java
index 0d396ac..7955c5f 100644
--- a/src/proguard/optimize/evaluation/value/LongValueFactory.java
+++ b/src/proguard/optimize/evaluation/value/LongValueFactory.java
@@ -1,8 +1,8 @@
-/* $Id: LongValueFactory.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: LongValueFactory.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/ReferenceValue.java b/src/proguard/optimize/evaluation/value/ReferenceValue.java
index 6267052..070fa14 100644
--- a/src/proguard/optimize/evaluation/value/ReferenceValue.java
+++ b/src/proguard/optimize/evaluation/value/ReferenceValue.java
@@ -1,8 +1,8 @@
-/* $Id: ReferenceValue.java,v 1.4 2005/06/11 13:13:16 eric Exp $
+/* $Id: ReferenceValue.java,v 1.4.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/ReferenceValueFactory.java b/src/proguard/optimize/evaluation/value/ReferenceValueFactory.java
index da0c2e8..0f765a4 100644
--- a/src/proguard/optimize/evaluation/value/ReferenceValueFactory.java
+++ b/src/proguard/optimize/evaluation/value/ReferenceValueFactory.java
@@ -1,8 +1,8 @@
-/* $Id: ReferenceValueFactory.java,v 1.5 2005/06/11 13:13:16 eric Exp $
+/* $Id: ReferenceValueFactory.java,v 1.5.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/SpecificArrayReferenceValue.java b/src/proguard/optimize/evaluation/value/SpecificArrayReferenceValue.java
index 53a5c22..3f9b023 100644
--- a/src/proguard/optimize/evaluation/value/SpecificArrayReferenceValue.java
+++ b/src/proguard/optimize/evaluation/value/SpecificArrayReferenceValue.java
@@ -1,8 +1,8 @@
-/* $Id: SpecificArrayReferenceValue.java,v 1.5 2005/06/11 13:13:16 eric Exp $
+/* $Id: SpecificArrayReferenceValue.java,v 1.5.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/SpecificDoubleValue.java b/src/proguard/optimize/evaluation/value/SpecificDoubleValue.java
index a61b995..3de7a31 100644
--- a/src/proguard/optimize/evaluation/value/SpecificDoubleValue.java
+++ b/src/proguard/optimize/evaluation/value/SpecificDoubleValue.java
@@ -1,8 +1,8 @@
-/* $Id: SpecificDoubleValue.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: SpecificDoubleValue.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/SpecificFloatValue.java b/src/proguard/optimize/evaluation/value/SpecificFloatValue.java
index 229bdb4..b444e47 100644
--- a/src/proguard/optimize/evaluation/value/SpecificFloatValue.java
+++ b/src/proguard/optimize/evaluation/value/SpecificFloatValue.java
@@ -1,8 +1,8 @@
-/* $Id: SpecificFloatValue.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: SpecificFloatValue.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/SpecificIntegerValue.java b/src/proguard/optimize/evaluation/value/SpecificIntegerValue.java
index a596a39..66663e7 100644
--- a/src/proguard/optimize/evaluation/value/SpecificIntegerValue.java
+++ b/src/proguard/optimize/evaluation/value/SpecificIntegerValue.java
@@ -1,8 +1,8 @@
-/* $Id: SpecificIntegerValue.java,v 1.4 2005/06/11 13:13:16 eric Exp $
+/* $Id: SpecificIntegerValue.java,v 1.4.2.2 2006/01/27 23:34:31 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -165,12 +165,12 @@ class SpecificIntegerValue extends IntegerValue
 
     public int lessThan(IntegerValue other)
     {
-        return other.greaterThanOrEqual(this);
+        return other.greaterThan(this);
     }
 
     public int lessThanOrEqual(IntegerValue other)
     {
-        return other.greaterThan(this);
+        return other.greaterThanOrEqual(this);
     }
 
 
diff --git a/src/proguard/optimize/evaluation/value/SpecificLongValue.java b/src/proguard/optimize/evaluation/value/SpecificLongValue.java
index c9de331..0546813 100644
--- a/src/proguard/optimize/evaluation/value/SpecificLongValue.java
+++ b/src/proguard/optimize/evaluation/value/SpecificLongValue.java
@@ -1,8 +1,8 @@
-/* $Id: SpecificLongValue.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: SpecificLongValue.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/SpecificReferenceValue.java b/src/proguard/optimize/evaluation/value/SpecificReferenceValue.java
index 6c0b3d1..43c2dba 100644
--- a/src/proguard/optimize/evaluation/value/SpecificReferenceValue.java
+++ b/src/proguard/optimize/evaluation/value/SpecificReferenceValue.java
@@ -1,8 +1,8 @@
-/* $Id: SpecificReferenceValue.java,v 1.5 2005/06/11 13:13:16 eric Exp $
+/* $Id: SpecificReferenceValue.java,v 1.5.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/Value.java b/src/proguard/optimize/evaluation/value/Value.java
index b9855f7..0e0032e 100644
--- a/src/proguard/optimize/evaluation/value/Value.java
+++ b/src/proguard/optimize/evaluation/value/Value.java
@@ -1,8 +1,8 @@
-/* $Id: Value.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: Value.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/evaluation/value/ValueFactory.java b/src/proguard/optimize/evaluation/value/ValueFactory.java
index f622380..0a0b99f 100644
--- a/src/proguard/optimize/evaluation/value/ValueFactory.java
+++ b/src/proguard/optimize/evaluation/value/ValueFactory.java
@@ -1,8 +1,8 @@
-/* $Id: ValueFactory.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: ValueFactory.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/BranchTargetFinder.java b/src/proguard/optimize/peephole/BranchTargetFinder.java
index f2083aa..bd1f179 100644
--- a/src/proguard/optimize/peephole/BranchTargetFinder.java
+++ b/src/proguard/optimize/peephole/BranchTargetFinder.java
@@ -1,8 +1,8 @@
-/* $Id: BranchTargetFinder.java,v 1.8 2005/08/13 20:59:45 eric Exp $
+/* $Id: BranchTargetFinder.java,v 1.8.2.2 2006/06/12 20:50:39 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -38,16 +38,20 @@ implements   AttrInfoVisitor,
              ExceptionInfoVisitor,
              CpInfoVisitor
 {
-    private static final byte INSTRUCTION       =  1;
-    private static final byte BRANCH_ORIGIN     =  2;
-    private static final byte BRANCH_TARGET     =  4;
-    private static final byte INITIALIZER       =  8;
-    private static final byte EXCEPTION_START   = 16;
-    private static final byte EXCEPTION_END     = 32;
-    private static final byte EXCEPTION_HANDLER = 64;
+    private static final short INSTRUCTION       =   1;
+    private static final short BRANCH_ORIGIN     =   2;
+    private static final short BRANCH_TARGET     =   4;
+//  private static final short AFTER_BRANCH      =   8;
+    private static final short EXCEPTION_START   =  16;
+    private static final short EXCEPTION_END     =  32;
+    private static final short EXCEPTION_HANDLER =  64;
+    private static final short SUBROUTINE_START  = 128;
+    private static final short SUBROUTINE_END    = 256;
+    private static final short INITIALIZER       = 512;
 
 
-    private byte[] instructionMarks;
+    private short[] instructionMarks;
+    private int[]   subroutineEnds;
 
     private boolean isInitializer;
 
@@ -59,7 +63,8 @@ implements   AttrInfoVisitor,
      */
     public BranchTargetFinder(int codeLength)
     {
-        instructionMarks = new byte[codeLength + 1];
+        instructionMarks = new short[codeLength + 1];
+        subroutineEnds   = new int[codeLength];
     }
 
 
@@ -138,6 +143,38 @@ implements   AttrInfoVisitor,
 
 
     /**
+     * Returns whether the instruction at the given offset is the start of a
+     * subroutine in the CodeAttribute that was visited most recently.
+     */
+    public boolean isSubroutineStart(int offset)
+    {
+        return (instructionMarks[offset] & SUBROUTINE_START) != 0;
+    }
+
+
+    /**
+     * Returns whether the instruction at the given offset is the end of a
+     * subroutine in the CodeAttribute that was visited most recently. Such an
+     * instruction is always a 'ret' instruction.
+     */
+    public boolean isSubroutineEnd(int offset)
+    {
+        return (instructionMarks[offset] & SUBROUTINE_END) != 0;
+    }
+
+
+    /**
+     * Returns the offset of the end of the subroutine that starts at the given
+     * offset, in the CodeAttribute that was visited most recently. Such an
+     * end is always at a 'ret' instruction.
+     */
+    public int subroutineEnd(int offset)
+    {
+        return subroutineEnds[offset];
+    }
+
+
+    /**
      * Returns whether the instruction at the given offset is the special
      * invocation of an instance initializer in the CodeAttrInfo that was
      * visited most recently.
@@ -172,31 +209,47 @@ implements   AttrInfoVisitor,
 
     public void visitCodeAttrInfo(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo)
     {
-        // Make sure there is a sufficiently large boolean array.
-        int length = codeAttrInfo.u4codeLength + 1;
-        if (instructionMarks.length < length)
+        // Make sure there are sufficiently large arrays.
+        int codeLength = codeAttrInfo.u4codeLength;
+        if (subroutineEnds.length < codeLength)
         {
-            // Create a new boolean array.
-            instructionMarks = new byte[length];
+            // Create a new arrays.
+            instructionMarks = new short[codeLength + 1];
+            subroutineEnds   = new int[codeLength];
         }
         else
         {
-            // Reset the boolean array.
-            for (int index = 0; index < length; index++)
+            // Reset the marks array.
+            for (int index = 0; index < codeLength; index++)
             {
                 instructionMarks[index] = 0;
             }
         }
 
-        // The first instruction and the end of the code are always branch targets.
-        instructionMarks[0]                         = BRANCH_TARGET;
-        instructionMarks[codeAttrInfo.u4codeLength] = BRANCH_TARGET;
+        // The first instruction and the end of the code are branch target
+        // sentinels.
+        instructionMarks[0]          = BRANCH_TARGET;
+        instructionMarks[codeLength] = BRANCH_TARGET;
 
         // Mark branch targets by going over all instructions.
         codeAttrInfo.instructionsAccept(classFile, methodInfo, this);
 
         // Mark branch targets in the exception table.
         codeAttrInfo.exceptionsAccept(classFile, methodInfo, this);
+
+        // Fill out the subroutine end array.
+        int subroutineEnd = codeLength - 1;
+        for (int index = codeLength - 1; index >= 0; index--)
+        {
+            // Remember the most recent subroutine end.
+            if (isSubroutineEnd(index))
+            {
+                subroutineEnd = index;
+            }
+
+            // Fill out the most recent subroutine end.
+            subroutineEnds[index] = subroutineEnd;
+        }
     }
 
 
@@ -207,9 +260,8 @@ implements   AttrInfoVisitor,
         // Mark the instruction.
         instructionMarks[offset] |= INSTRUCTION;
 
-        byte opcode = simpleInstruction.opcode;
-        if (opcode == InstructionConstants.OP_RET     ||
-            opcode == InstructionConstants.OP_IRETURN ||
+        short opcode = simpleInstruction.opcode;
+        if (opcode == InstructionConstants.OP_IRETURN ||
             opcode == InstructionConstants.OP_LRETURN ||
             opcode == InstructionConstants.OP_FRETURN ||
             opcode == InstructionConstants.OP_DRETURN ||
@@ -240,6 +292,12 @@ implements   AttrInfoVisitor,
     {
         // Mark the instruction.
         instructionMarks[offset] |= INSTRUCTION;
+
+        if (variableInstruction.opcode == InstructionConstants.OP_RET)
+        {
+            // Mark the branch origin.
+            instructionMarks[offset] |= BRANCH_ORIGIN | SUBROUTINE_END;
+        }
     }
 
 
@@ -250,6 +308,14 @@ implements   AttrInfoVisitor,
 
         // Mark the branch target.
         instructionMarks[offset + branchInstruction.branchOffset] |= BRANCH_TARGET;
+
+        byte opcode = branchInstruction.opcode;
+        if (opcode == InstructionConstants.OP_JSR ||
+            opcode == InstructionConstants.OP_JSR_W)
+        {
+            // Mark the subroutine start.
+            instructionMarks[offset + branchInstruction.branchOffset] |= SUBROUTINE_START;
+        }
     }
 
     public void visitTableSwitchInstruction(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, TableSwitchInstruction tableSwitchInstruction)
diff --git a/src/proguard/optimize/peephole/ClassFileFinalizer.java b/src/proguard/optimize/peephole/ClassFileFinalizer.java
index 5861b2f..ee7d2b1 100644
--- a/src/proguard/optimize/peephole/ClassFileFinalizer.java
+++ b/src/proguard/optimize/peephole/ClassFileFinalizer.java
@@ -1,4 +1,4 @@
-/* $Id: ClassFileFinalizer.java,v 1.8 2005/07/31 18:50:05 eric Exp $
+/* $Id: ClassFileFinalizer.java,v 1.8.2.1 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
@@ -49,7 +49,7 @@ public class ClassFileFinalizer
         this(null, null);
     }
 
-    
+
     /**
      * Creates a new ClassFileFinalizer.
      * @param extraClassFileVisitor  an optional extra visitor for all finalized
@@ -64,7 +64,7 @@ public class ClassFileFinalizer
         this.extraMemberInfoVisitor = extraMemberInfoVisitor;
     }
 
-        
+
     // Implementations for ClassFileVisitor.
 
     public void visitProgramClassFile(ProgramClassFile programClassFile)
diff --git a/src/proguard/optimize/peephole/GetterSetterInliner.java b/src/proguard/optimize/peephole/GetterSetterInliner.java
index 0fab145..9589f69 100644
--- a/src/proguard/optimize/peephole/GetterSetterInliner.java
+++ b/src/proguard/optimize/peephole/GetterSetterInliner.java
@@ -1,8 +1,8 @@
-/* $Id: GetterSetterInliner.java,v 1.18 2005/07/31 18:50:05 eric Exp $
+/* $Id: GetterSetterInliner.java,v 1.18.2.2 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -130,7 +130,7 @@ implements   InstructionVisitor,
                                                                        fieldrefCpInfoIndex).shrink();
 
                 codeAttrInfoEditor.replaceInstruction(offset, replacementInstruction);
-        
+
                 // Visit the instruction, if required.
                 if (extraInstructionVisitor != null)
                 {
diff --git a/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java b/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java
index 7dc1e93..95c243a 100644
--- a/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java
+++ b/src/proguard/optimize/peephole/GotoCommonCodeReplacer.java
@@ -1,8 +1,8 @@
-/* $Id: GotoCommonCodeReplacer.java,v 1.2 2005/10/04 21:00:11 eric Exp $
+/* $Id: GotoCommonCodeReplacer.java,v 1.2.2.5 2006/05/23 21:14:32 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -96,7 +96,7 @@ public class GotoCommonCodeReplacer implements InstructionVisitor
         {
             int branchOffset = branchInstruction.branchOffset;
             int targetOffset = offset + branchOffset;
-            
+
             // Get the number of common bytes.
             int commonCount = commonByteCodeCount(codeAttrInfo, offset, targetOffset);
 
@@ -117,7 +117,7 @@ public class GotoCommonCodeReplacer implements InstructionVisitor
                         codeAttrInfoEditor.replaceInstruction(     deleteOffset, null);
                         codeAttrInfoEditor.insertBeforeInstruction(deleteOffset, null);
                         codeAttrInfoEditor.insertAfterInstruction( deleteOffset, null);
-                        
+
                         codeAttrInfoEditor.deleteInstruction(deleteOffset);
                     }
                 }
@@ -131,7 +131,7 @@ public class GotoCommonCodeReplacer implements InstructionVisitor
                     codeAttrInfoEditor.replaceInstruction(offset,
                                                           newGotoInstruction);
                 }
-                
+
                 // Visit the instruction, if required.
                 if (extraInstructionVisitor != null)
                 {
@@ -141,12 +141,12 @@ public class GotoCommonCodeReplacer implements InstructionVisitor
         }
     }
 
-    
+
     // Small utility methods.
 
     /**
      * Returns the number of common bytes preceding the given offsets,
-     * avoiding branches and exception blocks. 
+     * avoiding branches and exception blocks.
      */
     private int commonByteCodeCount(CodeAttrInfo codeAttrInfo, int offset1, int offset2)
     {
@@ -182,30 +182,55 @@ public class GotoCommonCodeReplacer implements InstructionVisitor
                 branchTargetFinder.isInstruction(newOffset2))
             {
                 // Are the offsets involved in some branches?
-                // Note that the preverifier also doesn't like
-                // initializer invocations to be moved around.
-                if (branchTargetFinder.isBranchOrigin(newOffset1)         ||
-                    branchTargetFinder.isBranchTarget(newOffset1)         ||
-                    branchTargetFinder.isExceptionStart(newOffset1)       ||
-                    branchTargetFinder.isExceptionEnd(newOffset1)         ||
-                    branchTargetFinder.isInitializer(newOffset1)          ||
+                // Note that the preverifier doesn't like initializer
+                // invocations to be moved around.
+                // Also note that the preverifier doesn't like pop instructions
+                // that work on different operands.
+                if (branchTargetFinder.isBranchOrigin(newOffset1)   ||
+                    branchTargetFinder.isBranchTarget(newOffset1)   ||
+                    branchTargetFinder.isExceptionStart(newOffset1) ||
+                    branchTargetFinder.isExceptionEnd(newOffset1)   ||
+                    branchTargetFinder.isInitializer(newOffset1)    ||
                     branchTargetFinder.isExceptionStart(newOffset2) ||
-                    branchTargetFinder.isExceptionEnd(newOffset2))
+                    branchTargetFinder.isExceptionEnd(newOffset2)   ||
+                    isPop(code[newOffset1]))
                 {
                     break;
                 }
 
-                successfulDelta = delta;
+                // Make sure the new branch target was a branch target before,
+                // in order not to introduce new entries in the stack map table.
+                if (branchTargetFinder.isBranchTarget(newOffset2))
+                {
+                    successfulDelta = delta;
+                }
+
+                if (branchTargetFinder.isBranchTarget(newOffset1))
+                {
+                    break;
+                }
             }
         }
-        
+
         return successfulDelta;
     }
 
-    
+
+    /**
+     * Returns whether the given opcode represents a pop instruction that must
+     * get a consistent type (pop, pop2, arraylength).
+     */
+    private boolean isPop(byte opcode)
+    {
+        return opcode == InstructionConstants.OP_POP  ||
+               opcode == InstructionConstants.OP_POP2 ||
+               opcode == InstructionConstants.OP_ARRAYLENGTH;
+    }
+
+
     /**
      * Returns the whether there is a boundary of an exception block between
-     * the given offsets (including both). 
+     * the given offsets (including both).
      */
     private boolean exceptionBoundary(CodeAttrInfo codeAttrInfo, int offset1, int offset2)
     {
@@ -216,7 +241,7 @@ public class GotoCommonCodeReplacer implements InstructionVisitor
             offset1 = offset2;
             offset2 = offset;
         }
-        
+
         // Check if there is a boundary of an exception block.
         for (int offset = offset1; offset <= offset2; offset++)
         {
@@ -226,7 +251,7 @@ public class GotoCommonCodeReplacer implements InstructionVisitor
                 return true;
             }
         }
-        
+
         return false;
     }
 }
diff --git a/src/proguard/optimize/peephole/GotoGotoReplacer.java b/src/proguard/optimize/peephole/GotoGotoReplacer.java
index ecc8f6d..2cb099b 100644
--- a/src/proguard/optimize/peephole/GotoGotoReplacer.java
+++ b/src/proguard/optimize/peephole/GotoGotoReplacer.java
@@ -1,8 +1,8 @@
-/* $Id: GotoGotoReplacer.java,v 1.2 2005/10/04 21:40:37 eric Exp $
+/* $Id: GotoGotoReplacer.java,v 1.2.2.2 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -94,7 +94,7 @@ public class GotoGotoReplacer implements InstructionVisitor
                 {
                     // Simplify the goto instruction.
                     int targetBranchOffset   = ((BranchInstruction)targetInstruction).branchOffset;
-                    
+
                     Instruction newBranchInstruction =
                          new BranchInstruction(opcode,
                                                (branchOffset + targetBranchOffset));
diff --git a/src/proguard/optimize/peephole/GotoReturnReplacer.java b/src/proguard/optimize/peephole/GotoReturnReplacer.java
index 9b0bd5b..107a64b 100644
--- a/src/proguard/optimize/peephole/GotoReturnReplacer.java
+++ b/src/proguard/optimize/peephole/GotoReturnReplacer.java
@@ -1,8 +1,8 @@
-/* $Id: GotoReturnReplacer.java,v 1.8 2005/07/31 18:50:05 eric Exp $
+/* $Id: GotoReturnReplacer.java,v 1.8.2.2 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -100,7 +100,7 @@ public class GotoReturnReplacer implements InstructionVisitor
                              new SimpleInstruction(targetInstruction.opcode);
                         codeAttrInfoEditor.replaceInstruction(offset,
                                                               returnInstruction);
-        
+
                         // Visit the instruction, if required.
                         if (extraInstructionVisitor != null)
                         {
diff --git a/src/proguard/optimize/peephole/LoadStoreRemover.java b/src/proguard/optimize/peephole/LoadStoreRemover.java
index 86c69c0..01aaad8 100644
--- a/src/proguard/optimize/peephole/LoadStoreRemover.java
+++ b/src/proguard/optimize/peephole/LoadStoreRemover.java
@@ -1,8 +1,8 @@
-/* $Id: LoadStoreRemover.java,v 1.10 2005/07/31 18:50:05 eric Exp $
+/* $Id: LoadStoreRemover.java,v 1.10.2.2 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -109,7 +109,7 @@ public class LoadStoreRemover implements InstructionVisitor
                         // Delete both instructions.
                         codeAttrInfoEditor.deleteInstruction(offset);
                         codeAttrInfoEditor.deleteInstruction(nextOffset);
-        
+
                         // Visit the instruction, if required.
                         if (extraInstructionVisitor != null)
                         {
diff --git a/src/proguard/optimize/peephole/MethodPrivatizer.java b/src/proguard/optimize/peephole/MethodPrivatizer.java
index e2f8502..c3802c3 100644
--- a/src/proguard/optimize/peephole/MethodPrivatizer.java
+++ b/src/proguard/optimize/peephole/MethodPrivatizer.java
@@ -1,8 +1,8 @@
-/* $Id: MethodPrivatizer.java,v 1.7 2005/07/31 18:50:05 eric Exp $
+/* $Id: MethodPrivatizer.java,v 1.7.2.2 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -37,7 +37,7 @@ public class MethodPrivatizer
 {
     private MemberInfoVisitor extraMemberInfoVisitor;
 
-    
+
     /**
      * Creates a new MethodPrivatizer.
      */
@@ -46,7 +46,7 @@ public class MethodPrivatizer
         this(null);
     }
 
-    
+
     /**
      * Creates a new MethodPrivatizer.
      * @param extraMemberInfoVisitor an optional extra visitor for all privatized
@@ -57,7 +57,7 @@ public class MethodPrivatizer
         this.extraMemberInfoVisitor = extraMemberInfoVisitor;
     }
 
-        
+
     // Implementations for MemberInfoVisitor.
 
     public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo) {}
diff --git a/src/proguard/optimize/peephole/NopRemover.java b/src/proguard/optimize/peephole/NopRemover.java
index 4fe53cb..fa2272a 100644
--- a/src/proguard/optimize/peephole/NopRemover.java
+++ b/src/proguard/optimize/peephole/NopRemover.java
@@ -1,8 +1,8 @@
-/* $Id: NopRemover.java,v 1.7 2005/07/31 18:50:05 eric Exp $
+/* $Id: NopRemover.java,v 1.7.2.2 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -79,7 +79,7 @@ public class NopRemover implements InstructionVisitor
             !codeAttrInfoEditor.isModified(offset))
         {
             codeAttrInfoEditor.deleteInstruction(offset);
-        
+
             // Visit the instruction, if required.
             if (extraInstructionVisitor != null)
             {
diff --git a/src/proguard/optimize/peephole/PushPopRemover.java b/src/proguard/optimize/peephole/PushPopRemover.java
index 50f5939..27a1bed 100644
--- a/src/proguard/optimize/peephole/PushPopRemover.java
+++ b/src/proguard/optimize/peephole/PushPopRemover.java
@@ -1,8 +1,8 @@
-/* $Id: PushPopRemover.java,v 1.11 2005/07/31 18:50:05 eric Exp $
+/* $Id: PushPopRemover.java,v 1.11.2.2 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -132,7 +132,7 @@ public class PushPopRemover implements InstructionVisitor
      * if any, and if the latter is not a branch target.
      */
     private void deleteWithSubsequentPop(ClassFile    classFile,
-                                         MethodInfo   methodInfo, 
+                                         MethodInfo   methodInfo,
                                          CodeAttrInfo codeAttrInfo,
                                          int          offset,
                                          Instruction  instruction)
diff --git a/src/proguard/optimize/peephole/SingleImplementationFixer.java b/src/proguard/optimize/peephole/SingleImplementationFixer.java
index d9c156e..f12bd1a 100644
--- a/src/proguard/optimize/peephole/SingleImplementationFixer.java
+++ b/src/proguard/optimize/peephole/SingleImplementationFixer.java
@@ -1,8 +1,8 @@
-/* $Id: SingleImplementationFixer.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: SingleImplementationFixer.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/SingleImplementationInliner.java b/src/proguard/optimize/peephole/SingleImplementationInliner.java
index c26f3d8..a0c72c7 100644
--- a/src/proguard/optimize/peephole/SingleImplementationInliner.java
+++ b/src/proguard/optimize/peephole/SingleImplementationInliner.java
@@ -1,8 +1,8 @@
-/* $Id: SingleImplementationInliner.java,v 1.10 2005/06/26 16:20:23 eric Exp $
+/* $Id: SingleImplementationInliner.java,v 1.10.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/optimize/peephole/SingleImplementationMarker.java b/src/proguard/optimize/peephole/SingleImplementationMarker.java
index ce8abb0..40d267e 100644
--- a/src/proguard/optimize/peephole/SingleImplementationMarker.java
+++ b/src/proguard/optimize/peephole/SingleImplementationMarker.java
@@ -1,8 +1,8 @@
-/* $Id: SingleImplementationMarker.java,v 1.8 2005/07/31 18:50:05 eric Exp $
+/* $Id: SingleImplementationMarker.java,v 1.8.2.2 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -146,7 +146,7 @@ implements   ClassFileVisitor
         {
             System.out.println("Single implementation of ["+programClassFile.getName()+"]: ["+singleImplementationClassFile.getName()+"]");
         }
-        
+
         // Mark the interface and its single implementation.
         markSingleImplementation(programClassFile, singleImplementationClassFile);
 
diff --git a/src/proguard/optimize/peephole/StoreLoadReplacer.java b/src/proguard/optimize/peephole/StoreLoadReplacer.java
index 0c4b699..f6479a4 100644
--- a/src/proguard/optimize/peephole/StoreLoadReplacer.java
+++ b/src/proguard/optimize/peephole/StoreLoadReplacer.java
@@ -1,8 +1,8 @@
-/* $Id: StoreLoadReplacer.java,v 1.11 2005/07/31 18:50:05 eric Exp $
+/* $Id: StoreLoadReplacer.java,v 1.11.2.2 2006/02/13 00:20:43 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -127,7 +127,7 @@ public class StoreLoadReplacer implements InstructionVisitor
 
                         codeAttrInfoEditor.replaceInstruction(nextOffset,
                                                               storeInstruction);
-        
+
                         // Visit the instruction, if required.
                         if (extraInstructionVisitor != null)
                         {
diff --git a/src/proguard/retrace/ReTrace.java b/src/proguard/retrace/ReTrace.java
index 6bad1e2..98d8ccd 100644
--- a/src/proguard/retrace/ReTrace.java
+++ b/src/proguard/retrace/ReTrace.java
@@ -1,8 +1,8 @@
-/* $Id: ReTrace.java,v 1.10 2005/06/11 13:21:35 eric Exp $
+/* $Id: ReTrace.java,v 1.10.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/retrace/StackTrace.java b/src/proguard/retrace/StackTrace.java
index 45097d2..fc6d8f3 100644
--- a/src/proguard/retrace/StackTrace.java
+++ b/src/proguard/retrace/StackTrace.java
@@ -1,8 +1,8 @@
-/* $Id: StackTrace.java,v 1.8 2005/06/11 13:13:16 eric Exp $
+/* $Id: StackTrace.java,v 1.8.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/retrace/StackTraceItem.java b/src/proguard/retrace/StackTraceItem.java
index 4031aae..c6b580e 100644
--- a/src/proguard/retrace/StackTraceItem.java
+++ b/src/proguard/retrace/StackTraceItem.java
@@ -1,8 +1,8 @@
-/* $Id: StackTraceItem.java,v 1.9 2005/06/11 13:13:16 eric Exp $
+/* $Id: StackTraceItem.java,v 1.9.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/ClassFileShrinker.java b/src/proguard/shrink/ClassFileShrinker.java
index 4525057..d81175a 100644
--- a/src/proguard/shrink/ClassFileShrinker.java
+++ b/src/proguard/shrink/ClassFileShrinker.java
@@ -1,8 +1,8 @@
-/* $Id: ClassFileShrinker.java,v 1.27 2005/06/11 13:13:16 eric Exp $
+/* $Id: ClassFileShrinker.java,v 1.27.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/InnerUsageMarker.java b/src/proguard/shrink/InnerUsageMarker.java
index 43b6166..b7af318 100644
--- a/src/proguard/shrink/InnerUsageMarker.java
+++ b/src/proguard/shrink/InnerUsageMarker.java
@@ -1,8 +1,8 @@
-/* $Id: InnerUsageMarker.java,v 1.18 2005/06/11 13:21:35 eric Exp $
+/* $Id: InnerUsageMarker.java,v 1.18.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/InterfaceUsageMarker.java b/src/proguard/shrink/InterfaceUsageMarker.java
index c35ade1..7d7c2ee 100644
--- a/src/proguard/shrink/InterfaceUsageMarker.java
+++ b/src/proguard/shrink/InterfaceUsageMarker.java
@@ -1,8 +1,8 @@
-/* $Id: InterfaceUsageMarker.java,v 1.14 2005/06/26 16:20:23 eric Exp $
+/* $Id: InterfaceUsageMarker.java,v 1.14.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/ShortestUsageMark.java b/src/proguard/shrink/ShortestUsageMark.java
index f179ddc..e571df0 100644
--- a/src/proguard/shrink/ShortestUsageMark.java
+++ b/src/proguard/shrink/ShortestUsageMark.java
@@ -1,8 +1,8 @@
-/* $Id: ShortestUsageMark.java,v 1.4 2005/06/11 13:21:35 eric Exp $
+/* $Id: ShortestUsageMark.java,v 1.4.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/ShortestUsageMarker.java b/src/proguard/shrink/ShortestUsageMarker.java
index 0cd94a1..87e76d0 100644
--- a/src/proguard/shrink/ShortestUsageMarker.java
+++ b/src/proguard/shrink/ShortestUsageMarker.java
@@ -1,8 +1,8 @@
-/* $Id: ShortestUsageMarker.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: ShortestUsageMarker.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/ShortestUsagePrinter.java b/src/proguard/shrink/ShortestUsagePrinter.java
index b92dcb8..c825a31 100644
--- a/src/proguard/shrink/ShortestUsagePrinter.java
+++ b/src/proguard/shrink/ShortestUsagePrinter.java
@@ -1,8 +1,8 @@
-/* $Id: ShortestUsagePrinter.java,v 1.3 2005/06/11 13:21:35 eric Exp $
+/* $Id: ShortestUsagePrinter.java,v 1.3.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/Shrinker.java b/src/proguard/shrink/Shrinker.java
index 8d7e6a8..5c49036 100644
--- a/src/proguard/shrink/Shrinker.java
+++ b/src/proguard/shrink/Shrinker.java
@@ -1,8 +1,8 @@
-/* $Id: Shrinker.java,v 1.1 2005/07/24 12:54:51 eric Exp $
+/* $Id: Shrinker.java,v 1.1.2.3 2006/11/25 16:56:11 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -117,9 +117,9 @@ public class Shrinker
             new MultiClassFileVisitor(
             new ClassFileVisitor[] {
                 new ClassFileShrinker(usageMarker, 1024),
-                new ClassPoolFiller(newProgramClassPool, false)
+                new ClassPoolFiller(newProgramClassPool)
             })));
-        
+
         return newProgramClassPool;
     }
 
diff --git a/src/proguard/shrink/UsageMarker.java b/src/proguard/shrink/UsageMarker.java
index cbad551..89561dc 100644
--- a/src/proguard/shrink/UsageMarker.java
+++ b/src/proguard/shrink/UsageMarker.java
@@ -1,8 +1,8 @@
-/* $Id: UsageMarker.java,v 1.46 2005/06/26 16:19:24 eric Exp $
+/* $Id: UsageMarker.java,v 1.46.2.3 2006/10/14 12:33:22 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -178,10 +178,10 @@ public class UsageMarker
     private class MyPossiblyUsedMethodUsageMarker implements MemberInfoVisitor
     {
         // Implementations for MemberInfoVisitor.
-    
+
         public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo) {}
-    
-    
+
+
         public void visitProgramMethodInfo(ProgramClassFile programClassFile, ProgramMethodInfo programMethodInfo)
         {
             // Has the method already been referenced?
@@ -191,18 +191,18 @@ public class UsageMarker
 
                 // Mark the method body.
                 markProgramMethodBody(programClassFile, programMethodInfo);
-                
+
                 // Note that, if the method has been marked as possibly used,
                 // the method hierarchy has already been marked (cfr. below).
             }
         }
-    
-    
+
+
         public void visitLibraryFieldInfo(LibraryClassFile libraryClassFile, LibraryFieldInfo libraryFieldInfo) {}
         public void visitLibraryMethodInfo(LibraryClassFile libraryClassFile, LibraryMethodInfo libraryMethodInfo) {}
     }
 
-    
+
     // Implementations for MemberInfoVisitor.
 
     public void visitProgramFieldInfo(ProgramClassFile programClassFile, ProgramFieldInfo programFieldInfo)
@@ -239,7 +239,7 @@ public class UsageMarker
                 // Mark the method hierarchy.
                 markMethodHierarchy(programClassFile, programMethodInfo);
             }
-            
+
             // Hasn't the method been marked as possibly being used yet?
             else if (shouldBeMarkedAsPossiblyUsed(programMethodInfo))
             {
@@ -688,6 +688,9 @@ public class UsageMarker
     {
         markCpEntry(classFile, annotation.u2typeIndex);
 
+        // Mark the annotation class.
+        annotation.referencedClassFileAccept(this);
+
         // Mark the constant pool entries referenced by the element values.
         annotation.elementValuesAccept(classFile, this);
     }
@@ -700,6 +703,9 @@ public class UsageMarker
         if (constantElementValue.u2elementName != 0)
         {
             markCpEntry(classFile, constantElementValue.u2elementName);
+
+            // Mark the annotation method.
+            constantElementValue.referencedMethodInfoAccept(this);
         }
 
         markCpEntry(classFile, constantElementValue.u2constantValueIndex);
@@ -711,6 +717,9 @@ public class UsageMarker
         if (enumConstantElementValue.u2elementName != 0)
         {
             markCpEntry(classFile, enumConstantElementValue.u2elementName);
+
+            // Mark the annotation method.
+            enumConstantElementValue.referencedMethodInfoAccept(this);
         }
 
         markCpEntry(classFile, enumConstantElementValue.u2typeNameIndex);
@@ -723,10 +732,16 @@ public class UsageMarker
         if (classElementValue.u2elementName != 0)
         {
             markCpEntry(classFile, classElementValue.u2elementName);
+
+            // Mark the annotation method.
+            classElementValue.referencedMethodInfoAccept(this);
         }
 
         // Mark the referenced class constant pool entry.
         markCpEntry(classFile, classElementValue.u2classInfoIndex);
+
+        // Mark the referenced classes.
+        classElementValue.referencedClassesAccept(this);
     }
 
 
@@ -735,6 +750,9 @@ public class UsageMarker
         if (annotationElementValue.u2elementName != 0)
         {
             markCpEntry(classFile, annotationElementValue.u2elementName);
+
+            // Mark the annotation method.
+            annotationElementValue.referencedMethodInfoAccept(this);
         }
 
         // Mark the constant pool entries referenced by the annotation.
@@ -747,6 +765,9 @@ public class UsageMarker
         if (arrayElementValue.u2elementName != 0)
         {
             markCpEntry(classFile, arrayElementValue.u2elementName);
+
+            // Mark the annotation method.
+            arrayElementValue.referencedMethodInfoAccept(this);
         }
 
         // Mark the constant pool entries referenced by the element values.
diff --git a/src/proguard/shrink/UsagePrinter.java b/src/proguard/shrink/UsagePrinter.java
index 39a7c38..db460f7 100644
--- a/src/proguard/shrink/UsagePrinter.java
+++ b/src/proguard/shrink/UsagePrinter.java
@@ -1,8 +1,8 @@
-/* $Id: UsagePrinter.java,v 1.19 2005/06/11 13:21:35 eric Exp $
+/* $Id: UsagePrinter.java,v 1.19.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/shrink/UsedClassFileFilter.java b/src/proguard/shrink/UsedClassFileFilter.java
index 2379522..5a783bb 100644
--- a/src/proguard/shrink/UsedClassFileFilter.java
+++ b/src/proguard/shrink/UsedClassFileFilter.java
@@ -1,8 +1,8 @@
-/* $Id: UsedClassFileFilter.java,v 1.11 2005/06/11 13:13:16 eric Exp $
+/* $Id: UsedClassFileFilter.java,v 1.11.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/util/BasicListMatcher.java b/src/proguard/util/BasicListMatcher.java
index 3a3c44d..31035bd 100644
--- a/src/proguard/util/BasicListMatcher.java
+++ b/src/proguard/util/BasicListMatcher.java
@@ -1,4 +1,4 @@
-/* $Id: BasicListMatcher.java,v 1.7 2004/08/15 12:39:30 eric Exp $
+/* $Id: BasicListMatcher.java,v 1.8 2005/11/05 19:29:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
@@ -22,7 +22,6 @@ package proguard.util;
 
 import java.util.*;
 
-
 /**
  * This StringMatcher tests whether strings match an entry in a given list of
  * regular expressions. The list is given as a comma-separated string or as a
@@ -33,7 +32,7 @@ import java.util.*;
  * negator or not.
  * <p>
  * The individual regular expression matching is delegated to a StringMatcher
- * that is created by the {@link #createBasicMatcher(String}} method. If it is
+ * that is created by the {@link #createBasicMatcher(String)} method. If it is
  * not overridden, this method returns a BasicMatcher.
  *
  * @see BasicMatcher
diff --git a/src/proguard/util/BasicMatcher.java b/src/proguard/util/BasicMatcher.java
index b10f3e4..50b36f2 100644
--- a/src/proguard/util/BasicMatcher.java
+++ b/src/proguard/util/BasicMatcher.java
@@ -1,4 +1,4 @@
-/* $Id: BasicMatcher.java,v 1.7 2005/05/22 00:23:31 eric Exp $
+/* $Id: BasicMatcher.java,v 1.8 2005/11/05 19:29:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
@@ -22,7 +22,6 @@ package proguard.util;
 
 import java.util.*;
 
-
 /**
  * This StringMatcher tests whether strings match a given regular
  * expression. Supported wildcards are
diff --git a/src/proguard/util/ClassNameListMatcher.java b/src/proguard/util/ClassNameListMatcher.java
index 557883a..3b96c2f 100644
--- a/src/proguard/util/ClassNameListMatcher.java
+++ b/src/proguard/util/ClassNameListMatcher.java
@@ -1,4 +1,4 @@
-/* $Id: ClassNameListMatcher.java,v 1.5 2004/08/15 12:39:30 eric Exp $
+/* $Id: ClassNameListMatcher.java,v 1.6 2005/11/05 19:29:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
@@ -22,7 +22,6 @@ package proguard.util;
 
 import java.util.List;
 
-
 /**
  * This StringMatcher tests whether internal class names match any
  * entry in a given list of regular expressions.
diff --git a/src/proguard/util/ClassNameMatcher.java b/src/proguard/util/ClassNameMatcher.java
index f711300..f4a8f67 100644
--- a/src/proguard/util/ClassNameMatcher.java
+++ b/src/proguard/util/ClassNameMatcher.java
@@ -1,4 +1,4 @@
-/* $Id: ClassNameMatcher.java,v 1.5 2004/08/15 12:39:30 eric Exp $
+/* $Id: ClassNameMatcher.java,v 1.6.2.1 2006/10/18 21:12:47 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
@@ -22,7 +22,6 @@ package proguard.util;
 
 import proguard.classfile.ClassConstants;
 
-
 /**
  * This StringMatcher tests whether internal class names match a
  * given regular expression.
@@ -37,6 +36,11 @@ import proguard.classfile.ClassConstants;
  */
 public class ClassNameMatcher extends BasicMatcher
 {
+    private static final char[] CLASS_NAME_CHARACTERS = new char[]
+    {
+        ClassConstants.INTERNAL_SPECIAL_CHARACTER
+    };
+
     private static final char[] EXTENDED_CLASS_NAME_CHARACTERS = new char[]
     {
         ClassConstants.INTERNAL_PACKAGE_SEPARATOR
@@ -63,7 +67,7 @@ public class ClassNameMatcher extends BasicMatcher
     public ClassNameMatcher(String regularExpression)
     {
         super(regularExpression,
-              null,
+              CLASS_NAME_CHARACTERS,
               EXTENDED_CLASS_NAME_CHARACTERS,
               SPECIAL_PRIMITIVE_CHARACTERS);
     }
diff --git a/src/proguard/util/ExtensionMatcher.java b/src/proguard/util/ExtensionMatcher.java
index 101cb1b..28d94fb 100644
--- a/src/proguard/util/ExtensionMatcher.java
+++ b/src/proguard/util/ExtensionMatcher.java
@@ -1,8 +1,8 @@
-/* $Id: ExtensionMatcher.java,v 1.3 2005/06/11 13:13:16 eric Exp $
+/* $Id: ExtensionMatcher.java,v 1.4.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
@@ -20,9 +20,6 @@
  */
 package proguard.util;
 
-import java.util.*;
-
-
 /**
  * This StringMatcher tests whether strings end in a given extension.
  *
diff --git a/src/proguard/util/FileNameListMatcher.java b/src/proguard/util/FileNameListMatcher.java
index 765d100..5efafae 100644
--- a/src/proguard/util/FileNameListMatcher.java
+++ b/src/proguard/util/FileNameListMatcher.java
@@ -1,4 +1,4 @@
-/* $Id: FileNameListMatcher.java,v 1.5 2004/08/15 12:39:30 eric Exp $
+/* $Id: FileNameListMatcher.java,v 1.6 2005/11/05 19:29:25 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
@@ -22,7 +22,6 @@ package proguard.util;
 
 import java.util.List;
 
-
 /**
  * This StringMatcher tests whether file names match any entry in a
  * given list of regular expressions.
diff --git a/src/proguard/util/FileNameMatcher.java b/src/proguard/util/FileNameMatcher.java
index 86c6cc2..d190e68 100644
--- a/src/proguard/util/FileNameMatcher.java
+++ b/src/proguard/util/FileNameMatcher.java
@@ -1,4 +1,4 @@
-/* $Id: FileNameMatcher.java,v 1.6 2005/04/17 15:32:36 eric Exp $
+/* $Id: FileNameMatcher.java,v 1.7.2.1 2006/04/15 21:30:28 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
@@ -24,7 +24,6 @@ import proguard.classfile.ClassConstants;
 
 import java.io.*;
 
-
 /**
  * This StringMatcher tests whether file names match a given regular
  * expression.
@@ -42,6 +41,7 @@ public class FileNameMatcher extends BasicMatcher
     {
         ' ',
         '-',
+        '+',
         '.'
     };
 
diff --git a/src/proguard/util/ListUtil.java b/src/proguard/util/ListUtil.java
index e324869..db16510 100644
--- a/src/proguard/util/ListUtil.java
+++ b/src/proguard/util/ListUtil.java
@@ -1,8 +1,8 @@
-/* $Id: ListUtil.java,v 1.6 2005/06/11 13:13:16 eric Exp $
+/* $Id: ListUtil.java,v 1.6.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/wtk/ProGuardObfuscator.java b/src/proguard/wtk/ProGuardObfuscator.java
index e2e01ee..dbc2153 100644
--- a/src/proguard/wtk/ProGuardObfuscator.java
+++ b/src/proguard/wtk/ProGuardObfuscator.java
@@ -1,8 +1,8 @@
-/* $Id: ProGuardObfuscator.java,v 1.15 2005/06/11 13:13:16 eric Exp $
+/* $Id: ProGuardObfuscator.java,v 1.15.2.1 2006/01/16 22:57:56 eric Exp $
  *
  * ProGuard -- shrinking, optimization, and obfuscation of Java class files.
  *
- * Copyright (c) 2002-2005 Eric Lafortune (eric at graphics.cornell.edu)
+ * Copyright (c) 2002-2006 Eric Lafortune (eric at graphics.cornell.edu)
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/proguard.git



More information about the pkg-java-commits mailing list