aboutsummaryrefslogtreecommitdiff
path: root/java/openjdk6
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2013-03-06 00:50:28 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2013-03-06 00:50:28 +0000
commit0f7f30e0b6084a2cbd4b8718e0629ee43e430afb (patch)
treed7cc0e27c2e50cd501beef2b9faad0637d0b5537 /java/openjdk6
parent87617c6f9ad856e35e81fa55668b5a4369d303c0 (diff)
downloadports-0f7f30e0b6084a2cbd4b8718e0629ee43e430afb.tar.gz
ports-0f7f30e0b6084a2cbd4b8718e0629ee43e430afb.zip
Notes
Diffstat (limited to 'java/openjdk6')
-rw-r--r--java/openjdk6/Makefile36
-rw-r--r--java/openjdk6/files/icedtea/security/20120830/7182135-impossible_to_use_some_editors_directly.patch519
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/6563318.patch36
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/6664509.patch1322
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/6776941.patch272
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7141694.patch87
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7173145.patch22
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7186945.patch10819
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7186948.patch20
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7186952.patch127
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7186954.patch81
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7192392.patch695
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7192393.patch60
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7192977.patch436
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7197546.patch479
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7200491.patch49
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7200500.patch60
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7201064.patch117
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7201066.patch66
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7201068.patch83
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7201070.patch31
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/7201071.patch553
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/8000210.patch104
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/8000537.patch334
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/8000540.patch187
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/8000631.patch3964
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/8001235.patch37
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/8001242.patch61
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/8001307.patch27
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/8001972.patch438
-rw-r--r--java/openjdk6/files/icedtea/security/20130201/8002325.patch59
-rw-r--r--java/openjdk6/files/icedtea/security/20130219/8006446.patch395
-rw-r--r--java/openjdk6/files/icedtea/security/20130219/8006777.patch1036
-rw-r--r--java/openjdk6/files/icedtea/security/20130219/8007688.patch130
-rw-r--r--java/openjdk6/files/patch-set6
35 files changed, 22744 insertions, 4 deletions
diff --git a/java/openjdk6/Makefile b/java/openjdk6/Makefile
index cbb7444f8b41..71ad10ae9922 100644
--- a/java/openjdk6/Makefile
+++ b/java/openjdk6/Makefile
@@ -3,7 +3,7 @@
PORTNAME= openjdk6
PORTVERSION= b27
-PORTREVISION?= 1
+PORTREVISION?= 2
CATEGORIES= java devel
MASTER_SITES= http://download.java.net/openjdk/jdk6/promoted/${PORTVERSION}/ \
http://download.java.net/jaxp/openjdk/jdk6/:jaxp \
@@ -39,6 +39,40 @@ RUN_DEPENDS= javavm:${PORTSDIR}/java/javavmwrapper \
OPENJDK_BUILDDATE= 26_oct_2012
+EXTRA_PATCHES= ${FILESDIR}/icedtea/security/20120830/7182135-impossible_to_use_some_editors_directly.patch \
+ ${FILESDIR}/icedtea/security/20130201/7201068.patch \
+ ${FILESDIR}/icedtea/security/20130201/6563318.patch \
+ ${FILESDIR}/icedtea/security/20130201/6664509.patch \
+ ${FILESDIR}/icedtea/security/20130201/6776941.patch \
+ ${FILESDIR}/icedtea/security/20130201/7141694.patch \
+ ${FILESDIR}/icedtea/security/20130201/7173145.patch \
+ ${FILESDIR}/icedtea/security/20130201/7186945.patch \
+ ${FILESDIR}/icedtea/security/20130201/7186948.patch \
+ ${FILESDIR}/icedtea/security/20130201/7186952.patch \
+ ${FILESDIR}/icedtea/security/20130201/7186954.patch \
+ ${FILESDIR}/icedtea/security/20130201/7192392.patch \
+ ${FILESDIR}/icedtea/security/20130201/7192393.patch \
+ ${FILESDIR}/icedtea/security/20130201/7192977.patch \
+ ${FILESDIR}/icedtea/security/20130201/7197546.patch \
+ ${FILESDIR}/icedtea/security/20130201/7200491.patch \
+ ${FILESDIR}/icedtea/security/20130201/7200500.patch \
+ ${FILESDIR}/icedtea/security/20130201/7201064.patch \
+ ${FILESDIR}/icedtea/security/20130201/7201066.patch \
+ ${FILESDIR}/icedtea/security/20130201/7201070.patch \
+ ${FILESDIR}/icedtea/security/20130201/7201071.patch \
+ ${FILESDIR}/icedtea/security/20130201/8000210.patch \
+ ${FILESDIR}/icedtea/security/20130201/8000537.patch \
+ ${FILESDIR}/icedtea/security/20130201/8000540.patch \
+ ${FILESDIR}/icedtea/security/20130201/8000631.patch \
+ ${FILESDIR}/icedtea/security/20130201/8001242.patch \
+ ${FILESDIR}/icedtea/security/20130201/8001307.patch \
+ ${FILESDIR}/icedtea/security/20130201/8001972.patch \
+ ${FILESDIR}/icedtea/security/20130201/8002325.patch \
+ ${FILESDIR}/icedtea/security/20130201/8001235.patch \
+ ${FILESDIR}/icedtea/security/20130219/8006446.patch \
+ ${FILESDIR}/icedtea/security/20130219/8006777.patch \
+ ${FILESDIR}/icedtea/security/20130219/8007688.patch
+
OPTIONS_DEFINE= ICEDTEA IPV6 POLICY SOUND TZUPDATE
OPTIONS_DEFAULT=ICEDTEA IPV6 TZUPDATE
ICEDTEA_DESC= Apply additional patches from IcedTea
diff --git a/java/openjdk6/files/icedtea/security/20120830/7182135-impossible_to_use_some_editors_directly.patch b/java/openjdk6/files/icedtea/security/20120830/7182135-impossible_to_use_some_editors_directly.patch
new file mode 100644
index 000000000000..0653b33c02a7
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20120830/7182135-impossible_to_use_some_editors_directly.patch
@@ -0,0 +1,519 @@
+diff --git a/make/sun/Makefile b/make/sun/Makefile
+--- jdk/make/sun/Makefile
++++ jdk/make/sun/Makefile
+@@ -64,7 +64,7 @@
+ SUBDIRS = jar security javazic misc net audio $(RENDER_SUBDIR) image \
+ awt splashscreen $(XAWT_SUBDIR) $(MOTIF_SUBDIRS) \
+ $(HEADLESS_SUBDIR) $(DGA_SUBDIR) \
+- font jpeg cmm applet rmi $(JDBC_SUBDIR) \
++ font jpeg cmm applet rmi beans $(JDBC_SUBDIR) \
+ jawt text nio launcher management $(ORG_SUBDIR) \
+ native2ascii serialver tools jconsole
+
+diff --git a/make/sun/beans/Makefile b/make/sun/beans/Makefile
+new file mode 100644
+--- /dev/null
++++ jdk/make/sun/beans/Makefile
+@@ -0,0 +1,43 @@
++#
++# Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
++# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++#
++# This code is free software; you can redistribute it and/or modify it
++# under the terms of the GNU General Public License version 2 only, as
++# published by the Free Software Foundation. Oracle designates this
++# particular file as subject to the "Classpath" exception as provided
++# by Oracle in the LICENSE file that accompanied this code.
++#
++# This code 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
++# version 2 for more details (a copy is included in the LICENSE file that
++# accompanied this code).
++#
++# You should have received a copy of the GNU General Public License version
++# 2 along with this work; if not, write to the Free Software Foundation,
++# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++#
++# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++# or visit www.oracle.com if you need additional information or have any
++# questions.
++#
++
++#
++# Makefile for building sun.beans.*
++#
++
++BUILDDIR = ../..
++PACKAGE = sun.beans
++PRODUCT = sun
++include $(BUILDDIR)/common/Defs.gmk
++
++#
++# Files
++#
++AUTO_FILES_JAVA_DIRS = sun/beans
++
++#
++# Rules
++#
++include $(BUILDDIR)/common/Classes.gmk
+diff --git a/src/share/classes/com/sun/beans/editors/EnumEditor.java b/src/share/classes/com/sun/beans/editors/EnumEditor.java
+--- jdk/src/share/classes/com/sun/beans/editors/EnumEditor.java
++++ jdk/src/share/classes/com/sun/beans/editors/EnumEditor.java
+@@ -42,7 +42,7 @@
+ *
+ * @author Sergey A. Malenkov
+ */
+-public final class EnumEditor implements PropertyEditor {
++public class EnumEditor implements PropertyEditor {
+ private final List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
+
+ private final Class type;
+diff --git a/src/share/classes/sun/beans/editors/BooleanEditor.java b/src/share/classes/sun/beans/editors/BooleanEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/BooleanEditor.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++public class BooleanEditor extends com.sun.beans.editors.BooleanEditor {
++}
+diff --git a/src/share/classes/sun/beans/editors/ByteEditor.java b/src/share/classes/sun/beans/editors/ByteEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/ByteEditor.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++public class ByteEditor extends com.sun.beans.editors.ByteEditor {
++}
+diff --git a/src/share/classes/sun/beans/editors/ColorEditor.java b/src/share/classes/sun/beans/editors/ColorEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/ColorEditor.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++public class ColorEditor extends com.sun.beans.editors.ColorEditor {
++}
+diff --git a/src/share/classes/sun/beans/editors/DoubleEditor.java b/src/share/classes/sun/beans/editors/DoubleEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/DoubleEditor.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++public class DoubleEditor extends com.sun.beans.editors.DoubleEditor {
++}
+diff --git a/src/share/classes/sun/beans/editors/EnumEditor.java b/src/share/classes/sun/beans/editors/EnumEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/EnumEditor.java
+@@ -0,0 +1,35 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++public class EnumEditor extends com.sun.beans.editors.EnumEditor {
++ public EnumEditor(Class type) {
++ super(type);
++ }
++}
+diff --git a/src/share/classes/sun/beans/editors/FloatEditor.java b/src/share/classes/sun/beans/editors/FloatEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/FloatEditor.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++public class FloatEditor extends com.sun.beans.editors.FloatEditor {
++}
+diff --git a/src/share/classes/sun/beans/editors/FontEditor.java b/src/share/classes/sun/beans/editors/FontEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/FontEditor.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++public class FontEditor extends com.sun.beans.editors.FontEditor {
++}
+diff --git a/src/share/classes/sun/beans/editors/IntegerEditor.java b/src/share/classes/sun/beans/editors/IntegerEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/IntegerEditor.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++public class IntegerEditor extends com.sun.beans.editors.IntegerEditor {
++}
+diff --git a/src/share/classes/sun/beans/editors/LongEditor.java b/src/share/classes/sun/beans/editors/LongEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/LongEditor.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++public class LongEditor extends com.sun.beans.editors.LongEditor {
++}
+diff --git a/src/share/classes/sun/beans/editors/NumberEditor.java b/src/share/classes/sun/beans/editors/NumberEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/NumberEditor.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++abstract public class NumberEditor extends com.sun.beans.editors.NumberEditor {
++}
+diff --git a/src/share/classes/sun/beans/editors/ShortEditor.java b/src/share/classes/sun/beans/editors/ShortEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/ShortEditor.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++public class ShortEditor extends com.sun.beans.editors.ShortEditor {
++}
+diff --git a/src/share/classes/sun/beans/editors/StringEditor.java b/src/share/classes/sun/beans/editors/StringEditor.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/beans/editors/StringEditor.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.beans.editors;
++
++/**
++ * FOR BACKWARD COMPATIBILITY ONLY - DO NOT USE.
++ */
++public class StringEditor extends com.sun.beans.editors.StringEditor {
++}
diff --git a/java/openjdk6/files/icedtea/security/20130201/6563318.patch b/java/openjdk6/files/icedtea/security/20130201/6563318.patch
new file mode 100644
index 000000000000..8935ed6666c8
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/6563318.patch
@@ -0,0 +1,36 @@
+# HG changeset patch
+# User coffeys
+# Date 1355323250 0
+# Node ID 0da6d4cbcc77b3326756b52e6086b1262d52c214
+# Parent 042882b32f75d0e736c19f93688d37fb98d7d26d
+6563318: RMI data sanitization
+Reviewed-by: dmocek
+
+diff --git a/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java b/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java
+--- jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java
++++ jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -150,7 +150,7 @@ public final class CGIHandler {
+ returnServerError(e.getMessage());
+ }
+ else
+- returnClientError("invalid command: " + command);
++ returnClientError("Invalid command.");
+ } catch (Exception e) {
+ returnServerError("internal error: " + e.getMessage());
+ }
+@@ -217,7 +217,7 @@ final class CGIForwardCommand implements
+ try {
+ port = Integer.parseInt(param);
+ } catch (NumberFormatException e) {
+- throw new CGIClientException("invalid port number: " + param);
++ throw new CGIClientException("invalid port number.");
+ }
+ if (port <= 0 || port > 0xFFFF)
+ throw new CGIClientException("invalid port: " + port);
diff --git a/java/openjdk6/files/icedtea/security/20130201/6664509.patch b/java/openjdk6/files/icedtea/security/20130201/6664509.patch
new file mode 100644
index 000000000000..8d8f3191d014
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/6664509.patch
@@ -0,0 +1,1322 @@
+# HG changeset patch
+# User coffeys
+# Date 1355432912 0
+# Node ID eed3ef0116a18e006c4e062b3c8d6d5a5e503a43
+# Parent bedb05bba7fc681e34f9c3ce03dc2daa4ec2ce28
+6664509: Add logging context
+6664528: Find log level matching its name or value given at construction time
+Reviewed-by: mchung
+
+diff --git a/src/share/classes/java/util/logging/Level.java b/src/share/classes/java/util/logging/Level.java
+--- jdk/src/share/classes/java/util/logging/Level.java
++++ jdk/src/share/classes/java/util/logging/Level.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,10 @@
+ */
+
+ package java.util.logging;
++import java.util.ArrayList;
++import java.util.HashMap;
++import java.util.List;
++import java.util.Map;
+ import java.util.ResourceBundle;
+
+ /**
+@@ -59,7 +63,6 @@ import java.util.ResourceBundle;
+ */
+
+ public class Level implements java.io.Serializable {
+- private static java.util.ArrayList<Level> known = new java.util.ArrayList<Level>();
+ private static String defaultBundle = "sun.util.logging.resources.logging";
+
+ /**
+@@ -76,6 +79,9 @@ public class Level implements java.io.Se
+ * @serial The resource bundle name to be used in localizing the level name.
+ */
+ private final String resourceBundleName;
++
++ // localized level name
++ private String localizedLevelName;
+
+ /**
+ * OFF is a special level that can be used to turn off logging.
+@@ -202,9 +208,8 @@ public class Level implements java.io.Se
+ this.name = name;
+ this.value = value;
+ this.resourceBundleName = resourceBundleName;
+- synchronized (Level.class) {
+- known.add(this);
+- }
++ this.localizedLevelName = resourceBundleName == null ? name : null;
++ KnownLevel.add(this);
+ }
+
+ /**
+@@ -236,12 +241,76 @@ public class Level implements java.io.Se
+ * @return localized name
+ */
+ public String getLocalizedName() {
++ return getLocalizedLevelName();
++ }
++
++ // package-private getLevelName() is used by the implementation
++ // instead of getName() to avoid calling the subclass's version
++ final String getLevelName() {
++ return this.name;
++ }
++
++ final synchronized String getLocalizedLevelName() {
++ if (localizedLevelName != null) {
++ return localizedLevelName;
++ }
++
+ try {
+ ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName);
+- return rb.getString(name);
++ localizedLevelName = rb.getString(name);
+ } catch (Exception ex) {
+- return name;
++ localizedLevelName = name;
+ }
++ return localizedLevelName;
++ }
++
++ // Returns a mirrored Level object that matches the given name as
++ // specified in the Level.parse method. Returns null if not found.
++ //
++ // It returns the same Level object as the one returned by Level.parse
++ // method if the given name is a non-localized name or integer.
++ //
++ // If the name is a localized name, findLevel and parse method may
++ // return a different level value if there is a custom Level subclass
++ // that overrides Level.getLocalizedName() to return a different string
++ // than what's returned by the default implementation.
++ //
++ static Level findLevel(String name) {
++ if (name == null) {
++ throw new NullPointerException();
++ }
++
++ KnownLevel level;
++
++ // Look for a known Level with the given non-localized name.
++ level = KnownLevel.findByName(name);
++ if (level != null) {
++ return level.mirroredLevel;
++ }
++
++ // Now, check if the given name is an integer. If so,
++ // first look for a Level with the given value and then
++ // if necessary create one.
++ try {
++ int x = Integer.parseInt(name);
++ level = KnownLevel.findByValue(x);
++ if (level == null) {
++ // add new Level
++ Level levelObject = new Level(name, x);
++ level = KnownLevel.findByValue(x);
++ }
++ return level.mirroredLevel;
++ } catch (NumberFormatException ex) {
++ // Not an integer.
++ // Drop through.
++ }
++
++ level = KnownLevel.findByLocalizedLevelName(name);
++ if (level != null) {
++ return level.mirroredLevel;
++ }
++
++ return null;
+ }
+
+ /**
+@@ -266,21 +335,15 @@ public class Level implements java.io.Se
+ // Serialization magic to prevent "doppelgangers".
+ // This is a performance optimization.
+ private Object readResolve() {
+- synchronized (Level.class) {
+- for (int i = 0; i < known.size(); i++) {
+- Level other = known.get(i);
+- if (this.name.equals(other.name) && this.value == other.value
+- && (this.resourceBundleName == other.resourceBundleName ||
+- (this.resourceBundleName != null &&
+- this.resourceBundleName.equals(other.resourceBundleName)))) {
+- return other;
+- }
+- }
+- // Woops. Whoever sent us this object knows
+- // about a new log level. Add it to our list.
+- known.add(this);
+- return this;
++ KnownLevel o = KnownLevel.matches(this);
++ if (o != null) {
++ return o.levelObject;
+ }
++
++ // Woops. Whoever sent us this object knows
++ // about a new log level. Add it to our list.
++ Level level = new Level(this.name, this.value, this.resourceBundleName);
++ return level;
+ }
+
+ /**
+@@ -294,6 +357,7 @@ public class Level implements java.io.Se
+ * <li> "SEVERE"
+ * <li> "1000"
+ * </ul>
++ *
+ * @param name string to be parsed
+ * @throws NullPointerException if the name is null
+ * @throws IllegalArgumentException if the value is not valid.
+@@ -313,12 +377,12 @@ public class Level implements java.io.Se
+ // Check that name is not null.
+ name.length();
+
++ KnownLevel level;
++
+ // Look for a known Level with the given non-localized name.
+- for (int i = 0; i < known.size(); i++) {
+- Level l = known.get(i);
+- if (name.equals(l.name)) {
+- return l;
+- }
++ level = KnownLevel.findByName(name);
++ if (level != null) {
++ return level.levelObject;
+ }
+
+ // Now, check if the given name is an integer. If so,
+@@ -326,27 +390,23 @@ public class Level implements java.io.Se
+ // if necessary create one.
+ try {
+ int x = Integer.parseInt(name);
+- for (int i = 0; i < known.size(); i++) {
+- Level l = known.get(i);
+- if (l.value == x) {
+- return l;
+- }
++ level = KnownLevel.findByValue(x);
++ if (level == null) {
++ // add new Level
++ Level levelObject = new Level(name, x);
++ level = KnownLevel.findByValue(x);
+ }
+- // Create a new Level.
+- return new Level(name, x);
++ return level.levelObject;
+ } catch (NumberFormatException ex) {
+ // Not an integer.
+ // Drop through.
+ }
+-
+- // Finally, look for a known level with the given localized name,
++ // Finally, look for a known level with the given localized name,
+ // in the current default locale.
+ // This is relatively expensive, but not excessively so.
+- for (int i = 0; i < known.size(); i++) {
+- Level l = known.get(i);
+- if (name.equals(l.getLocalizedName())) {
+- return l;
+- }
++ level = KnownLevel.findByLocalizedName(name);
++ if (level != null) {
++ return level.levelObject;
+ }
+
+ // OK, we've tried everything and failed
+@@ -373,4 +433,125 @@ public class Level implements java.io.Se
+ public int hashCode() {
+ return this.value;
+ }
++
++ // KnownLevel class maintains the global list of all known levels.
++ // The API allows multiple custom Level instances of the same name/value
++ // be created. This class provides convenient methods to find a level
++ // by a given name, by a given value, or by a given localized name.
++ //
++ // KnownLevel wraps the following Level objects:
++ // 1. levelObject: standard Level object or custom Level object
++ // 2. mirroredLevel: Level object representing the level specified in the
++ // logging configuration.
++ //
++ // Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
++ // are non-final but the name and resource bundle name are parameters to
++ // the Level constructor. Use the mirroredLevel object instead of the
++ // levelObject to prevent the logging framework to execute foreign code
++ // implemented by untrusted Level subclass.
++ //
++ // Implementation Notes:
++ // If Level.getName, Level.getLocalizedName, Level.getResourceBundleName methods
++ // were final, the following KnownLevel implementation can be removed.
++ // Future API change should take this into consideration.
++ static final class KnownLevel {
++ private static Map<String, List<KnownLevel>> nameToLevels =
++ new HashMap<String, List<KnownLevel>>();
++ private static Map<Integer, List<KnownLevel>> intToLevels =
++ new HashMap<Integer, List<KnownLevel>>();
++ final Level levelObject; // instance of Level class or Level subclass
++ final Level mirroredLevel; // instance of Level class
++ KnownLevel(Level l) {
++ this.levelObject = l;
++ if (l.getClass() == Level.class) {
++ this.mirroredLevel = l;
++ } else {
++ this.mirroredLevel = new Level(l.name, l.value, l.resourceBundleName);
++ }
++ }
++
++ static synchronized void add(Level l) {
++ // the mirroredLevel object is always added to the list
++ // before the custom Level instance
++ KnownLevel o = new KnownLevel(l);
++ List<KnownLevel> list = nameToLevels.get(l.name);
++ if (list == null) {
++ list = new ArrayList<KnownLevel>();
++ nameToLevels.put(l.name, list);
++ }
++ list.add(o);
++
++ list = intToLevels.get(l.value);
++ if (list == null) {
++ list = new ArrayList<KnownLevel>();
++ intToLevels.put(l.value, list);
++ }
++ list.add(o);
++ }
++
++ // Returns a KnownLevel with the given non-localized name.
++ static synchronized KnownLevel findByName(String name) {
++ List<KnownLevel> list = nameToLevels.get(name);
++ if (list != null) {
++ return list.get(0);
++ }
++ return null;
++ }
++
++ // Returns a KnownLevel with the given value.
++ static synchronized KnownLevel findByValue(int value) {
++ List<KnownLevel> list = intToLevels.get(value);
++ if (list != null) {
++ return list.get(0);
++ }
++ return null;
++ }
++
++ // Returns a KnownLevel with the given localized name matching
++ // by calling the Level.getLocalizedLevelName() method (i.e. found
++ // from the resourceBundle associated with the Level object).
++ // This method does not call Level.getLocalizedName() that may
++ // be overridden in a subclass implementation
++ static synchronized KnownLevel findByLocalizedLevelName(String name) {
++ for (List<KnownLevel> levels : nameToLevels.values()) {
++ for (KnownLevel l : levels) {
++ String lname = l.levelObject.getLocalizedLevelName();
++ if (name.equals(lname)) {
++ return l;
++ }
++ }
++ }
++ return null;
++ }
++
++ // Returns a KnownLevel with the given localized name matching
++ // by calling the Level.getLocalizedName() method
++ static synchronized KnownLevel findByLocalizedName(String name) {
++ for (List<KnownLevel> levels : nameToLevels.values()) {
++ for (KnownLevel l : levels) {
++ String lname = l.levelObject.getLocalizedName();
++ if (name.equals(lname)) {
++ return l;
++ }
++ }
++ }
++ return null;
++ }
++
++ static synchronized KnownLevel matches(Level l) {
++ List<KnownLevel> list = nameToLevels.get(l.name);
++ if (list != null) {
++ for (KnownLevel level : list) {
++ Level other = level.mirroredLevel;
++ if (l.value == other.value &&
++ (l.resourceBundleName == other.resourceBundleName ||
++ (l.resourceBundleName != null &&
++ l.resourceBundleName.equals(other.resourceBundleName)))) {
++ return level;
++ }
++ }
++ }
++ return null;
++ }
++ }
+ }
+diff --git a/src/share/classes/java/util/logging/LogManager.java b/src/share/classes/java/util/logging/LogManager.java
+--- jdk/src/share/classes/java/util/logging/LogManager.java
++++ jdk/src/share/classes/java/util/logging/LogManager.java
+@@ -34,6 +34,8 @@ import java.beans.PropertyChangeListener
+ import java.beans.PropertyChangeListener;
+ import java.beans.PropertyChangeSupport;
+ import java.net.URL;
++import sun.misc.JavaAWTAccess;
++import sun.misc.SharedSecrets;
+ import sun.security.action.GetPropertyAction;
+
+ /**
+@@ -155,11 +157,9 @@ public class LogManager {
+ = new PropertyChangeSupport(LogManager.class);
+ private final static Level defaultLevel = Level.INFO;
+
+- // Table of named Loggers that maps names to Loggers.
+- private Hashtable<String,LoggerWeakRef> namedLoggers =
+- new Hashtable<String,LoggerWeakRef>();
+- // Tree of named Loggers
+- private LogNode root = new LogNode(null);
++ // LoggerContext for system loggers and user loggers
++ private final LoggerContext systemContext = new SystemLoggerContext();
++ private final LoggerContext userContext = new UserLoggerContext();
+ private Logger rootLogger;
+
+ // Have we done the primordial reading of the configuration file?
+@@ -197,12 +197,13 @@ public class LogManager {
+
+ // Create and retain Logger for the root of the namespace.
+ manager.rootLogger = manager.new RootLogger();
+- manager.addLogger(manager.rootLogger);
++ manager.systemContext.addLogger(manager.rootLogger);
++ manager.userContext.addLogger(manager.rootLogger);
+
+ // Adding the global Logger. Doing so in the Logger.<clinit>
+ // would deadlock with the LogManager.<clinit>.
+ Logger.global.setLogManager(manager);
+- manager.addLogger(Logger.global);
++ manager.systemContext.addLogger(Logger.global);
+
+ // We don't call readConfiguration() here, as we may be running
+ // very early in the JVM startup sequence. Instead readConfiguration
+@@ -273,8 +274,8 @@ public class LogManager {
+ }
+ readPrimordialConfiguration = true;
+ try {
+- AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+- public Object run() throws Exception {
++ AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
++ public Void run() throws Exception {
+ readConfiguration();
+ return null;
+ }
+@@ -326,6 +327,296 @@ public class LogManager {
+ changes.removePropertyChangeListener(l);
+ }
+
++ // Returns the LoggerContext for the user code (i.e. application or AppContext).
++ // Loggers are isolated from each AppContext.
++ LoggerContext getUserContext() {
++ LoggerContext context = null;
++
++ SecurityManager sm = System.getSecurityManager();
++ JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess();
++ if (sm != null && javaAwtAccess != null) {
++ synchronized (javaAwtAccess) {
++ // AppContext.getAppContext() returns the system AppContext if called
++ // from a system thread but Logger.getLogger might be called from
++ // an applet code. Instead, find the AppContext of the applet code
++ // from the execution stack.
++ Object ecx = javaAwtAccess.getExecutionContext();
++ if (ecx == null) {
++ // fall back to AppContext.getAppContext()
++ ecx = javaAwtAccess.getContext();
++ }
++ context = (LoggerContext) javaAwtAccess.get(ecx, LoggerContext.class);
++ if (context == null) {
++ if (javaAwtAccess.isMainAppContext()) {
++ context = userContext;
++ } else {
++ context = new UserLoggerContext();
++ context.addLogger(manager.rootLogger);
++ }
++ javaAwtAccess.put(ecx, LoggerContext.class, context);
++ }
++ }
++ } else {
++ context = userContext;
++ }
++ return context;
++ }
++
++ LoggerContext getSystemContext() {
++ return systemContext;
++ }
++
++ private List<LoggerContext> contexts() {
++ List<LoggerContext> cxs = new ArrayList<LoggerContext>();
++ cxs.add(systemContext);
++ cxs.add(getUserContext());
++ return cxs;
++ }
++
++ static class LoggerContext {
++ // Table of named Loggers that maps names to Loggers.
++
++ private final Hashtable<String, LoggerWeakRef> namedLoggers =
++ new Hashtable<String, LoggerWeakRef>();
++ // Tree of named Loggers
++ private final LogNode root;
++
++ private LoggerContext() {
++ this.root = new LogNode(null, this);
++ }
++
++ synchronized Logger findLogger(String name) {
++ LoggerWeakRef ref = namedLoggers.get(name);
++ if (ref == null) {
++ return null;
++ }
++ Logger logger = ref.get();
++ if (logger == null) {
++ // Hashtable holds stale weak reference
++ // to a logger which has been GC-ed.
++ removeLogger(name);
++ }
++ return logger;
++ }
++
++ synchronized boolean addLogger(Logger logger) {
++ final String name = logger.getName();
++ if (name == null) {
++ throw new NullPointerException();
++ }
++
++ // cleanup some Loggers that have been GC'ed
++ manager.drainLoggerRefQueueBounded();
++
++ LoggerWeakRef ref = namedLoggers.get(name);
++ if (ref != null) {
++ if (ref.get() == null) {
++ // It's possible that the Logger was GC'ed after the
++ // drainLoggerRefQueueBounded() call above so allow
++ // a new one to be registered.
++ removeLogger(name);
++ } else {
++ // We already have a registered logger with the given name.
++ return false;
++ }
++ }
++
++ // We're adding a new logger.
++ // Note that we are creating a weak reference here.
++ ref = manager.new LoggerWeakRef(logger);
++ namedLoggers.put(name, ref);
++
++ // Apply any initial level defined for the new logger.
++ Level level = manager.getLevelProperty(name + ".level", null);
++ if (level != null) {
++ doSetLevel(logger, level);
++ }
++
++ // Do we have a per logger handler too?
++ // Note: this will add a 200ms penalty
++ manager.loadLoggerHandlers(logger, name, name + ".handlers");
++ processParentHandlers(logger, name);
++
++ // Find the new node and its parent.
++ LogNode node = getNode(name);
++ node.loggerRef = ref;
++ Logger parent = null;
++ LogNode nodep = node.parent;
++ while (nodep != null) {
++ LoggerWeakRef nodeRef = nodep.loggerRef;
++ if (nodeRef != null) {
++ parent = nodeRef.get();
++ if (parent != null) {
++ break;
++ }
++ }
++ nodep = nodep.parent;
++ }
++
++ if (parent != null) {
++ doSetParent(logger, parent);
++ }
++ // Walk over the children and tell them we are their new parent.
++ node.walkAndSetParent(logger);
++ // new LogNode is ready so tell the LoggerWeakRef about it
++ ref.setNode(node);
++ return true;
++ }
++
++ void removeLogger(String name) {
++ namedLoggers.remove(name);
++ }
++
++ synchronized Enumeration<String> getLoggerNames() {
++ return namedLoggers.keys();
++ }
++
++ Logger demandLogger(String name) {
++ return demandLogger(name, null);
++ }
++
++ // Find or create a specified logger instance. If a logger has
++ // already been created with the given name it is returned.
++ // Otherwise a new logger instance is created and registered
++ // in the LogManager global namespace.
++ // This method will always return a non-null Logger object.
++ // Synchronization is not required here. All synchronization for
++ // adding a new Logger object is handled by addLogger().
++ Logger demandLogger(String name, String resourceBundleName) {
++ Logger result = findLogger(name);
++ if (result == null) {
++ // only allocate the new logger once
++ Logger newLogger = new Logger(name, resourceBundleName);
++ do {
++ if (addLogger(newLogger)) {
++ // We successfully added the new Logger that we
++ // created above so return it without refetching.
++ return newLogger;
++ }
++
++ // We didn't add the new Logger that we created above
++ // because another thread added a Logger with the same
++ // name after our null check above and before our call
++ // to addLogger(). We have to refetch the Logger because
++ // addLogger() returns a boolean instead of the Logger
++ // reference itself. However, if the thread that created
++ // the other Logger is not holding a strong reference to
++ // the other Logger, then it is possible for the other
++ // Logger to be GC'ed after we saw it in addLogger() and
++ // before we can refetch it. If it has been GC'ed then
++ // we'll just loop around and try again.
++ result = findLogger(name);
++ } while (result == null);
++ }
++ return result;
++ }
++
++ // If logger.getUseParentHandlers() returns 'true' and any of the logger's
++ // parents have levels or handlers defined, make sure they are instantiated.
++ private void processParentHandlers(Logger logger, String name) {
++ int ix = 1;
++ for (;;) {
++ int ix2 = name.indexOf(".", ix);
++ if (ix2 < 0) {
++ break;
++ }
++ String pname = name.substring(0, ix2);
++
++ if (manager.getProperty(pname + ".level") != null
++ || manager.getProperty(pname + ".handlers") != null) {
++ // This pname has a level/handlers definition.
++ // Make sure it exists.
++ demandLogger(pname);
++ }
++ ix = ix2 + 1;
++ }
++ }
++
++ // Gets a node in our tree of logger nodes.
++ // If necessary, create it.
++ LogNode getNode(String name) {
++ if (name == null || name.equals("")) {
++ return root;
++ }
++ LogNode node = root;
++ while (name.length() > 0) {
++ int ix = name.indexOf(".");
++ String head;
++ if (ix > 0) {
++ head = name.substring(0, ix);
++ name = name.substring(ix + 1);
++ } else {
++ head = name;
++ name = "";
++ }
++ if (node.children == null) {
++ node.children = new HashMap<String, LogNode>();
++ }
++ LogNode child = node.children.get(head);
++ if (child == null) {
++ child = new LogNode(node, this);
++ node.children.put(head, child);
++ }
++ node = child;
++ }
++ return node;
++ }
++ }
++
++ static class SystemLoggerContext extends LoggerContext {
++ // Default resource bundle for all system loggers
++
++ Logger demandLogger(String name) {
++ // default to use the system logger's resource bundle
++ return super.demandLogger(name, Logger.SYSTEM_LOGGER_RB_NAME);
++ }
++ }
++
++ static class UserLoggerContext extends LoggerContext {
++
++ /**
++ * Returns a Logger of the given name if there is one registered
++ * in this context. Otherwise, it will return the one registered
++ * in the system context if there is one. The returned Logger
++ * instance may be initialized with a different resourceBundleName.
++ * If no such logger exists, a new Logger instance will be created
++ * and registered in this context.
++ */
++ Logger demandLogger(String name, String resourceBundleName) {
++ Logger result = findLogger(name);
++ if (result == null) {
++ // use the system logger if exists; or allocate a new logger.
++ // The system logger is added to the app logger context so that
++ // any child logger created in the app logger context can have
++ // a system logger as its parent if already exist.
++ Logger logger = manager.systemContext.findLogger(name);
++ Logger newLogger =
++ logger != null ? logger : new Logger(name, resourceBundleName);
++ do {
++ if (addLogger(newLogger)) {
++ // We successfully added the new Logger that we
++ // created above so return it without refetching.
++ return newLogger;
++ }
++
++ // We didn't add the new Logger that we created above
++ // because another thread added a Logger with the same
++ // name after our null check above and before our call
++ // to addLogger(). We have to refetch the Logger because
++ // addLogger() returns a boolean instead of the Logger
++ // reference itself. However, if the thread that created
++ // the other Logger is not holding a strong reference to
++ // the other Logger, then it is possible for the other
++ // Logger to be GC'ed after we saw it in addLogger() and
++ // before we can refetch it. If it has been GC'ed then
++ // we'll just loop around and try again.
++ result = findLogger(name);
++ } while (result == null);
++ }
++ return result;
++ }
++ }
++
+ // Package-level method.
+ // Find or create a specified logger instance. If a logger has
+ // already been created with the given name it is returned.
+@@ -339,27 +630,6 @@ public class LogManager {
+ result = getLogger(name);
+ }
+ return result;
+- }
+-
+- // If logger.getUseParentHandlers() returns 'true' and any of the logger's
+- // parents have levels or handlers defined, make sure they are instantiated.
+- private void processParentHandlers(Logger logger, String name) {
+- int ix = 1;
+- for (;;) {
+- int ix2 = name.indexOf(".", ix);
+- if (ix2 < 0) {
+- break;
+- }
+- String pname = name.substring(0,ix2);
+-
+- if (getProperty(pname+".level") != null ||
+- getProperty(pname+".handlers") != null) {
+- // This pname has a level/handlers definition.
+- // Make sure it exists.
+- demandLogger(pname);
+- }
+- ix = ix2+1;
+- }
+ }
+
+ // Add new per logger handlers.
+@@ -383,16 +653,17 @@ public class LogManager {
+ try {
+ Class clz = ClassLoader.getSystemClassLoader().loadClass(word);
+ Handler hdl = (Handler) clz.newInstance();
+- try {
+- // Check if there is a property defining the
+- // this handler's level.
+- String levs = getProperty(word + ".level");
+- if (levs != null) {
+- hdl.setLevel(Level.parse(levs));
++ // Check if there is a property defining the
++ // this handler's level.
++ String levs = getProperty(word + ".level");
++ if (levs != null) {
++ Level l = Level.findLevel(levs);
++ if (l != null) {
++ hdl.setLevel(l);
++ } else {
++ // Probably a bad level. Drop through.
++ System.err.println("Can't set level for " + word);
+ }
+- } catch (Exception ex) {
+- System.err.println("Can't set level for " + word);
+- // Probably a bad level. Drop through.
+ }
+ // Add this Handler to the logger
+ logger.addHandler(hdl);
+@@ -448,7 +719,7 @@ public class LogManager {
+ if (node != null) {
+ // if we have a LogNode, then we were a named Logger
+ // so clear namedLoggers weak ref to us
+- manager.namedLoggers.remove(name);
++ node.context.removeLogger(name);
+ name = null; // clear our ref to the Logger's name
+
+ node.loggerRef = null; // clear LogNode's weak ref to us
+@@ -544,67 +815,11 @@ public class LogManager {
+ if (name == null) {
+ throw new NullPointerException();
+ }
+-
+- // cleanup some Loggers that have been GC'ed
+- drainLoggerRefQueueBounded();
+-
+- LoggerWeakRef ref = namedLoggers.get(name);
+- if (ref != null) {
+- if (ref.get() == null) {
+- // It's possible that the Logger was GC'ed after the
+- // drainLoggerRefQueueBounded() call above so allow
+- // a new one to be registered.
+- namedLoggers.remove(name);
+- } else {
+- // We already have a registered logger with the given name.
+- return false;
+- }
++ if (systemContext.findLogger(name) != null) {
++ return false;
+ }
+-
+- // We're adding a new logger.
+- // Note that we are creating a weak reference here.
+- ref = new LoggerWeakRef(logger);
+- namedLoggers.put(name, ref);
+-
+- // Apply any initial level defined for the new logger.
+- Level level = getLevelProperty(name+".level", null);
+- if (level != null) {
+- doSetLevel(logger, level);
+- }
+-
+- // Do we have a per logger handler too?
+- // Note: this will add a 200ms penalty
+- loadLoggerHandlers(logger, name, name+".handlers");
+- processParentHandlers(logger, name);
+-
+- // Find the new node and its parent.
+- LogNode node = findNode(name);
+- node.loggerRef = ref;
+- Logger parent = null;
+- LogNode nodep = node.parent;
+- while (nodep != null) {
+- LoggerWeakRef nodeRef = nodep.loggerRef;
+- if (nodeRef != null) {
+- parent = nodeRef.get();
+- if (parent != null) {
+- break;
+- }
+- }
+- nodep = nodep.parent;
+- }
+-
+- if (parent != null) {
+- doSetParent(logger, parent);
+- }
+- // Walk over the children and tell them we are their new parent.
+- node.walkAndSetParent(logger);
+-
+- // new LogNode is ready so tell the LoggerWeakRef about it
+- ref.setNode(node);
+-
+- return true;
++ return getUserContext().addLogger(logger);
+ }
+-
+
+ // Private method to set a level on a logger.
+ // If necessary, we raise privilege before doing the call.
+@@ -644,36 +859,6 @@ public class LogManager {
+ }});
+ }
+
+- // Find a node in our tree of logger nodes.
+- // If necessary, create it.
+- private LogNode findNode(String name) {
+- if (name == null || name.equals("")) {
+- return root;
+- }
+- LogNode node = root;
+- while (name.length() > 0) {
+- int ix = name.indexOf(".");
+- String head;
+- if (ix > 0) {
+- head = name.substring(0,ix);
+- name = name.substring(ix+1);
+- } else {
+- head = name;
+- name = "";
+- }
+- if (node.children == null) {
+- node.children = new HashMap<String,LogNode>();
+- }
+- LogNode child = node.children.get(head);
+- if (child == null) {
+- child = new LogNode(node);
+- node.children.put(head, child);
+- }
+- node = child;
+- }
+- return node;
+- }
+-
+ /**
+ * Method to find a named logger.
+ * <p>
+@@ -689,18 +874,16 @@ public class LogManager {
+ * @param name name of the logger
+ * @return matching logger or null if none is found
+ */
+- public synchronized Logger getLogger(String name) {
+- LoggerWeakRef ref = namedLoggers.get(name);
+- if (ref == null) {
+- return null;
+- }
+- Logger logger = ref.get();
+- if (logger == null) {
+- // Hashtable holds stale weak reference
+- // to a logger which has been GC-ed.
+- namedLoggers.remove(name);
+- }
+- return logger;
++ public Logger getLogger(String name) {
++ // return the first logger added
++ //
++ // once a system logger is added in the system context, no one can
++ // adds a logger with the same name in the global context
++ // (see LogManager.addLogger). So if there is a logger in the global
++ // context with the same name as one in the system context, it must be
++ // added before the system logger was created.
++ Logger logger = getUserContext().findLogger(name);
++ return logger != null ? logger : systemContext.findLogger(name);
+ }
+
+ /**
+@@ -719,8 +902,12 @@ public class LogManager {
+ * <p>
+ * @return enumeration of logger name strings
+ */
+- public synchronized Enumeration<String> getLoggerNames() {
+- return namedLoggers.keys();
++ public Enumeration<String> getLoggerNames() {
++ // only return unique names
++ Set<String> names =
++ new HashSet<String>(Collections.list(systemContext.getLoggerNames()));
++ names.addAll(Collections.list(getUserContext().getLoggerNames()));
++ return Collections.enumeration(names);
+ }
+
+ /**
+@@ -805,20 +992,20 @@ public class LogManager {
+ // the global handlers, if they haven't been initialized yet.
+ initializedGlobalHandlers = true;
+ }
+- Enumeration enum_ = getLoggerNames();
+- while (enum_.hasMoreElements()) {
+- String name = (String)enum_.nextElement();
+- resetLogger(name);
++ for (LoggerContext cx : contexts()) {
++ Enumeration<String> enum_ = cx.getLoggerNames();
++ while (enum_.hasMoreElements()) {
++ String name = enum_.nextElement();
++ Logger logger = cx.findLogger(name);
++ if (logger != null) {
++ resetLogger(logger);
++ }
++ }
+ }
+ }
+
+-
+ // Private method to reset an individual target logger.
+- private void resetLogger(String name) {
+- Logger logger = getLogger(name);
+- if (logger == null) {
+- return;
+- }
++ private void resetLogger(Logger logger) {
+ // Close all the Logger's handlers.
+ Handler[] targets = logger.getHandlers();
+ for (int i = 0; i < targets.length; i++) {
+@@ -830,6 +1017,7 @@ public class LogManager {
+ // Problems closing a handler? Keep going...
+ }
+ }
++ String name = logger.getName();
+ if (name != null && name.equals("")) {
+ // This is the root logger.
+ logger.setLevel(defaultLevel);
+@@ -977,11 +1165,8 @@ public class LogManager {
+ if (val == null) {
+ return defaultValue;
+ }
+- try {
+- return Level.parse(val.trim());
+- } catch (Exception ex) {
+- return defaultValue;
+- }
++ Level l = Level.findLevel(val.trim());
++ return l != null ? l : defaultValue;
+ }
+
+ // Package private method to get a filter property.
+@@ -1072,9 +1257,11 @@ public class LogManager {
+ HashMap<String,LogNode> children;
+ LoggerWeakRef loggerRef;
+ LogNode parent;
++ final LoggerContext context;
+
+- LogNode(LogNode parent) {
++ LogNode(LogNode parent, LoggerContext context) {
+ this.parent = parent;
++ this.context = context;
+ }
+
+ // Recursive method to walk the tree below a node and set
+@@ -1133,7 +1320,7 @@ public class LogManager {
+ // Private method to be called when the configuration has
+ // changed to apply any level settings to any pre-existing loggers.
+ synchronized private void setLevelsOnExistingLoggers() {
+- Enumeration enum_ = props.propertyNames();
++ Enumeration<?> enum_ = props.propertyNames();
+ while (enum_.hasMoreElements()) {
+ String key = (String)enum_.nextElement();
+ if (!key.endsWith(".level")) {
+@@ -1147,11 +1334,13 @@ public class LogManager {
+ System.err.println("Bad level value for property: " + key);
+ continue;
+ }
+- Logger l = getLogger(name);
+- if (l == null) {
+- continue;
++ for (LoggerContext cx : contexts()) {
++ Logger l = cx.findLogger(name);
++ if (l == null) {
++ continue;
++ }
++ l.setLevel(level);
+ }
+- l.setLevel(level);
+ }
+ }
+
+diff --git a/src/share/classes/java/util/logging/Logger.java b/src/share/classes/java/util/logging/Logger.java
+--- jdk/src/share/classes/java/util/logging/Logger.java
++++ jdk/src/share/classes/java/util/logging/Logger.java
+@@ -29,6 +29,7 @@ import java.util.*;
+ import java.util.*;
+ import java.security.*;
+ import java.lang.ref.WeakReference;
++import java.util.logging.LogManager.LoggerContext;
+
+ /**
+ * A Logger object is used to log messages for a specific
+@@ -276,6 +277,26 @@ public class Logger {
+ }
+ }
+
++ // Until all JDK code converted to call sun.util.logging.PlatformLogger
++ // (see 7054233), we need to determine if Logger.getLogger is to add
++ // a system logger or user logger.
++ //
++ // As an interim solution, if the immediate caller whose caller loader is
++ // null, we assume it's a system logger and add it to the system context.
++ private static LoggerContext getLoggerContext() {
++ LogManager manager = LogManager.getLogManager();
++ SecurityManager sm = System.getSecurityManager();
++ if (sm != null) {
++ // 0: Reflection 1: Logger.getLoggerContext 2: Logger.getLogger 3: caller
++ final int SKIP_FRAMES = 3;
++ Class<?> caller = sun.reflect.Reflection.getCallerClass(SKIP_FRAMES);
++ if (caller.getClassLoader() == null) {
++ return manager.getSystemContext();
++ }
++ }
++ return manager.getUserContext();
++ }
++
+ /**
+ * Find or create a logger for a named subsystem. If a logger has
+ * already been created with the given name it is returned. Otherwise
+@@ -304,8 +325,8 @@ public class Logger {
+ * @throws NullPointerException if the name is null.
+ */
+ public static synchronized Logger getLogger(String name) {
+- LogManager manager = LogManager.getLogManager();
+- return manager.demandLogger(name);
++ LoggerContext context = getLoggerContext();
++ return context.demandLogger(name);
+ }
+
+ /**
+@@ -348,8 +369,8 @@ public class Logger {
+ * @throws NullPointerException if the name is null.
+ */
+ public static synchronized Logger getLogger(String name, String resourceBundleName) {
+- LogManager manager = LogManager.getLogManager();
+- Logger result = manager.demandLogger(name);
++ LoggerContext context = getLoggerContext();
++ Logger result = context.demandLogger(name, resourceBundleName);
+ if (result.resourceBundleName == null) {
+ // Note: we may get a MissingResourceException here.
+ result.setupResourceInfo(resourceBundleName);
+@@ -513,7 +534,7 @@ public class Logger {
+ private void doLog(LogRecord lr) {
+ lr.setLoggerName(name);
+ String ebname = getEffectiveResourceBundleName();
+- if (ebname != null) {
++ if (ebname != null && !ebname.equals(SYSTEM_LOGGER_RB_NAME)) {
+ lr.setResourceBundleName(ebname);
+ lr.setResourceBundle(findResourceBundle(ebname));
+ }
+@@ -1271,6 +1292,22 @@ public class Logger {
+ // May also return null if we can't find the resource bundle and
+ // there is no suitable previous cached value.
+
++ static final String SYSTEM_LOGGER_RB_NAME = "sun.util.logging.resources.logging";
++
++ private static ResourceBundle findSystemResourceBundle(final Locale locale) {
++ // the resource bundle is in a restricted package
++ return AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
++ public ResourceBundle run() {
++ try {
++ return ResourceBundle.getBundle(SYSTEM_LOGGER_RB_NAME,
++ locale);
++ } catch (MissingResourceException e) {
++ throw new InternalError(e.toString());
++ }
++ }
++ });
++ }
++
+ private synchronized ResourceBundle findResourceBundle(String name) {
+ // Return a null bundle for a null name.
+ if (name == null) {
+@@ -1282,6 +1319,13 @@ public class Logger {
+ // Normally we should hit on our simple one entry cache.
+ if (catalog != null && currentLocale == catalogLocale
+ && name == catalogName) {
++ return catalog;
++ }
++
++ if (name.equals(SYSTEM_LOGGER_RB_NAME)) {
++ catalog = findSystemResourceBundle(currentLocale);
++ catalogName = name;
++ catalogLocale = currentLocale;
+ return catalog;
+ }
+
+diff --git a/src/share/classes/java/util/logging/Logging.java b/src/share/classes/java/util/logging/Logging.java
+--- jdk/src/share/classes/java/util/logging/Logging.java
++++ jdk/src/share/classes/java/util/logging/Logging.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -34,15 +34,15 @@ import java.util.ArrayList;
+ *
+ * The <tt>LoggingMXBean</tt> interface provides a standard
+ * method for management access to the individual
+- * java.util.Logger objects available at runtime.
++ * {@code Logger} objects available at runtime.
+ *
+ * @author Ron Mann
+ * @author Mandy Chung
+ * @since 1.5
+ *
+ * @see javax.management
+- * @see java.util.Logger
+- * @see java.util.LogManager
++ * @see Logger
++ * @see LogManager
+ */
+ class Logging implements LoggingMXBean {
+
+@@ -75,7 +75,7 @@ class Logging implements LoggingMXBean {
+ if (level == null) {
+ return EMPTY_STRING;
+ } else {
+- return level.getName();
++ return level.getLevelName();
+ }
+ }
+
+@@ -94,7 +94,10 @@ class Logging implements LoggingMXBean {
+ Level level = null;
+ if (levelName != null) {
+ // parse will throw IAE if logLevel is invalid
+- level = Level.parse(levelName);
++ level = Level.findLevel(levelName);
++ if (level == null) {
++ throw new IllegalArgumentException("Unknown level \"" + levelName + "\"");
++ }
+ }
+
+ logger.setLevel(level);
+diff --git a/src/share/classes/java/util/logging/SimpleFormatter.java b/src/share/classes/java/util/logging/SimpleFormatter.java
+--- jdk/src/share/classes/java/util/logging/SimpleFormatter.java
++++ jdk/src/share/classes/java/util/logging/SimpleFormatter.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -83,7 +83,7 @@ public class SimpleFormatter extends For
+ }
+ sb.append(lineSeparator);
+ String message = formatMessage(record);
+- sb.append(record.getLevel().getLocalizedName());
++ sb.append(record.getLevel().getLocalizedLevelName());
+ sb.append(": ");
+ sb.append(message);
+ sb.append(lineSeparator);
+diff --git a/src/share/classes/sun/awt/AppContext.java b/src/share/classes/sun/awt/AppContext.java
+--- jdk/src/share/classes/sun/awt/AppContext.java
++++ jdk/src/share/classes/sun/awt/AppContext.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -275,7 +275,7 @@ public final class AppContext {
+ if ((recent != null) && (recent.thread == currentThread)) {
+ appContext = recent.appContext; // Cache hit
+ } else {
+- appContext = (AppContext)AccessController.doPrivileged(
++ appContext = (AppContext)AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ // Get the current ThreadGroup, and look for it and its
+@@ -319,19 +319,25 @@ public final class AppContext {
+ // Before we return the main "system" AppContext, check to
+ // see if there's an AWTSecurityManager installed. If so,
+ // allow it to choose the AppContext to return.
+- SecurityManager securityManager = System.getSecurityManager();
+- if ((securityManager != null) &&
+- (securityManager instanceof AWTSecurityManager)) {
+- AWTSecurityManager awtSecMgr =
+- (AWTSecurityManager)securityManager;
+- AppContext secAppContext = awtSecMgr.getAppContext();
+- if (secAppContext != null) {
+- appContext = secAppContext; // Return what we're told
+- }
++ AppContext secAppContext = getExecutionAppContext();
++ if (secAppContext != null) {
++ appContext = secAppContext; // Return what we're told
+ }
+ }
+
+ return appContext;
++ }
++
++ private final static AppContext getExecutionAppContext() {
++ SecurityManager securityManager = System.getSecurityManager();
++ if ((securityManager != null) &&
++ (securityManager instanceof AWTSecurityManager))
++ {
++ AWTSecurityManager awtSecMgr = (AWTSecurityManager) securityManager;
++ AppContext secAppContext = awtSecMgr.getAppContext();
++ return secAppContext; // Return what we're told
++ }
++ return null;
+ }
+
+ private long DISPOSAL_TIMEOUT = 5000; // Default to 5-second timeout
+@@ -786,6 +792,21 @@ public final class AppContext {
+ public boolean isMainAppContext() {
+ return (numAppContexts == 1);
+ }
++ public Object getContext() {
++ return getAppContext();
++ }
++ public Object getExecutionContext() {
++ return getExecutionAppContext();
++ }
++ public Object get(Object context, Object key) {
++ return ((AppContext)context).get(key);
++ }
++ public void put(Object context, Object key, Object value) {
++ ((AppContext)context).put(key, value);
++ }
++ public void remove(Object context, Object key) {
++ ((AppContext)context).remove(key);
++ }
+ });
+ }
+ }
+diff --git a/src/share/classes/sun/misc/JavaAWTAccess.java b/src/share/classes/sun/misc/JavaAWTAccess.java
+--- jdk/src/share/classes/sun/misc/JavaAWTAccess.java
++++ jdk/src/share/classes/sun/misc/JavaAWTAccess.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -24,6 +24,14 @@ package sun.misc;
+ package sun.misc;
+
+ public interface JavaAWTAccess {
++ public Object getContext();
++ public Object getExecutionContext();
++
++ public Object get(Object context, Object key);
++ public void put(Object context, Object key, Object value);
++ public void remove(Object context, Object key);
++
++ // convenience methods whose context is the object returned by getContext()
+ public Object get(Object key);
+ public void put(Object key, Object value);
+ public void remove(Object key);
+diff --git a/src/share/lib/security/java.security b/src/share/lib/security/java.security
+--- jdk/src/share/lib/security/java.security
++++ jdk/src/share/lib/security/java.security
+@@ -129,7 +129,10 @@ system.scope=sun.security.provider.Ident
+ # been granted.
+ package.access=sun.,\
+ com.sun.xml.internal.,\
+- com.sun.imageio.
++ com.sun.imageio.,\
++ com.sun.istack.internal.,\
++ com.sun.jmx.defaults.,\
++ com.sun.jmx.remote.util.
+
+ #
+ # List of comma-separated packages that start with or equal this string
+@@ -143,7 +146,10 @@ package.access=sun.,\
+ #
+ package.definition=sun.,\
+ com.sun.xml.internal.,\
+- com.sun.imageio.
++ com.sun.imageio.,\
++ com.sun.istack.internal.,\
++ com.sun.jmx.defaults.,\
++ com.sun.jmx.remote.util.
+
+ #
+ # Determines whether this properties file can be appended to
diff --git a/java/openjdk6/files/icedtea/security/20130201/6776941.patch b/java/openjdk6/files/icedtea/security/20130201/6776941.patch
new file mode 100644
index 000000000000..7604b50b9b22
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/6776941.patch
@@ -0,0 +1,272 @@
+# HG changeset patch
+# User dholmes
+# Date 1350872930 14400
+# Node ID 6088f35106866940de257456c8eee21b130d5ff5
+# Parent 21487ef30163da2a96369eee80a3bf5e94612017
+6776941: Improve thread pool shutdown
+Reviewed-by: dl, skoivu
+
+diff --git a/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java b/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java
+--- jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java
++++ jdk/src/share/classes/java/util/concurrent/ThreadPoolExecutor.java
+@@ -34,8 +34,10 @@
+ */
+
+ package java.util.concurrent;
+-import java.util.concurrent.locks.*;
+-import java.util.concurrent.atomic.*;
++import java.util.concurrent.locks.AbstractQueuedSynchronizer;
++import java.util.concurrent.locks.Condition;
++import java.util.concurrent.locks.ReentrantLock;
++import java.util.concurrent.atomic.AtomicInteger;
+ import java.util.*;
+
+ /**
+@@ -491,10 +493,15 @@ public class ThreadPoolExecutor extends
+ * policy limiting the number of threads. Even though it is not
+ * treated as an error, failure to create threads may result in
+ * new tasks being rejected or existing ones remaining stuck in
+- * the queue. On the other hand, no special precautions exist to
+- * handle OutOfMemoryErrors that might be thrown while trying to
+- * create threads, since there is generally no recourse from
+- * within this class.
++ * the queue.
++ *
++ * We go further and preserve pool invariants even in the face of
++ * errors such as OutOfMemoryError, that might be thrown while
++ * trying to create threads. Such errors are rather common due to
++ * the need to allocate a native stack in Thread#start, and users
++ * will want to perform clean pool shutdown to clean up. There
++ * will likely be enough memory available for the cleanup code to
++ * complete without encountering yet another OutOfMemoryError.
+ */
+ private volatile ThreadFactory threadFactory;
+
+@@ -568,9 +575,13 @@ public class ThreadPoolExecutor extends
+ * task execution. This protects against interrupts that are
+ * intended to wake up a worker thread waiting for a task from
+ * instead interrupting a task being run. We implement a simple
+- * non-reentrant mutual exclusion lock rather than use ReentrantLock
+- * because we do not want worker tasks to be able to reacquire the
+- * lock when they invoke pool control methods like setCorePoolSize.
++ * non-reentrant mutual exclusion lock rather than use
++ * ReentrantLock because we do not want worker tasks to be able to
++ * reacquire the lock when they invoke pool control methods like
++ * setCorePoolSize. Additionally, to suppress interrupts until
++ * the thread actually starts running tasks, we initialize lock
++ * state to a negative value, and clear it upon start (in
++ * runWorker).
+ */
+ private final class Worker
+ extends AbstractQueuedSynchronizer
+@@ -594,6 +605,7 @@ public class ThreadPoolExecutor extends
+ * @param firstTask the first task (null if none)
+ */
+ Worker(Runnable firstTask) {
++ setState(-1); // inhibit interrupts until runWorker
+ this.firstTask = firstTask;
+ this.thread = getThreadFactory().newThread(this);
+ }
+@@ -609,7 +621,7 @@ public class ThreadPoolExecutor extends
+ // The value 1 represents the locked state.
+
+ protected boolean isHeldExclusively() {
+- return getState() == 1;
++ return getState() != 0;
+ }
+
+ protected boolean tryAcquire(int unused) {
+@@ -630,6 +642,16 @@ public class ThreadPoolExecutor extends
+ public boolean tryLock() { return tryAcquire(1); }
+ public void unlock() { release(1); }
+ public boolean isLocked() { return isHeldExclusively(); }
++
++ void interruptIfStarted() {
++ Thread t;
++ if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) {
++ try {
++ t.interrupt();
++ } catch (SecurityException ignore) {
++ }
++ }
++ }
+ }
+
+ /*
+@@ -729,10 +751,7 @@ public class ThreadPoolExecutor extends
+ mainLock.lock();
+ try {
+ for (Worker w : workers) {
+- try {
+- w.thread.interrupt();
+- } catch (SecurityException ignore) {
+- }
++ w.interruptIfStarted();
+ }
+ } finally {
+ mainLock.unlock();
+@@ -789,19 +808,6 @@ public class ThreadPoolExecutor extends
+ }
+
+ private static final boolean ONLY_ONE = true;
+-
+- /**
+- * Ensures that unless the pool is stopping, the current thread
+- * does not have its interrupt set. This requires a double-check
+- * of state in case the interrupt was cleared concurrently with a
+- * shutdownNow -- if so, the interrupt is re-enabled.
+- */
+- private void clearInterruptsForTaskRun() {
+- if (runStateLessThan(ctl.get(), STOP) &&
+- Thread.interrupted() &&
+- runStateAtLeast(ctl.get(), STOP))
+- Thread.currentThread().interrupt();
+- }
+
+ /*
+ * Misc utilities, most of which are also exported to
+@@ -862,12 +868,13 @@ public class ThreadPoolExecutor extends
+ * Checks if a new worker can be added with respect to current
+ * pool state and the given bound (either core or maximum). If so,
+ * the worker count is adjusted accordingly, and, if possible, a
+- * new worker is created and started running firstTask as its
++ * new worker is created and started, running firstTask as its
+ * first task. This method returns false if the pool is stopped or
+ * eligible to shut down. It also returns false if the thread
+- * factory fails to create a thread when asked, which requires a
+- * backout of workerCount, and a recheck for termination, in case
+- * the existence of this worker was holding up termination.
++ * factory fails to create a thread when asked. If the thread
++ * creation fails, either due to the thread factory returning
++ * null, or due to an exception (typically OutOfMemoryError in
++ * Thread#start), we roll back cleanly.
+ *
+ * @param firstTask the task the new thread should run first (or
+ * null if none). Workers are created with an initial first task
+@@ -910,46 +917,65 @@ public class ThreadPoolExecutor extends
+ }
+ }
+
+- Worker w = new Worker(firstTask);
+- Thread t = w.thread;
++ boolean workerStarted = false;
++ boolean workerAdded = false;
++ Worker w = null;
++ try {
++ final ReentrantLock mainLock = this.mainLock;
++ w = new Worker(firstTask);
++ final Thread t = w.thread;
++ if (t != null) {
++ mainLock.lock();
++ try {
++ // Recheck while holding lock.
++ // Back out on ThreadFactory failure or if
++ // shut down before lock acquired.
++ int c = ctl.get();
++ int rs = runStateOf(c);
+
++ if (rs < SHUTDOWN ||
++ (rs == SHUTDOWN && firstTask == null)) {
++ if (t.isAlive()) // precheck that t is startable
++ throw new IllegalThreadStateException();
++ workers.add(w);
++ int s = workers.size();
++ if (s > largestPoolSize)
++ largestPoolSize = s;
++ workerAdded = true;
++ }
++ } finally {
++ mainLock.unlock();
++ }
++ if (workerAdded) {
++ t.start();
++ workerStarted = true;
++ }
++ }
++ } finally {
++ if (! workerStarted)
++ addWorkerFailed(w);
++ }
++ return workerStarted;
++ }
++
++ /**
++ * Rolls back the worker thread creation.
++ * - removes worker from workers, if present
++ * - decrements worker count
++ * - rechecks for termination, in case the existence of this
++ * worker was holding up termination
++ */
++ private void addWorkerFailed(Worker w) {
+ final ReentrantLock mainLock = this.mainLock;
+ mainLock.lock();
+ try {
+- // Recheck while holding lock.
+- // Back out on ThreadFactory failure or if
+- // shut down before lock acquired.
+- int c = ctl.get();
+- int rs = runStateOf(c);
+-
+- if (t == null ||
+- (rs >= SHUTDOWN &&
+- ! (rs == SHUTDOWN &&
+- firstTask == null))) {
+- decrementWorkerCount();
+- tryTerminate();
+- return false;
+- }
+-
+- workers.add(w);
+-
+- int s = workers.size();
+- if (s > largestPoolSize)
+- largestPoolSize = s;
++ if (w != null)
++ workers.remove(w);
++ decrementWorkerCount();
++ tryTerminate();
+ } finally {
+ mainLock.unlock();
+ }
+-
+- t.start();
+- // It is possible (but unlikely) for a thread to have been
+- // added to workers, but not yet started, during transition to
+- // STOP, which could result in a rare missed interrupt,
+- // because Thread.interrupt is not guaranteed to have any effect
+- // on a non-yet-started Thread (see Thread#interrupt).
+- if (runStateOf(ctl.get()) == STOP && ! t.isInterrupted())
+- t.interrupt();
+-
+- return true;
+ }
+
+ /**
+@@ -1096,15 +1122,25 @@ public class ThreadPoolExecutor extends
+ * @param w the worker
+ */
+ final void runWorker(Worker w) {
++ Thread wt = Thread.currentThread();
+ Runnable task = w.firstTask;
+ w.firstTask = null;
++ w.unlock(); // allow interrupts
+ boolean completedAbruptly = true;
+ try {
+ while (task != null || (task = getTask()) != null) {
+ w.lock();
+- clearInterruptsForTaskRun();
++ // If pool is stopping, ensure thread is interrupted;
++ // if not, ensure thread is not interrupted. This
++ // requires a recheck in second case to deal with
++ // shutdownNow race while clearing interrupt
++ if ((runStateAtLeast(ctl.get(), STOP) ||
++ (Thread.interrupted() &&
++ runStateAtLeast(ctl.get(), STOP))) &&
++ !wt.isInterrupted())
++ wt.interrupt();
+ try {
+- beforeExecute(w.thread, task);
++ beforeExecute(wt, task);
+ Throwable thrown = null;
+ try {
+ task.run();
diff --git a/java/openjdk6/files/icedtea/security/20130201/7141694.patch b/java/openjdk6/files/icedtea/security/20130201/7141694.patch
new file mode 100644
index 000000000000..66d69a7b69a7
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7141694.patch
@@ -0,0 +1,87 @@
+# HG changeset patch
+# User mbankal
+# Date 1355396891 28800
+# Node ID 7eb471f1efdd127f982e53b290c1fece845a897c
+# Parent 58fdb67fcacc67693fc43b5601e88bd7c216f850
+7141694: Improving CORBA internals
+Reviewed-by: coffeys, ahgross
+
+diff --git a/src/share/classes/com/sun/corba/se/spi/orb/ORB.java b/src/share/classes/com/sun/corba/se/spi/orb/ORB.java
+--- corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java
++++ corba/src/share/classes/com/sun/corba/se/spi/orb/ORB.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -98,6 +98,7 @@ import com.sun.corba.se.impl.presentatio
+ import com.sun.corba.se.impl.presentation.rmi.PresentationManagerImpl ;
+
+ import com.sun.corba.se.impl.orbutil.ORBClassLoader ;
++import sun.awt.AppContext;
+
+ public abstract class ORB extends com.sun.corba.se.org.omg.CORBA.ORB
+ implements Broker, TypeCodeFactory
+@@ -173,14 +174,7 @@ public abstract class ORB extends com.su
+
+ private MonitoringManager monitoringManager;
+
+- // There is only one instance of the PresentationManager
+- // that is shared between all ORBs. This is necessary
+- // because RMI-IIOP requires the PresentationManager in
+- // places where no ORB is available, so the PresentationManager
+- // must be global. It is initialized here as well.
+- protected static PresentationManager globalPM = null ;
+-
+- static {
++ private static PresentationManager setupPresentationManager() {
+ staticWrapper = ORBUtilSystemException.get(
+ CORBALogDomains.RPC_PRESENTATION ) ;
+
+@@ -220,17 +214,26 @@ public abstract class ORB extends com.su
+ }
+ ) ;
+
+- globalPM = new PresentationManagerImpl( useDynamicStub ) ;
+- globalPM.setStubFactoryFactory( false,
++ PresentationManager pm = new PresentationManagerImpl( useDynamicStub ) ;
++ pm.setStubFactoryFactory( false,
+ PresentationDefaults.getStaticStubFactoryFactory() ) ;
+- globalPM.setStubFactoryFactory( true, dynamicStubFactoryFactory ) ;
++ pm.setStubFactoryFactory( true, dynamicStubFactoryFactory ) ;
++ return pm;
+ }
+
+- /** Get the single instance of the PresentationManager
++ /**
++ * Returns the Presentation Manager for the current thread group, using the ThreadGroup-specific
++ * AppContext to hold it. Creates and records one if needed.
+ */
+- public static PresentationManager getPresentationManager()
++ public static PresentationManager getPresentationManager()
+ {
+- return globalPM ;
++ AppContext ac = AppContext.getAppContext();
++ PresentationManager pm = (PresentationManager) ac.get(PresentationManager.class);
++ if (pm == null) {
++ pm = setupPresentationManager();
++ ac.put(PresentationManager.class, pm);
++ }
++ return pm;
+ }
+
+ /** Get the appropriate StubFactoryFactory. This
+@@ -240,8 +243,9 @@ public abstract class ORB extends com.su
+ public static PresentationManager.StubFactoryFactory
+ getStubFactoryFactory()
+ {
+- boolean useDynamicStubs = globalPM.useDynamicStubs() ;
+- return globalPM.getStubFactoryFactory( useDynamicStubs ) ;
++ PresentationManager gPM = getPresentationManager();
++ boolean useDynamicStubs = gPM.useDynamicStubs() ;
++ return gPM.getStubFactoryFactory( useDynamicStubs ) ;
+ }
+
+ protected ORB()
diff --git a/java/openjdk6/files/icedtea/security/20130201/7173145.patch b/java/openjdk6/files/icedtea/security/20130201/7173145.patch
new file mode 100644
index 000000000000..b7971618d3d7
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7173145.patch
@@ -0,0 +1,22 @@
+# HG changeset patch
+# User anthony
+# Date 1350043271 -14400
+# Node ID ce11c5c59cb8672eeddf9d5ce49563ccbc387854
+# Parent 9c2a2aae44a46e0b63b913987672d1488fa4e7a5
+7173145: Improve in-memory representation of splashscreens
+Reviewed-by: bae, mschoene
+
+diff --git a/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c b/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c
+--- jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c
++++ jdk/src/share/native/sun/awt/splashscreen/splashscreen_jpeg.c
+@@ -133,6 +133,10 @@ SplashDecodeJpeg(Splash * splash, struct
+ ImageFormat srcFormat;
+
+ jpeg_read_header(cinfo, TRUE);
++
++ // SplashScreen jpeg converter expects data in RGB format only
++ cinfo->out_color_space = JCS_RGB;
++
+ jpeg_start_decompress(cinfo);
+
+ SplashCleanup(splash);
diff --git a/java/openjdk6/files/icedtea/security/20130201/7186945.patch b/java/openjdk6/files/icedtea/security/20130201/7186945.patch
new file mode 100644
index 000000000000..007ff979f1b7
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7186945.patch
@@ -0,0 +1,10819 @@
+# HG changeset patch
+# User miroslawzn
+# Date 1354324090 28800
+# Node ID f3f9b711bb1228f4598ded7eb0380c32eba63521
+# Parent 9bbc6817b00c3e9d4eba05d53a8a20b45947ea03
+7186945: Unpack200 improvement
+7186957: Improve Pack200 data validation
+7186946: Refine unpacker resource usage
+Reviewed-by: ksrini
+
+diff --git a/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java b/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java
+--- jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java
++++ jdk/src/share/classes/com/sun/java/util/jar/pack/BandStructure.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -22,7 +22,6 @@
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-
+ package com.sun.java.util.jar.pack;
+
+ import java.io.*;
+@@ -62,20 +61,20 @@ class BandStructure implements Constants
+
+ /** Call this exactly once, early, to specify the archive major version. */
+ public void initPackageMajver(int packageMajver) throws IOException {
+- assert(packageMajver > 0 && packageMajver < 0x10000);
+- if (this.packageMajver > 0) {
+- throw new IOException(
+- "Package majver is already initialized to " + this.packageMajver+
+- "; new setting is " + packageMajver);
+- }
+- this.packageMajver = packageMajver;
+- adjustToMajver();
++ assert(packageMajver > 0 && packageMajver < 0x10000);
++ if (this.packageMajver > 0) {
++ throw new IOException(
++ "Package majver is already initialized to " + this.packageMajver+
++ "; new setting is " + packageMajver);
++ }
++ this.packageMajver = packageMajver;
++ adjustToMajver();
+ }
+ public int getPackageMajver() {
+- if (packageMajver < 0) {
+- throw new RuntimeException("Package majver not yet initialized");
+- }
+- return packageMajver;
++ if (packageMajver < 0) {
++ throw new RuntimeException("Package majver not yet initialized");
++ }
++ return packageMajver;
+ }
+
+ private final boolean isReader = this instanceof PackageReader;
+@@ -103,163 +102,163 @@ class BandStructure implements Constants
+ final static Coding MDELTA5 = Coding.of(5,64,2).getDeltaCoding();
+
+ final private static Coding[] basicCodings = {
+- // Table of "Canonical BHSD Codings" from Pack200 spec.
+- null, // _meta_default
++ // Table of "Canonical BHSD Codings" from Pack200 spec.
++ null, // _meta_default
+
+- // Fixed-length codings:
+- Coding.of(1,256,0),
+- Coding.of(1,256,1),
+- Coding.of(1,256,0).getDeltaCoding(),
+- Coding.of(1,256,1).getDeltaCoding(),
+- Coding.of(2,256,0),
+- Coding.of(2,256,1),
+- Coding.of(2,256,0).getDeltaCoding(),
+- Coding.of(2,256,1).getDeltaCoding(),
+- Coding.of(3,256,0),
+- Coding.of(3,256,1),
+- Coding.of(3,256,0).getDeltaCoding(),
+- Coding.of(3,256,1).getDeltaCoding(),
+- Coding.of(4,256,0),
+- Coding.of(4,256,1),
+- Coding.of(4,256,0).getDeltaCoding(),
+- Coding.of(4,256,1).getDeltaCoding(),
++ // Fixed-length codings:
++ Coding.of(1,256,0),
++ Coding.of(1,256,1),
++ Coding.of(1,256,0).getDeltaCoding(),
++ Coding.of(1,256,1).getDeltaCoding(),
++ Coding.of(2,256,0),
++ Coding.of(2,256,1),
++ Coding.of(2,256,0).getDeltaCoding(),
++ Coding.of(2,256,1).getDeltaCoding(),
++ Coding.of(3,256,0),
++ Coding.of(3,256,1),
++ Coding.of(3,256,0).getDeltaCoding(),
++ Coding.of(3,256,1).getDeltaCoding(),
++ Coding.of(4,256,0),
++ Coding.of(4,256,1),
++ Coding.of(4,256,0).getDeltaCoding(),
++ Coding.of(4,256,1).getDeltaCoding(),
+
+- // Full-range variable-length codings:
+- Coding.of(5, 4,0),
+- Coding.of(5, 4,1),
+- Coding.of(5, 4,2),
+- Coding.of(5, 16,0),
+- Coding.of(5, 16,1),
+- Coding.of(5, 16,2),
+- Coding.of(5, 32,0),
+- Coding.of(5, 32,1),
+- Coding.of(5, 32,2),
+- Coding.of(5, 64,0),
+- Coding.of(5, 64,1),
+- Coding.of(5, 64,2),
+- Coding.of(5,128,0),
+- Coding.of(5,128,1),
+- Coding.of(5,128,2),
++ // Full-range variable-length codings:
++ Coding.of(5, 4,0),
++ Coding.of(5, 4,1),
++ Coding.of(5, 4,2),
++ Coding.of(5, 16,0),
++ Coding.of(5, 16,1),
++ Coding.of(5, 16,2),
++ Coding.of(5, 32,0),
++ Coding.of(5, 32,1),
++ Coding.of(5, 32,2),
++ Coding.of(5, 64,0),
++ Coding.of(5, 64,1),
++ Coding.of(5, 64,2),
++ Coding.of(5,128,0),
++ Coding.of(5,128,1),
++ Coding.of(5,128,2),
+
+- Coding.of(5, 4,0).getDeltaCoding(),
+- Coding.of(5, 4,1).getDeltaCoding(),
+- Coding.of(5, 4,2).getDeltaCoding(),
+- Coding.of(5, 16,0).getDeltaCoding(),
+- Coding.of(5, 16,1).getDeltaCoding(),
+- Coding.of(5, 16,2).getDeltaCoding(),
+- Coding.of(5, 32,0).getDeltaCoding(),
+- Coding.of(5, 32,1).getDeltaCoding(),
+- Coding.of(5, 32,2).getDeltaCoding(),
+- Coding.of(5, 64,0).getDeltaCoding(),
+- Coding.of(5, 64,1).getDeltaCoding(),
+- Coding.of(5, 64,2).getDeltaCoding(),
+- Coding.of(5,128,0).getDeltaCoding(),
+- Coding.of(5,128,1).getDeltaCoding(),
+- Coding.of(5,128,2).getDeltaCoding(),
++ Coding.of(5, 4,0).getDeltaCoding(),
++ Coding.of(5, 4,1).getDeltaCoding(),
++ Coding.of(5, 4,2).getDeltaCoding(),
++ Coding.of(5, 16,0).getDeltaCoding(),
++ Coding.of(5, 16,1).getDeltaCoding(),
++ Coding.of(5, 16,2).getDeltaCoding(),
++ Coding.of(5, 32,0).getDeltaCoding(),
++ Coding.of(5, 32,1).getDeltaCoding(),
++ Coding.of(5, 32,2).getDeltaCoding(),
++ Coding.of(5, 64,0).getDeltaCoding(),
++ Coding.of(5, 64,1).getDeltaCoding(),
++ Coding.of(5, 64,2).getDeltaCoding(),
++ Coding.of(5,128,0).getDeltaCoding(),
++ Coding.of(5,128,1).getDeltaCoding(),
++ Coding.of(5,128,2).getDeltaCoding(),
+
+- // Variable length subrange codings:
+- Coding.of(2,192,0),
+- Coding.of(2,224,0),
+- Coding.of(2,240,0),
+- Coding.of(2,248,0),
+- Coding.of(2,252,0),
++ // Variable length subrange codings:
++ Coding.of(2,192,0),
++ Coding.of(2,224,0),
++ Coding.of(2,240,0),
++ Coding.of(2,248,0),
++ Coding.of(2,252,0),
+
+- Coding.of(2, 8,0).getDeltaCoding(),
+- Coding.of(2, 8,1).getDeltaCoding(),
+- Coding.of(2, 16,0).getDeltaCoding(),
+- Coding.of(2, 16,1).getDeltaCoding(),
+- Coding.of(2, 32,0).getDeltaCoding(),
+- Coding.of(2, 32,1).getDeltaCoding(),
+- Coding.of(2, 64,0).getDeltaCoding(),
+- Coding.of(2, 64,1).getDeltaCoding(),
+- Coding.of(2,128,0).getDeltaCoding(),
+- Coding.of(2,128,1).getDeltaCoding(),
+- Coding.of(2,192,0).getDeltaCoding(),
+- Coding.of(2,192,1).getDeltaCoding(),
+- Coding.of(2,224,0).getDeltaCoding(),
+- Coding.of(2,224,1).getDeltaCoding(),
+- Coding.of(2,240,0).getDeltaCoding(),
+- Coding.of(2,240,1).getDeltaCoding(),
+- Coding.of(2,248,0).getDeltaCoding(),
+- Coding.of(2,248,1).getDeltaCoding(),
++ Coding.of(2, 8,0).getDeltaCoding(),
++ Coding.of(2, 8,1).getDeltaCoding(),
++ Coding.of(2, 16,0).getDeltaCoding(),
++ Coding.of(2, 16,1).getDeltaCoding(),
++ Coding.of(2, 32,0).getDeltaCoding(),
++ Coding.of(2, 32,1).getDeltaCoding(),
++ Coding.of(2, 64,0).getDeltaCoding(),
++ Coding.of(2, 64,1).getDeltaCoding(),
++ Coding.of(2,128,0).getDeltaCoding(),
++ Coding.of(2,128,1).getDeltaCoding(),
++ Coding.of(2,192,0).getDeltaCoding(),
++ Coding.of(2,192,1).getDeltaCoding(),
++ Coding.of(2,224,0).getDeltaCoding(),
++ Coding.of(2,224,1).getDeltaCoding(),
++ Coding.of(2,240,0).getDeltaCoding(),
++ Coding.of(2,240,1).getDeltaCoding(),
++ Coding.of(2,248,0).getDeltaCoding(),
++ Coding.of(2,248,1).getDeltaCoding(),
+
+- Coding.of(3,192,0),
+- Coding.of(3,224,0),
+- Coding.of(3,240,0),
+- Coding.of(3,248,0),
+- Coding.of(3,252,0),
++ Coding.of(3,192,0),
++ Coding.of(3,224,0),
++ Coding.of(3,240,0),
++ Coding.of(3,248,0),
++ Coding.of(3,252,0),
+
+- Coding.of(3, 8,0).getDeltaCoding(),
+- Coding.of(3, 8,1).getDeltaCoding(),
+- Coding.of(3, 16,0).getDeltaCoding(),
+- Coding.of(3, 16,1).getDeltaCoding(),
+- Coding.of(3, 32,0).getDeltaCoding(),
+- Coding.of(3, 32,1).getDeltaCoding(),
+- Coding.of(3, 64,0).getDeltaCoding(),
+- Coding.of(3, 64,1).getDeltaCoding(),
+- Coding.of(3,128,0).getDeltaCoding(),
+- Coding.of(3,128,1).getDeltaCoding(),
+- Coding.of(3,192,0).getDeltaCoding(),
+- Coding.of(3,192,1).getDeltaCoding(),
+- Coding.of(3,224,0).getDeltaCoding(),
+- Coding.of(3,224,1).getDeltaCoding(),
+- Coding.of(3,240,0).getDeltaCoding(),
+- Coding.of(3,240,1).getDeltaCoding(),
+- Coding.of(3,248,0).getDeltaCoding(),
+- Coding.of(3,248,1).getDeltaCoding(),
++ Coding.of(3, 8,0).getDeltaCoding(),
++ Coding.of(3, 8,1).getDeltaCoding(),
++ Coding.of(3, 16,0).getDeltaCoding(),
++ Coding.of(3, 16,1).getDeltaCoding(),
++ Coding.of(3, 32,0).getDeltaCoding(),
++ Coding.of(3, 32,1).getDeltaCoding(),
++ Coding.of(3, 64,0).getDeltaCoding(),
++ Coding.of(3, 64,1).getDeltaCoding(),
++ Coding.of(3,128,0).getDeltaCoding(),
++ Coding.of(3,128,1).getDeltaCoding(),
++ Coding.of(3,192,0).getDeltaCoding(),
++ Coding.of(3,192,1).getDeltaCoding(),
++ Coding.of(3,224,0).getDeltaCoding(),
++ Coding.of(3,224,1).getDeltaCoding(),
++ Coding.of(3,240,0).getDeltaCoding(),
++ Coding.of(3,240,1).getDeltaCoding(),
++ Coding.of(3,248,0).getDeltaCoding(),
++ Coding.of(3,248,1).getDeltaCoding(),
+
+- Coding.of(4,192,0),
+- Coding.of(4,224,0),
+- Coding.of(4,240,0),
+- Coding.of(4,248,0),
+- Coding.of(4,252,0),
++ Coding.of(4,192,0),
++ Coding.of(4,224,0),
++ Coding.of(4,240,0),
++ Coding.of(4,248,0),
++ Coding.of(4,252,0),
+
+- Coding.of(4, 8,0).getDeltaCoding(),
+- Coding.of(4, 8,1).getDeltaCoding(),
+- Coding.of(4, 16,0).getDeltaCoding(),
+- Coding.of(4, 16,1).getDeltaCoding(),
+- Coding.of(4, 32,0).getDeltaCoding(),
+- Coding.of(4, 32,1).getDeltaCoding(),
+- Coding.of(4, 64,0).getDeltaCoding(),
+- Coding.of(4, 64,1).getDeltaCoding(),
+- Coding.of(4,128,0).getDeltaCoding(),
+- Coding.of(4,128,1).getDeltaCoding(),
+- Coding.of(4,192,0).getDeltaCoding(),
+- Coding.of(4,192,1).getDeltaCoding(),
+- Coding.of(4,224,0).getDeltaCoding(),
+- Coding.of(4,224,1).getDeltaCoding(),
+- Coding.of(4,240,0).getDeltaCoding(),
+- Coding.of(4,240,1).getDeltaCoding(),
+- Coding.of(4,248,0).getDeltaCoding(),
+- Coding.of(4,248,1).getDeltaCoding(),
++ Coding.of(4, 8,0).getDeltaCoding(),
++ Coding.of(4, 8,1).getDeltaCoding(),
++ Coding.of(4, 16,0).getDeltaCoding(),
++ Coding.of(4, 16,1).getDeltaCoding(),
++ Coding.of(4, 32,0).getDeltaCoding(),
++ Coding.of(4, 32,1).getDeltaCoding(),
++ Coding.of(4, 64,0).getDeltaCoding(),
++ Coding.of(4, 64,1).getDeltaCoding(),
++ Coding.of(4,128,0).getDeltaCoding(),
++ Coding.of(4,128,1).getDeltaCoding(),
++ Coding.of(4,192,0).getDeltaCoding(),
++ Coding.of(4,192,1).getDeltaCoding(),
++ Coding.of(4,224,0).getDeltaCoding(),
++ Coding.of(4,224,1).getDeltaCoding(),
++ Coding.of(4,240,0).getDeltaCoding(),
++ Coding.of(4,240,1).getDeltaCoding(),
++ Coding.of(4,248,0).getDeltaCoding(),
++ Coding.of(4,248,1).getDeltaCoding(),
+
+- null
++ null
+ };
+ final private static HashMap basicCodingIndexes;
+ static {
+- assert(basicCodings[_meta_default] == null);
+- assert(basicCodings[_meta_canon_min] != null);
+- assert(basicCodings[_meta_canon_max] != null);
+- HashMap map = new HashMap();
+- for (int i = 0; i < basicCodings.length; i++) {
+- Coding c = basicCodings[i];
+- if (c == null) continue;
+- assert(i >= _meta_canon_min);
+- assert(i <= _meta_canon_max);
+- map.put(c, new Integer(i));
+- }
+- basicCodingIndexes = map;
++ assert(basicCodings[_meta_default] == null);
++ assert(basicCodings[_meta_canon_min] != null);
++ assert(basicCodings[_meta_canon_max] != null);
++ HashMap map = new HashMap();
++ for (int i = 0; i < basicCodings.length; i++) {
++ Coding c = basicCodings[i];
++ if (c == null) continue;
++ assert(i >= _meta_canon_min);
++ assert(i <= _meta_canon_max);
++ map.put(c, new Integer(i));
++ }
++ basicCodingIndexes = map;
+ }
+ public static Coding codingForIndex(int i) {
+- return i < basicCodings.length ? basicCodings[i] : null;
++ return i < basicCodings.length ? basicCodings[i] : null;
+ }
+ public static int indexOf(Coding c) {
+- Integer i = (Integer) basicCodingIndexes.get(c);
+- if (i == null) return 0;
+- return i.intValue();
++ Integer i = (Integer) basicCodingIndexes.get(c);
++ if (i == null) return 0;
++ return i.intValue();
+ }
+ public static Coding[] getBasicCodings() {
+- return (Coding[]) basicCodings.clone();
++ return (Coding[]) basicCodings.clone();
+ }
+
+ protected byte[] bandHeaderBytes; // used for input only
+@@ -267,31 +266,31 @@ class BandStructure implements Constants
+ protected int bandHeaderBytePos0; // for debug
+
+ protected CodingMethod getBandHeader(int XB, Coding regularCoding) {
+- CodingMethod[] res = {null};
+- // push back XB onto the band header bytes
+- bandHeaderBytes[--bandHeaderBytePos] = (byte) XB;
+- bandHeaderBytePos0 = bandHeaderBytePos;
+- // scan forward through XB and any additional band header bytes
+- bandHeaderBytePos = parseMetaCoding(bandHeaderBytes,
+- bandHeaderBytePos,
+- regularCoding,
+- res);
+- return res[0];
++ CodingMethod[] res = {null};
++ // push back XB onto the band header bytes
++ bandHeaderBytes[--bandHeaderBytePos] = (byte) XB;
++ bandHeaderBytePos0 = bandHeaderBytePos;
++ // scan forward through XB and any additional band header bytes
++ bandHeaderBytePos = parseMetaCoding(bandHeaderBytes,
++ bandHeaderBytePos,
++ regularCoding,
++ res);
++ return res[0];
+ }
+
+ public static int parseMetaCoding(byte[] bytes, int pos, Coding dflt, CodingMethod[] res) {
+- if ((bytes[pos] & 0xFF) == _meta_default) {
+- res[0] = dflt;
+- return pos+1;
+- }
+- int pos2;
+- pos2 = Coding.parseMetaCoding(bytes, pos, dflt, res);
+- if (pos2 > pos) return pos2;
+- pos2 = PopulationCoding.parseMetaCoding(bytes, pos, dflt, res);
+- if (pos2 > pos) return pos2;
+- pos2 = AdaptiveCoding.parseMetaCoding(bytes, pos, dflt, res);
+- if (pos2 > pos) return pos2;
+- throw new RuntimeException("Bad meta-coding op "+(bytes[pos]&0xFF));
++ if ((bytes[pos] & 0xFF) == _meta_default) {
++ res[0] = dflt;
++ return pos+1;
++ }
++ int pos2;
++ pos2 = Coding.parseMetaCoding(bytes, pos, dflt, res);
++ if (pos2 > pos) return pos2;
++ pos2 = PopulationCoding.parseMetaCoding(bytes, pos, dflt, res);
++ if (pos2 > pos) return pos2;
++ pos2 = AdaptiveCoding.parseMetaCoding(bytes, pos, dflt, res);
++ if (pos2 > pos) return pos2;
++ throw new RuntimeException("Bad meta-coding op "+(bytes[pos]&0xFF));
+ }
+
+ static final int SHORT_BAND_HEURISTIC = 100;
+@@ -311,11 +310,11 @@ class BandStructure implements Constants
+ public static final int DONE_PHASE = 8; // done writing or reading
+
+ static boolean phaseIsRead(int p) {
+- return (p % 2) == 0;
++ return (p % 2) == 0;
+ }
+ static int phaseCmp(int p0, int p1) {
+- assert((p0 % 2) == (p1 % 2) || (p0 % 8) == 0 || (p1 % 8) == 0);
+- return p0 - p1;
++ assert((p0 % 2) == (p1 % 2) || (p0 % 8) == 0 || (p1 % 8) == 0);
++ return p0 - p1;
+ }
+
+ /** The packed file is divided up into a number of segments.
+@@ -332,7 +331,7 @@ class BandStructure implements Constants
+ *
+ * The three phases for reading a packed file are EXPECT, READ,
+ * and DISBURSE.
+- * 1. For each band, the expected number of integers is determined.
++ * 1. For each band, the expected number of integers is determined.
+ * 2. The data is actually read from the file into the band.
+ * 3. The band pays out its values as requested, in an ad hoc order.
+ *
+@@ -340,696 +339,695 @@ class BandStructure implements Constants
+ * Clearly, these phases must be properly ordered WRT each other.
+ */
+ abstract class Band {
+- private int phase = NO_PHASE;
+- private final String name;
++ private int phase = NO_PHASE;
++ private final String name;
+
+- private int valuesExpected;
++ private int valuesExpected;
+
+- protected long outputSize = -1; // cache
++ protected long outputSize = -1; // cache
+
+- final public Coding regularCoding;
++ final public Coding regularCoding;
+
+- final public int seqForDebug;
+- public int elementCountForDebug;
++ final public int seqForDebug;
++ public int elementCountForDebug;
+
+
+- protected Band(String name, Coding regularCoding) {
+- this.name = name;
+- this.regularCoding = regularCoding;
+- this.seqForDebug = ++nextSeqForDebug;
+- if (verbose > 2)
+- Utils.log.fine("Band "+seqForDebug+" is "+name);
+- // caller must call init
+- }
++ protected Band(String name, Coding regularCoding) {
++ this.name = name;
++ this.regularCoding = regularCoding;
++ this.seqForDebug = ++nextSeqForDebug;
++ if (verbose > 2)
++ Utils.log.fine("Band "+seqForDebug+" is "+name);
++ // caller must call init
++ }
+
+- public Band init() {
+- // Cannot due this from the constructor, because constructor
+- // may wish to initialize some subclass variables.
+- // Set initial phase for reading or writing:
+- if (isReader)
+- readyToExpect();
+- else
+- readyToCollect();
+- return this;
+- }
++ public Band init() {
++ // Cannot due this from the constructor, because constructor
++ // may wish to initialize some subclass variables.
++ // Set initial phase for reading or writing:
++ if (isReader)
++ readyToExpect();
++ else
++ readyToCollect();
++ return this;
++ }
+
+- // common operations
+- boolean isReader() { return isReader; }
+- int phase() { return phase; }
+- String name() { return name; }
++ // common operations
++ boolean isReader() { return isReader; }
++ int phase() { return phase; }
++ String name() { return name; }
+
+- /** Return -1 if data buffer not allocated, else max length. */
+- public abstract int capacity();
++ /** Return -1 if data buffer not allocated, else max length. */
++ public abstract int capacity();
+
+- /** Allocate data buffer to specified length. */
+- protected abstract void setCapacity(int cap);
++ /** Allocate data buffer to specified length. */
++ protected abstract void setCapacity(int cap);
+
+- /** Return current number of values in buffer, which must exist. */
+- public abstract int length();
++ /** Return current number of values in buffer, which must exist. */
++ public abstract int length();
+
+- protected abstract int valuesRemainingForDebug();
++ protected abstract int valuesRemainingForDebug();
+
+- public final int valuesExpected() {
+- return valuesExpected;
+- }
++ public final int valuesExpected() {
++ return valuesExpected;
++ }
+
+- /** Write out bytes, encoding the values. */
+- public final void writeTo(OutputStream out) throws IOException {
+- assert(assertReadyToWriteTo(this, out));
+- setPhase(WRITE_PHASE);
+- // subclasses continue by writing their contents to output
+- writeDataTo(out);
+- doneWriting();
+- }
++ /** Write out bytes, encoding the values. */
++ public final void writeTo(OutputStream out) throws IOException {
++ assert(assertReadyToWriteTo(this, out));
++ setPhase(WRITE_PHASE);
++ // subclasses continue by writing their contents to output
++ writeDataTo(out);
++ doneWriting();
++ }
+
+- abstract void chooseBandCodings() throws IOException;
++ abstract void chooseBandCodings() throws IOException;
+
+- public final long outputSize() {
+- if (outputSize >= 0) {
+- long size = outputSize;
+- assert(size == computeOutputSize());
+- return size;
+- }
+- return computeOutputSize();
+- }
++ public final long outputSize() {
++ if (outputSize >= 0) {
++ long size = outputSize;
++ assert(size == computeOutputSize());
++ return size;
++ }
++ return computeOutputSize();
++ }
+
+- protected abstract long computeOutputSize();
++ protected abstract long computeOutputSize();
+
+- abstract protected void writeDataTo(OutputStream out) throws IOException;
++ abstract protected void writeDataTo(OutputStream out) throws IOException;
+
+- /** Expect a certain number of values. */
+- void expectLength(int l) {
+- assert(assertPhase(this, EXPECT_PHASE));
+- assert(valuesExpected == 0); // all at once
+- assert(l >= 0);
+- valuesExpected = l;
+- }
+- /** Expect more values. (Multiple calls accumulate.) */
+- void expectMoreLength(int l) {
+- assert(assertPhase(this, EXPECT_PHASE));
+- valuesExpected += l;
+- }
++ /** Expect a certain number of values. */
++ void expectLength(int l) {
++ assert(assertPhase(this, EXPECT_PHASE));
++ assert(valuesExpected == 0); // all at once
++ assert(l >= 0);
++ valuesExpected = l;
++ }
++ /** Expect more values. (Multiple calls accumulate.) */
++ void expectMoreLength(int l) {
++ assert(assertPhase(this, EXPECT_PHASE));
++ valuesExpected += l;
++ }
+
+
+- /// Phase change markers.
++ /// Phase change markers.
+
+- private void readyToCollect() { // called implicitly by constructor
+- setCapacity(1);
+- setPhase(COLLECT_PHASE);
+- }
+- protected void doneWriting() {
+- assert(assertPhase(this, WRITE_PHASE));
+- setPhase(DONE_PHASE);
+- }
+- private void readyToExpect() { // called implicitly by constructor
+- setPhase(EXPECT_PHASE);
+- }
+- /** Read in bytes, decoding the values. */
+- public final void readFrom(InputStream in) throws IOException {
+- assert(assertReadyToReadFrom(this, in));
+- setCapacity(valuesExpected());
+- setPhase(READ_PHASE);
+- // subclasses continue by reading their contents from input:
+- readDataFrom(in);
+- readyToDisburse();
+- }
+- abstract protected void readDataFrom(InputStream in) throws IOException;
+- protected void readyToDisburse() {
+- if (verbose > 1) Utils.log.fine("readyToDisburse "+this);
+- setPhase(DISBURSE_PHASE);
+- }
+- public void doneDisbursing() {
+- assert(assertPhase(this, DISBURSE_PHASE));
+- setPhase(DONE_PHASE);
+- }
+- public final void doneWithUnusedBand() {
+- if (isReader) {
+- assert(assertPhase(this, EXPECT_PHASE));
+- assert(valuesExpected() == 0);
+- // Fast forward:
+- setPhase(READ_PHASE);
+- setPhase(DISBURSE_PHASE);
+- setPhase(DONE_PHASE);
+- } else {
+- setPhase(FROZEN_PHASE);
+- }
+- }
++ private void readyToCollect() { // called implicitly by constructor
++ setCapacity(1);
++ setPhase(COLLECT_PHASE);
++ }
++ protected void doneWriting() {
++ assert(assertPhase(this, WRITE_PHASE));
++ setPhase(DONE_PHASE);
++ }
++ private void readyToExpect() { // called implicitly by constructor
++ setPhase(EXPECT_PHASE);
++ }
++ /** Read in bytes, decoding the values. */
++ public final void readFrom(InputStream in) throws IOException {
++ assert(assertReadyToReadFrom(this, in));
++ setCapacity(valuesExpected());
++ setPhase(READ_PHASE);
++ // subclasses continue by reading their contents from input:
++ readDataFrom(in);
++ readyToDisburse();
++ }
++ abstract protected void readDataFrom(InputStream in) throws IOException;
++ protected void readyToDisburse() {
++ if (verbose > 1) Utils.log.fine("readyToDisburse "+this);
++ setPhase(DISBURSE_PHASE);
++ }
++ public void doneDisbursing() {
++ assert(assertPhase(this, DISBURSE_PHASE));
++ setPhase(DONE_PHASE);
++ }
++ public final void doneWithUnusedBand() {
++ if (isReader) {
++ assert(assertPhase(this, EXPECT_PHASE));
++ assert(valuesExpected() == 0);
++ // Fast forward:
++ setPhase(READ_PHASE);
++ setPhase(DISBURSE_PHASE);
++ setPhase(DONE_PHASE);
++ } else {
++ setPhase(FROZEN_PHASE);
++ }
++ }
+
+- protected void setPhase(int newPhase) {
+- assert(assertPhaseChangeOK(this, phase, newPhase));
+- this.phase = newPhase;
+- }
++ protected void setPhase(int newPhase) {
++ assert(assertPhaseChangeOK(this, phase, newPhase));
++ this.phase = newPhase;
++ }
+
+- protected int lengthForDebug = -1; // DEBUG ONLY
+- public String toString() { // DEBUG ONLY
+- int length = (lengthForDebug != -1 ? lengthForDebug : length());
+- String str = name;
+- if (length != 0)
+- str += "[" + length + "]";
+- if (elementCountForDebug != 0)
+- str += "(" + elementCountForDebug + ")";
+- return str;
+- }
++ protected int lengthForDebug = -1; // DEBUG ONLY
++ public String toString() { // DEBUG ONLY
++ int length = (lengthForDebug != -1 ? lengthForDebug : length());
++ String str = name;
++ if (length != 0)
++ str += "[" + length + "]";
++ if (elementCountForDebug != 0)
++ str += "(" + elementCountForDebug + ")";
++ return str;
++ }
+ }
+
+ class ValueBand extends Band {
+- private int[] values; // must be null in EXPECT phase
+- private int length;
+- private int valuesDisbursed;
++ private int[] values; // must be null in EXPECT phase
++ private int length;
++ private int valuesDisbursed;
+
+- private CodingMethod bandCoding;
+- private byte[] metaCoding;
++ private CodingMethod bandCoding;
++ private byte[] metaCoding;
+
+- protected ValueBand(String name, Coding regularCoding) {
+- super(name, regularCoding);
+- }
++ protected ValueBand(String name, Coding regularCoding) {
++ super(name, regularCoding);
++ }
+
+- public int capacity() {
+- return values == null ? -1 : values.length;
+- }
++ public int capacity() {
++ return values == null ? -1 : values.length;
++ }
+
+- /** Declare predicted or needed capacity. */
+- protected void setCapacity(int cap) {
+- assert(length <= cap);
+- if (cap == -1) { values = null; return; }
+- values = realloc(values, cap);
+- }
++ /** Declare predicted or needed capacity. */
++ protected void setCapacity(int cap) {
++ assert(length <= cap);
++ if (cap == -1) { values = null; return; }
++ values = realloc(values, cap);
++ }
+
+- public int length() {
+- return length;
+- }
+- protected int valuesRemainingForDebug() {
+- return length - valuesDisbursed;
+- }
+- protected int valueAtForDebug(int i) {
+- return values[i];
+- }
++ public int length() {
++ return length;
++ }
++ protected int valuesRemainingForDebug() {
++ return length - valuesDisbursed;
++ }
++ protected int valueAtForDebug(int i) {
++ return values[i];
++ }
+
+- void patchValue(int i, int value) {
+- // Only one use for this.
+- assert(this == archive_header_S);
+- assert(i == AH_ARCHIVE_SIZE_HI || i == AH_ARCHIVE_SIZE_LO);
+- assert(i < length); // must have already output a dummy
+- values[i] = value;
+- outputSize = -1; // decache
+- }
++ void patchValue(int i, int value) {
++ // Only one use for this.
++ assert(this == archive_header_S);
++ assert(i == AH_ARCHIVE_SIZE_HI || i == AH_ARCHIVE_SIZE_LO);
++ assert(i < length); // must have already output a dummy
++ values[i] = value;
++ outputSize = -1; // decache
++ }
+
+- protected void initializeValues(int[] values) {
+- assert(assertCanChangeLength(this));
+- assert(length == 0);
+- this.values = values;
+- this.length = values.length;
+- }
++ protected void initializeValues(int[] values) {
++ assert(assertCanChangeLength(this));
++ assert(length == 0);
++ this.values = values;
++ this.length = values.length;
++ }
+
+- /** Collect one value, or store one decoded value. */
+- protected void addValue(int x) {
+- assert(assertCanChangeLength(this));
+- if (length == values.length)
+- setCapacity(length < 1000 ? length * 10 : length * 2);
+- values[length++] = x;
+- }
++ /** Collect one value, or store one decoded value. */
++ protected void addValue(int x) {
++ assert(assertCanChangeLength(this));
++ if (length == values.length)
++ setCapacity(length < 1000 ? length * 10 : length * 2);
++ values[length++] = x;
++ }
+
+- private boolean canVaryCoding() {
+- if (!optVaryCodings) return false;
+- if (length == 0) return false;
+- // Can't read band_headers w/o the archive header:
+- if (this == archive_header_0) return false;
+- if (this == archive_header_S) return false;
+- if (this == archive_header_1) return false;
+- // BYTE1 bands can't vary codings, but the others can.
+- // All that's needed for the initial escape is at least
+- // 256 negative values or more than 256 non-negative values
+- return (regularCoding.min() <= -256 || regularCoding.max() >= 256);
+- }
++ private boolean canVaryCoding() {
++ if (!optVaryCodings) return false;
++ if (length == 0) return false;
++ // Can't read band_headers w/o the archive header:
++ if (this == archive_header_0) return false;
++ if (this == archive_header_S) return false;
++ if (this == archive_header_1) return false;
++ // BYTE1 bands can't vary codings, but the others can.
++ // All that's needed for the initial escape is at least
++ // 256 negative values or more than 256 non-negative values
++ return (regularCoding.min() <= -256 || regularCoding.max() >= 256);
++ }
+
+- private boolean shouldVaryCoding() {
+- assert(canVaryCoding());
+- if (effort < MAX_EFFORT && length < SHORT_BAND_HEURISTIC)
+- return false;
+- return true;
+- }
++ private boolean shouldVaryCoding() {
++ assert(canVaryCoding());
++ if (effort < MAX_EFFORT && length < SHORT_BAND_HEURISTIC)
++ return false;
++ return true;
++ }
+
+- protected void chooseBandCodings() throws IOException {
+- boolean canVary = canVaryCoding();
+- if (!canVary || !shouldVaryCoding()) {
+- if (regularCoding.canRepresent(values, 0, length)) {
+- bandCoding = regularCoding;
+- } else {
+- assert(canVary);
+- if (verbose > 1)
+- Utils.log.fine("regular coding fails in band "+name());
+- bandCoding = UNSIGNED5;
+- }
+- outputSize = -1;
+- } else {
+- int[] sizes = {0,0};
+- bandCoding = chooseCoding(values, 0, length,
+- regularCoding, name(),
+- sizes);
+- outputSize = sizes[CodingChooser.BYTE_SIZE];
+- if (outputSize == 0) // CodingChooser failed to size it.
+- outputSize = -1;
+- }
++ protected void chooseBandCodings() throws IOException {
++ boolean canVary = canVaryCoding();
++ if (!canVary || !shouldVaryCoding()) {
++ if (regularCoding.canRepresent(values, 0, length)) {
++ bandCoding = regularCoding;
++ } else {
++ assert(canVary);
++ if (verbose > 1)
++ Utils.log.fine("regular coding fails in band "+name());
++ bandCoding = UNSIGNED5;
++ }
++ outputSize = -1;
++ } else {
++ int[] sizes = {0,0};
++ bandCoding = chooseCoding(values, 0, length,
++ regularCoding, name(),
++ sizes);
++ outputSize = sizes[CodingChooser.BYTE_SIZE];
++ if (outputSize == 0) // CodingChooser failed to size it.
++ outputSize = -1;
++ }
+
+- // Compute and save the meta-coding bytes also.
+- if (bandCoding != regularCoding) {
+- metaCoding = bandCoding.getMetaCoding(regularCoding);
+- if (verbose > 1) {
+- Utils.log.fine("alternate coding "+this+" "+bandCoding);
+- }
+- } else if (canVary &&
+- decodeEscapeValue(values[0], regularCoding) >= 0) {
+- // Need an explicit default.
+- metaCoding = defaultMetaCoding;
+- } else {
+- // Common case: Zero bytes of meta coding.
+- metaCoding = noMetaCoding;
+- }
+- if (metaCoding.length > 0
+- && (verbose > 2 || verbose > 1 && metaCoding.length > 1)) {
+- StringBuffer sb = new StringBuffer();
+- for (int i = 0; i < metaCoding.length; i++) {
+- if (i == 1) sb.append(" /");
+- sb.append(" ").append(metaCoding[i] & 0xFF);
+- }
+- Utils.log.fine(" meta-coding "+sb);
+- }
++ // Compute and save the meta-coding bytes also.
++ if (bandCoding != regularCoding) {
++ metaCoding = bandCoding.getMetaCoding(regularCoding);
++ if (verbose > 1) {
++ Utils.log.fine("alternate coding "+this+" "+bandCoding);
++ }
++ } else if (canVary &&
++ decodeEscapeValue(values[0], regularCoding) >= 0) {
++ // Need an explicit default.
++ metaCoding = defaultMetaCoding;
++ } else {
++ // Common case: Zero bytes of meta coding.
++ metaCoding = noMetaCoding;
++ }
++ if (metaCoding.length > 0
++ && (verbose > 2 || verbose > 1 && metaCoding.length > 1)) {
++ StringBuffer sb = new StringBuffer();
++ for (int i = 0; i < metaCoding.length; i++) {
++ if (i == 1) sb.append(" /");
++ sb.append(" ").append(metaCoding[i] & 0xFF);
++ }
++ Utils.log.fine(" meta-coding "+sb);
++ }
+
+- assert((outputSize < 0) ||
+- !(bandCoding instanceof Coding) ||
+- (outputSize == ((Coding)bandCoding)
+- .getLength(values, 0, length)))
+- : (bandCoding+" : "+
+- outputSize+" != "+
+- ((Coding)bandCoding).getLength(values, 0, length)
+- +" ?= "+getCodingChooser().computeByteSize(bandCoding,values,0,length)
+- );
++ assert((outputSize < 0) ||
++ !(bandCoding instanceof Coding) ||
++ (outputSize == ((Coding)bandCoding)
++ .getLength(values, 0, length)))
++ : (bandCoding+" : "+
++ outputSize+" != "+
++ ((Coding)bandCoding).getLength(values, 0, length)
++ +" ?= "+getCodingChooser().computeByteSize(bandCoding,values,0,length)
++ );
+
+- // Compute outputSize of the escape value X, if any.
+- if (metaCoding.length > 0) {
+- // First byte XB of meta-coding is treated specially,
+- // but any other bytes go into the band headers band.
+- // This must be done before any other output happens.
+- if (outputSize >= 0)
+- outputSize += computeEscapeSize(); // good cache
+- // Other bytes go into band_headers.
+- for (int i = 1; i < metaCoding.length; i++) {
+- band_headers.putByte(metaCoding[i] & 0xFF);
+- }
+- }
+- }
++ // Compute outputSize of the escape value X, if any.
++ if (metaCoding.length > 0) {
++ // First byte XB of meta-coding is treated specially,
++ // but any other bytes go into the band headers band.
++ // This must be done before any other output happens.
++ if (outputSize >= 0)
++ outputSize += computeEscapeSize(); // good cache
++ // Other bytes go into band_headers.
++ for (int i = 1; i < metaCoding.length; i++) {
++ band_headers.putByte(metaCoding[i] & 0xFF);
++ }
++ }
++ }
+
+- protected long computeOutputSize() {
+- outputSize = getCodingChooser().computeByteSize(bandCoding,
+- values, 0, length);
+- assert(outputSize < Integer.MAX_VALUE);
+- outputSize += computeEscapeSize();
+- return outputSize;
+- }
++ protected long computeOutputSize() {
++ outputSize = getCodingChooser().computeByteSize(bandCoding,
++ values, 0, length);
++ assert(outputSize < Integer.MAX_VALUE);
++ outputSize += computeEscapeSize();
++ return outputSize;
++ }
+
+- protected int computeEscapeSize() {
+- if (metaCoding.length == 0) return 0;
+- int XB = metaCoding[0] & 0xFF;
+- int X = encodeEscapeValue(XB, regularCoding);
+- return regularCoding.setD(0).getLength(X);
+- }
++ protected int computeEscapeSize() {
++ if (metaCoding.length == 0) return 0;
++ int XB = metaCoding[0] & 0xFF;
++ int X = encodeEscapeValue(XB, regularCoding);
++ return regularCoding.setD(0).getLength(X);
++ }
+
+- protected void writeDataTo(OutputStream out) throws IOException {
+- if (length == 0) return; // nothing to write
+- long len0 = 0;
+- if (out == outputCounter) {
+- len0 = outputCounter.getCount();
+- }
+- if (metaCoding.length > 0) {
+- int XB = metaCoding[0] & 0xFF;
+- // We need an explicit band header, either because
+- // there is a non-default coding method, or because
+- // the first value would be parsed as an escape value.
+- int X = encodeEscapeValue(XB, regularCoding);
+- //System.out.println("X="+X+" XB="+XB+" in "+this);
+- regularCoding.setD(0).writeTo(out, X);
+- }
+- bandCoding.writeArrayTo(out, values, 0, length);
+- if (out == outputCounter) {
+- long len1 = outputCounter.getCount();
+- assert(outputSize == outputCounter.getCount() - len0)
+- : (outputSize+" != "+outputCounter.getCount()+"-"+len0);
+- }
+- if (optDumpBands) dumpBand();
+- }
++ protected void writeDataTo(OutputStream out) throws IOException {
++ if (length == 0) return; // nothing to write
++ long len0 = 0;
++ if (out == outputCounter) {
++ len0 = outputCounter.getCount();
++ }
++ if (metaCoding.length > 0) {
++ int XB = metaCoding[0] & 0xFF;
++ // We need an explicit band header, either because
++ // there is a non-default coding method, or because
++ // the first value would be parsed as an escape value.
++ int X = encodeEscapeValue(XB, regularCoding);
++ //System.out.println("X="+X+" XB="+XB+" in "+this);
++ regularCoding.setD(0).writeTo(out, X);
++ }
++ bandCoding.writeArrayTo(out, values, 0, length);
++ if (out == outputCounter) {
++ long len1 = outputCounter.getCount();
++ assert(outputSize == outputCounter.getCount() - len0)
++ : (outputSize+" != "+outputCounter.getCount()+"-"+len0);
++ }
++ if (optDumpBands) dumpBand();
++ }
+
+- protected void readDataFrom(InputStream in) throws IOException {
+- length = valuesExpected();
+- if (length == 0) return; // nothing to read
+- if (verbose > 1)
+- Utils.log.fine("Reading band "+this);
+- if (!canVaryCoding()) {
+- bandCoding = regularCoding;
+- metaCoding = noMetaCoding;
+- } else {
+- assert(in.markSupported()); // input must be buffered
+- in.mark(Coding.B_MAX);
+- int X = regularCoding.setD(0).readFrom(in);
+- int XB = decodeEscapeValue(X, regularCoding);
+- if (XB < 0) {
+- // Do not consume this value. No alternate coding.
+- in.reset();
+- XB = _meta_default;
+- bandCoding = regularCoding;
+- metaCoding = noMetaCoding;
+- } else if (XB == _meta_default) {
+- bandCoding = regularCoding;
+- metaCoding = defaultMetaCoding;
+- } else {
+- if (verbose > 2)
+- Utils.log.fine("found X="+X+" => XB="+XB);
+- bandCoding = getBandHeader(XB, regularCoding);
+- // This is really used only by dumpBands.
+- int p0 = bandHeaderBytePos0;
+- int p1 = bandHeaderBytePos;
+- metaCoding = new byte[p1-p0];
+- System.arraycopy(bandHeaderBytes, p0,
+- metaCoding, 0, metaCoding.length);
+- }
+- }
+- if (bandCoding != regularCoding) {
+- if (verbose > 1)
+- Utils.log.fine(name()+": irregular coding "+bandCoding);
+- }
+- bandCoding.readArrayFrom(in, values, 0, length);
+- if (optDumpBands) dumpBand();
+- }
++ protected void readDataFrom(InputStream in) throws IOException {
++ length = valuesExpected();
++ if (length == 0) return; // nothing to read
++ if (verbose > 1)
++ Utils.log.fine("Reading band "+this);
++ if (!canVaryCoding()) {
++ bandCoding = regularCoding;
++ metaCoding = noMetaCoding;
++ } else {
++ assert(in.markSupported()); // input must be buffered
++ in.mark(Coding.B_MAX);
++ int X = regularCoding.setD(0).readFrom(in);
++ int XB = decodeEscapeValue(X, regularCoding);
++ if (XB < 0) {
++ // Do not consume this value. No alternate coding.
++ in.reset();
++ XB = _meta_default;
++ bandCoding = regularCoding;
++ metaCoding = noMetaCoding;
++ } else if (XB == _meta_default) {
++ bandCoding = regularCoding;
++ metaCoding = defaultMetaCoding;
++ } else {
++ if (verbose > 2)
++ Utils.log.fine("found X="+X+" => XB="+XB);
++ bandCoding = getBandHeader(XB, regularCoding);
++ // This is really used only by dumpBands.
++ int p0 = bandHeaderBytePos0;
++ int p1 = bandHeaderBytePos;
++ metaCoding = new byte[p1-p0];
++ System.arraycopy(bandHeaderBytes, p0,
++ metaCoding, 0, metaCoding.length);
++ }
++ }
++ if (bandCoding != regularCoding) {
++ if (verbose > 1)
++ Utils.log.fine(name()+": irregular coding "+bandCoding);
++ }
++ bandCoding.readArrayFrom(in, values, 0, length);
++ if (optDumpBands) dumpBand();
++ }
+
+- public void doneDisbursing() {
+- super.doneDisbursing();
+- values = null; // for GC
+- }
++ public void doneDisbursing() {
++ super.doneDisbursing();
++ values = null; // for GC
++ }
+
+- private void dumpBand() throws IOException {
+- assert(optDumpBands);
+- PrintStream ps = new PrintStream(getDumpStream(this, ".txt"));
+- String irr = (bandCoding == regularCoding) ? "" : " irregular";
+- ps.print("# length="+length+
+- " size="+outputSize()+
+- irr+" coding="+bandCoding);
+- if (metaCoding != noMetaCoding) {
+- StringBuffer sb = new StringBuffer();
+- for (int i = 0; i < metaCoding.length; i++) {
+- if (i == 1) sb.append(" /");
+- sb.append(" ").append(metaCoding[i] & 0xFF);
+- }
+- ps.print(" //header: "+sb);
+- }
+- printArrayTo(ps, values, 0, length);
+- ps.close();
+- OutputStream ds = getDumpStream(this, ".bnd");
+- bandCoding.writeArrayTo(ds, values, 0, length);
+- ds.close();
+- }
++ private void dumpBand() throws IOException {
++ assert(optDumpBands);
++ PrintStream ps = new PrintStream(getDumpStream(this, ".txt"));
++ String irr = (bandCoding == regularCoding) ? "" : " irregular";
++ ps.print("# length="+length+
++ " size="+outputSize()+
++ irr+" coding="+bandCoding);
++ if (metaCoding != noMetaCoding) {
++ StringBuffer sb = new StringBuffer();
++ for (int i = 0; i < metaCoding.length; i++) {
++ if (i == 1) sb.append(" /");
++ sb.append(" ").append(metaCoding[i] & 0xFF);
++ }
++ ps.print(" //header: "+sb);
++ }
++ printArrayTo(ps, values, 0, length);
++ ps.close();
++ OutputStream ds = getDumpStream(this, ".bnd");
++ bandCoding.writeArrayTo(ds, values, 0, length);
++ ds.close();
++ }
+
+- /** Disburse one value. */
+- protected int getValue() {
+- assert(phase() == DISBURSE_PHASE);
+- assert(valuesDisbursed < length);
+- return values[valuesDisbursed++];
+- }
++ /** Disburse one value. */
++ protected int getValue() {
++ assert(phase() == DISBURSE_PHASE);
++ assert(valuesDisbursed < length);
++ return values[valuesDisbursed++];
++ }
+
+- /** Reset for another pass over the same value set. */
+- public void resetForSecondPass() {
+- assert(phase() == DISBURSE_PHASE);
+- assert(valuesDisbursed == length()); // 1st pass is complete
+- valuesDisbursed = 0;
+- }
++ /** Reset for another pass over the same value set. */
++ public void resetForSecondPass() {
++ assert(phase() == DISBURSE_PHASE);
++ assert(valuesDisbursed == length()); // 1st pass is complete
++ valuesDisbursed = 0;
++ }
+ }
+
+ class ByteBand extends Band {
+- private ByteArrayOutputStream bytes; // input buffer
+- private ByteArrayOutputStream bytesForDump;
+- private InputStream in;
++ private ByteArrayOutputStream bytes; // input buffer
++ private ByteArrayOutputStream bytesForDump;
++ private InputStream in;
+
+- public ByteBand(String name) {
+- super(name, BYTE1);
+- }
++ public ByteBand(String name) {
++ super(name, BYTE1);
++ }
+
+- public int capacity() {
+- return bytes == null ? -1 : Integer.MAX_VALUE;
+- }
+- protected void setCapacity(int cap) {
+- assert(bytes == null); // do this just once
+- bytes = new ByteArrayOutputStream(cap);
+- }
+- public void destroy() {
+- lengthForDebug = length();
+- bytes = null;
+- }
++ public int capacity() {
++ return bytes == null ? -1 : Integer.MAX_VALUE;
++ }
++ protected void setCapacity(int cap) {
++ assert(bytes == null); // do this just once
++ bytes = new ByteArrayOutputStream(cap);
++ }
++ public void destroy() {
++ lengthForDebug = length();
++ bytes = null;
++ }
+
+- public int length() {
+- return bytes == null ? -1 : bytes.size();
+- }
+- public void reset() {
+- bytes.reset();
+- }
+- protected int valuesRemainingForDebug() {
+- return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available();
+- }
++ public int length() {
++ return bytes == null ? -1 : bytes.size();
++ }
++ public void reset() {
++ bytes.reset();
++ }
++ protected int valuesRemainingForDebug() {
++ return (bytes == null) ? -1 : ((ByteArrayInputStream)in).available();
++ }
+
+- protected void chooseBandCodings() throws IOException {
+- // No-op.
+- assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0);
+- assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0);
+- }
++ protected void chooseBandCodings() throws IOException {
++ // No-op.
++ assert(decodeEscapeValue(regularCoding.min(), regularCoding) < 0);
++ assert(decodeEscapeValue(regularCoding.max(), regularCoding) < 0);
++ }
+
+- protected long computeOutputSize() {
+- // do not cache
+- return bytes.size();
+- }
++ protected long computeOutputSize() {
++ // do not cache
++ return bytes.size();
++ }
+
+- public void writeDataTo(OutputStream out) throws IOException {
+- if (length() == 0) return;
+- bytes.writeTo(out);
+- if (optDumpBands) dumpBand();
+- destroy(); // done with the bits!
+- }
++ public void writeDataTo(OutputStream out) throws IOException {
++ if (length() == 0) return;
++ bytes.writeTo(out);
++ if (optDumpBands) dumpBand();
++ destroy(); // done with the bits!
++ }
+
+- private void dumpBand() throws IOException {
+- assert(optDumpBands);
+- OutputStream ds = getDumpStream(this, ".bnd");
+- if (bytesForDump != null)
+- bytesForDump.writeTo(ds);
+- else
+- bytes.writeTo(ds);
+- ds.close();
+- }
++ private void dumpBand() throws IOException {
++ assert(optDumpBands);
++ OutputStream ds = getDumpStream(this, ".bnd");
++ if (bytesForDump != null)
++ bytesForDump.writeTo(ds);
++ else
++ bytes.writeTo(ds);
++ ds.close();
++ }
+
+- public void readDataFrom(InputStream in) throws IOException {
+- int vex = valuesExpected();
+- if (vex == 0) return;
+- if (verbose > 1) {
+- lengthForDebug = vex;
+- Utils.log.fine("Reading band "+this);
+- lengthForDebug = -1;
+- }
+- byte[] buf = new byte[Math.min(vex, 1<<14)];
+- while (vex > 0) {
+- int nr = in.read(buf, 0, Math.min(vex, buf.length));
+- if (nr < 0) throw new EOFException();
+- bytes.write(buf, 0, nr);
+- vex -= nr;
+- }
+- if (optDumpBands) dumpBand();
+- }
++ public void readDataFrom(InputStream in) throws IOException {
++ int vex = valuesExpected();
++ if (vex == 0) return;
++ if (verbose > 1) {
++ lengthForDebug = vex;
++ Utils.log.fine("Reading band "+this);
++ lengthForDebug = -1;
++ }
++ byte[] buf = new byte[Math.min(vex, 1<<14)];
++ while (vex > 0) {
++ int nr = in.read(buf, 0, Math.min(vex, buf.length));
++ if (nr < 0) throw new EOFException();
++ bytes.write(buf, 0, nr);
++ vex -= nr;
++ }
++ if (optDumpBands) dumpBand();
++ }
+
+- public void readyToDisburse() {
+- in = new ByteArrayInputStream(bytes.toByteArray());
+- super.readyToDisburse();
+- }
++ public void readyToDisburse() {
++ in = new ByteArrayInputStream(bytes.toByteArray());
++ super.readyToDisburse();
++ }
+
+- public void doneDisbursing() {
+- super.doneDisbursing();
+- if (optDumpBands
+- && bytesForDump != null && bytesForDump.size() > 0) {
+- try {
+- dumpBand();
+- } catch (IOException ee) {
+- throw new RuntimeException(ee);
+- }
+- }
+- in = null; // GC
+- bytes = null; // GC
+- bytesForDump = null; // GC
+- }
++ public void doneDisbursing() {
++ super.doneDisbursing();
++ if (optDumpBands
++ && bytesForDump != null && bytesForDump.size() > 0) {
++ try {
++ dumpBand();
++ } catch (IOException ee) {
++ throw new RuntimeException(ee);
++ }
++ }
++ in = null; // GC
++ bytes = null; // GC
++ bytesForDump = null; // GC
++ }
+
+- // alternative to readFrom:
+- public void setInputStreamFrom(InputStream in) throws IOException {
+- assert(bytes == null);
+- assert(assertReadyToReadFrom(this, in));
+- setPhase(READ_PHASE);
+- this.in = in;
+- if (optDumpBands) {
+- // Tap the stream.
+- bytesForDump = new ByteArrayOutputStream();
+- this.in = new FilterInputStream(in) {
+- public int read() throws IOException {
+- int ch = in.read();
+- if (ch >= 0) bytesForDump.write(ch);
+- return ch;
+- }
+- public int read(byte b[], int off, int len) throws IOException {
+- int nr = in.read(b, off, len);
+- if (nr >= 0) bytesForDump.write(b, off, nr);
+- return nr;
+- }
+- };
+- }
+- super.readyToDisburse();
+- }
++ // alternative to readFrom:
++ public void setInputStreamFrom(InputStream in) throws IOException {
++ assert(bytes == null);
++ assert(assertReadyToReadFrom(this, in));
++ setPhase(READ_PHASE);
++ this.in = in;
++ if (optDumpBands) {
++ // Tap the stream.
++ bytesForDump = new ByteArrayOutputStream();
++ this.in = new FilterInputStream(in) {
++ public int read() throws IOException {
++ int ch = in.read();
++ if (ch >= 0) bytesForDump.write(ch);
++ return ch;
++ }
++ public int read(byte b[], int off, int len) throws IOException {
++ int nr = in.read(b, off, len);
++ if (nr >= 0) bytesForDump.write(b, off, nr);
++ return nr;
++ }
++ };
++ }
++ super.readyToDisburse();
++ }
+
+- public OutputStream collectorStream() {
+- assert(phase() == COLLECT_PHASE);
+- assert(bytes != null);
+- return bytes;
+- }
++ public OutputStream collectorStream() {
++ assert(phase() == COLLECT_PHASE);
++ assert(bytes != null);
++ return bytes;
++ }
+
+- public InputStream getInputStream() {
+- assert(phase() == DISBURSE_PHASE);
+- assert(in != null);
+- return in;
+- }
+- public int getByte() throws IOException {
+- int b = getInputStream().read();
+- if (b < 0) throw new EOFException();
+- return b;
+- }
+- public void putByte(int b) throws IOException {
+- assert(b == (b & 0xFF));
+- collectorStream().write(b);
+- }
+- public String toString() {
+- return "byte "+super.toString();
+- }
++ public InputStream getInputStream() {
++ assert(phase() == DISBURSE_PHASE);
++ assert(in != null);
++ return in;
++ }
++ public int getByte() throws IOException {
++ int b = getInputStream().read();
++ if (b < 0) throw new EOFException();
++ return b;
++ }
++ public void putByte(int b) throws IOException {
++ assert(b == (b & 0xFF));
++ collectorStream().write(b);
++ }
++ public String toString() {
++ return "byte "+super.toString();
++ }
+ }
+
+ class IntBand extends ValueBand {
+- // The usual coding for bands is 7bit/5byte/delta.
+- public IntBand(String name, Coding regularCoding) {
+- super(name, regularCoding);
+- }
++ // The usual coding for bands is 7bit/5byte/delta.
++ public IntBand(String name, Coding regularCoding) {
++ super(name, regularCoding);
++ }
+
+- public void putInt(int x) {
+- assert(phase() == COLLECT_PHASE);
+- addValue(x);
+- }
++ public void putInt(int x) {
++ assert(phase() == COLLECT_PHASE);
++ addValue(x);
++ }
+
+- public int getInt() {
+- return getValue();
+- }
+- /** Return the sum of all values in this band. */
+- public int getIntTotal() {
+- assert(phase() == DISBURSE_PHASE);
+- // assert that this is the whole pass; no other reads allowed
+- assert(valuesRemainingForDebug() == length());
+- int total = 0;
+- for (int k = length(); k > 0; k--) {
+- total += getInt();
+- }
+- resetForSecondPass();
+- return total;
+- }
+- /** Return the occurrence count of a specific value in this band. */
+- public int getIntCount(int value) {
+- assert(phase() == DISBURSE_PHASE);
+- // assert that this is the whole pass; no other reads allowed
+- assert(valuesRemainingForDebug() == length());
+- int total = 0;
+- for (int k = length(); k > 0; k--) {
+- if (getInt() == value) {
+- total += 1;
+- }
+- }
+- resetForSecondPass();
+- return total;
+- }
++ public int getInt() {
++ return getValue();
++ }
++ /** Return the sum of all values in this band. */
++ public int getIntTotal() {
++ assert(phase() == DISBURSE_PHASE);
++ // assert that this is the whole pass; no other reads allowed
++ assert(valuesRemainingForDebug() == length());
++ int total = 0;
++ for (int k = length(); k > 0; k--) {
++ total += getInt();
++ }
++ resetForSecondPass();
++ return total;
++ }
++ /** Return the occurrence count of a specific value in this band. */
++ public int getIntCount(int value) {
++ assert(phase() == DISBURSE_PHASE);
++ // assert that this is the whole pass; no other reads allowed
++ assert(valuesRemainingForDebug() == length());
++ int total = 0;
++ for (int k = length(); k > 0; k--) {
++ if (getInt() == value) {
++ total += 1;
++ }
++ }
++ resetForSecondPass();
++ return total;
++ }
+ }
+
+ static int getIntTotal(int[] values) {
+- int total = 0;
+- for (int i = 0; i < values.length; i++) {
+- total += values[i];
+- }
+- return total;
++ int total = 0;
++ for (int i = 0; i < values.length; i++) {
++ total += values[i];
++ }
++ return total;
+ }
+
+ class CPRefBand extends ValueBand {
+- Index index;
+- boolean nullOK;
++ Index index;
++ boolean nullOK;
+
+- public CPRefBand(String name, Coding regularCoding, byte cpTag, boolean nullOK) {
+- super(name, regularCoding);
+- this.nullOK = nullOK;
+- if (cpTag != CONSTANT_None)
+- setBandIndex(this, cpTag);
+- }
+- public CPRefBand(String name, Coding regularCoding, byte cpTag) {
+- this(name, regularCoding, cpTag, false);
+- }
+- public CPRefBand(String name, Coding regularCoding, Object undef) {
+- this(name, regularCoding, CONSTANT_None, false);
+- }
++ public CPRefBand(String name, Coding regularCoding, byte cpTag, boolean nullOK) {
++ super(name, regularCoding);
++ this.nullOK = nullOK;
++ if (cpTag != CONSTANT_None)
++ setBandIndex(this, cpTag);
++ }
++ public CPRefBand(String name, Coding regularCoding, byte cpTag) {
++ this(name, regularCoding, cpTag, false);
++ }
++ public CPRefBand(String name, Coding regularCoding, Object undef) {
++ this(name, regularCoding, CONSTANT_None, false);
++ }
+
+- public void setIndex(Index index) {
+- this.index = index;
+- }
++ public void setIndex(Index index) {
++ this.index = index;
++ }
+
+- protected void readDataFrom(InputStream in) throws IOException {
+- super.readDataFrom(in);
+- assert(assertValidCPRefs(this));
+- }
++ protected void readDataFrom(InputStream in) throws IOException {
++ super.readDataFrom(in);
++ assert(assertValidCPRefs(this));
++ }
+
+- /** Write a constant pool reference. */
+- public void putRef(Entry e) {
+- assert(index != null);
+- addValue(encodeRefOrNull(e, index));
+- }
+- public void putRef(Entry e, Index index) {
+- assert(this.index == null);
+- addValue(encodeRefOrNull(e, index));
+- }
+- public void putRef(Entry e, byte cptag) {
+- putRef(e, getCPIndex(cptag));
+- }
++ /** Write a constant pool reference. */
++ public void putRef(Entry e) {
++ addValue(encodeRefOrNull(e, index));
++ }
++ public void putRef(Entry e, Index index) {
++ assert(this.index == null);
++ addValue(encodeRefOrNull(e, index));
++ }
++ public void putRef(Entry e, byte cptag) {
++ putRef(e, getCPIndex(cptag));
++ }
+
+- public Entry getRef() {
+- if (index == null) Utils.log.warning("No index for "+this);
+- assert(index != null);
+- return decodeRefOrNull(getValue(), index);
+- }
+- public Entry getRef(Index index) {
+- assert(this.index == null);
+- return decodeRefOrNull(getValue(), index);
+- }
+- public Entry getRef(byte cptag) {
+- return getRef(getCPIndex(cptag));
+- }
++ public Entry getRef() {
++ if (index == null) Utils.log.warning("No index for "+this);
++ assert(index != null);
++ return decodeRefOrNull(getValue(), index);
++ }
++ public Entry getRef(Index index) {
++ assert(this.index == null);
++ return decodeRefOrNull(getValue(), index);
++ }
++ public Entry getRef(byte cptag) {
++ return getRef(getCPIndex(cptag));
++ }
+
+- private int encodeRefOrNull(Entry e, Index index) {
+- int nonNullCode; // NNC is the coding which assumes nulls are rare
+- if (e == null) {
+- nonNullCode = -1; // negative values are rare
+- } else {
+- nonNullCode = encodeRef(e, index);
+- }
+- // If nulls are expected, increment, to make -1 code turn to 0.
+- return (nullOK ? 1 : 0) + nonNullCode;
+- }
+- private Entry decodeRefOrNull(int code, Index index) {
+- // Inverse to encodeRefOrNull...
+- int nonNullCode = code - (nullOK ? 1 : 0);
+- if (nonNullCode == -1) {
+- return null;
+- } else {
+- return decodeRef(nonNullCode, index);
+- }
+- }
++ private int encodeRefOrNull(Entry e, Index index) {
++ int nonNullCode; // NNC is the coding which assumes nulls are rare
++ if (e == null) {
++ nonNullCode = -1; // negative values are rare
++ } else {
++ nonNullCode = encodeRef(e, index);
++ }
++ // If nulls are expected, increment, to make -1 code turn to 0.
++ return (nullOK ? 1 : 0) + nonNullCode;
++ }
++ private Entry decodeRefOrNull(int code, Index index) {
++ // Inverse to encodeRefOrNull...
++ int nonNullCode = code - (nullOK ? 1 : 0);
++ if (nonNullCode == -1) {
++ return null;
++ } else {
++ return decodeRef(nonNullCode, index);
++ }
++ }
+ }
+
+ // Bootstrap support for CPRefBands. These are needed to record
+@@ -1039,51 +1037,53 @@ class BandStructure implements Constants
+
+
+ int encodeRef(Entry e, Index ix) {
+- int coding = ix.indexOf(e);
+- if (verbose > 2)
+- Utils.log.fine("putRef "+coding+" => "+e);
+- return coding;
++ if (ix == null)
++ throw new RuntimeException("null index for " + e.stringValue());
++ int coding = ix.indexOf(e);
++ if (verbose > 2)
++ Utils.log.fine("putRef "+coding+" => "+e);
++ return coding;
+ }
+
+ Entry decodeRef(int n, Index ix) {
+- if (n < 0 || n >= ix.size())
+- Utils.log.warning("decoding bad ref "+n+" in "+ix);
+- Entry e = ix.getEntry(n);
+- if (verbose > 2)
+- Utils.log.fine("getRef "+n+" => "+e);
+- return e;
++ if (n < 0 || n >= ix.size())
++ Utils.log.warning("decoding bad ref "+n+" in "+ix);
++ Entry e = ix.getEntry(n);
++ if (verbose > 2)
++ Utils.log.fine("getRef "+n+" => "+e);
++ return e;
+ }
+
+ private CodingChooser codingChooser;
+ protected CodingChooser getCodingChooser() {
+- if (codingChooser == null) {
+- codingChooser = new CodingChooser(effort, basicCodings);
+- if (codingChooser.stress != null
+- && this instanceof PackageWriter) {
+- // Twist the random state based on my first file.
+- // This sends each segment off in a different direction.
+- List classes = ((PackageWriter)this).pkg.classes;
+- if (!classes.isEmpty()) {
+- Package.Class cls = (Package.Class) classes.get(0);
+- codingChooser.addStressSeed(cls.getName().hashCode());
+- }
+- }
+- }
+- return codingChooser;
++ if (codingChooser == null) {
++ codingChooser = new CodingChooser(effort, basicCodings);
++ if (codingChooser.stress != null
++ && this instanceof PackageWriter) {
++ // Twist the random state based on my first file.
++ // This sends each segment off in a different direction.
++ List classes = ((PackageWriter)this).pkg.classes;
++ if (!classes.isEmpty()) {
++ Package.Class cls = (Package.Class) classes.get(0);
++ codingChooser.addStressSeed(cls.getName().hashCode());
++ }
++ }
++ }
++ return codingChooser;
+ }
+
+ public CodingMethod chooseCoding(int[] values, int start, int end,
+- Coding regular, String bandName,
+- int[] sizes) {
+- assert(optVaryCodings);
+- if (effort <= MIN_EFFORT) {
+- return regular;
+- }
+- CodingChooser cc = getCodingChooser();
+- if (verbose > 1 || cc.verbose > 1) {
+- Utils.log.fine("--- chooseCoding "+bandName);
+- }
+- return cc.choose(values, start, end, regular, sizes);
++ Coding regular, String bandName,
++ int[] sizes) {
++ assert(optVaryCodings);
++ if (effort <= MIN_EFFORT) {
++ return regular;
++ }
++ CodingChooser cc = getCodingChooser();
++ if (verbose > 1 || cc.verbose > 1) {
++ Utils.log.fine("--- chooseCoding "+bandName);
++ }
++ return cc.choose(values, start, end, regular, sizes);
+ }
+
+ static final byte[] defaultMetaCoding = { _meta_default };
+@@ -1108,201 +1108,201 @@ class BandStructure implements Constants
+ // Result is in [0..255] if XB was successfully extracted, else -1.
+ // See section "Coding Specifier Meta-Encoding" in the JSR 200 spec.
+ protected static int decodeEscapeValue(int X, Coding regularCoding) {
+- // The first value in a band is always coded with the default coding D.
+- // If this first value X is an escape value, it actually represents the
+- // first (and perhaps only) byte of a meta-coding.
+- // Result is in [0..255] if XB was successfully extracted, else -1.
+- if (regularCoding.B() == 1 || regularCoding.L() == 0)
+- return -1; // degenerate regular coding (BYTE1)
+- if (regularCoding.S() != 0) {
+- if (-256 <= X && X <= -1 && regularCoding.min() <= -256) {
+- int XB = -1-X;
+- assert(XB >= 0 && XB < 256);
+- return XB;
+- }
+- } else {
+- int L = regularCoding.L();
+- if (L <= X && X <= L+255 && regularCoding.max() >= L+255) {
+- int XB = X-L;
+- assert(XB >= 0 && XB < 256);
+- return XB;
+- }
+- }
+- return -1; // negative value for failure
++ // The first value in a band is always coded with the default coding D.
++ // If this first value X is an escape value, it actually represents the
++ // first (and perhaps only) byte of a meta-coding.
++ // Result is in [0..255] if XB was successfully extracted, else -1.
++ if (regularCoding.B() == 1 || regularCoding.L() == 0)
++ return -1; // degenerate regular coding (BYTE1)
++ if (regularCoding.S() != 0) {
++ if (-256 <= X && X <= -1 && regularCoding.min() <= -256) {
++ int XB = -1-X;
++ assert(XB >= 0 && XB < 256);
++ return XB;
++ }
++ } else {
++ int L = regularCoding.L();
++ if (L <= X && X <= L+255 && regularCoding.max() >= L+255) {
++ int XB = X-L;
++ assert(XB >= 0 && XB < 256);
++ return XB;
++ }
++ }
++ return -1; // negative value for failure
+ }
+ // Inverse to decodeEscapeValue().
+ protected static int encodeEscapeValue(int XB, Coding regularCoding) {
+- assert(XB >= 0 && XB < 256);
+- assert(regularCoding.B() > 1 && regularCoding.L() > 0);
+- int X;
+- if (regularCoding.S() != 0) {
+- assert(regularCoding.min() <= -256);
+- X = -1-XB;
+- } else {
+- int L = regularCoding.L();
+- assert(regularCoding.max() >= L+255);
+- X = XB+L;
+- }
+- assert(decodeEscapeValue(X, regularCoding) == XB)
+- : (regularCoding+" XB="+XB+" X="+X);
+- return X;
++ assert(XB >= 0 && XB < 256);
++ assert(regularCoding.B() > 1 && regularCoding.L() > 0);
++ int X;
++ if (regularCoding.S() != 0) {
++ assert(regularCoding.min() <= -256);
++ X = -1-XB;
++ } else {
++ int L = regularCoding.L();
++ assert(regularCoding.max() >= L+255);
++ X = XB+L;
++ }
++ assert(decodeEscapeValue(X, regularCoding) == XB)
++ : (regularCoding+" XB="+XB+" X="+X);
++ return X;
+ }
+
+ static {
+- boolean checkXB = false;
+- assert(checkXB = true);
+- if (checkXB) {
+- for (int i = 0; i < basicCodings.length; i++) {
+- Coding D = basicCodings[i];
+- if (D == null) continue;
+- if (D.B() == 1) continue;
+- if (D.L() == 0) continue;
+- for (int XB = 0; XB <= 255; XB++) {
+- // The following exercises decodeEscapeValue also:
+- encodeEscapeValue(XB, D);
+- }
+- }
+- }
++ boolean checkXB = false;
++ assert(checkXB = true);
++ if (checkXB) {
++ for (int i = 0; i < basicCodings.length; i++) {
++ Coding D = basicCodings[i];
++ if (D == null) continue;
++ if (D.B() == 1) continue;
++ if (D.L() == 0) continue;
++ for (int XB = 0; XB <= 255; XB++) {
++ // The following exercises decodeEscapeValue also:
++ encodeEscapeValue(XB, D);
++ }
++ }
++ }
+ }
+
+ class MultiBand extends Band {
+- MultiBand(String name, Coding regularCoding) {
+- super(name, regularCoding);
+- }
++ MultiBand(String name, Coding regularCoding) {
++ super(name, regularCoding);
++ }
+
+- public Band init() {
+- super.init();
+- // This is all just to keep the asserts happy:
+- setCapacity(0);
+- if (phase() == EXPECT_PHASE) {
+- // Fast forward:
+- setPhase(READ_PHASE);
+- setPhase(DISBURSE_PHASE);
+- }
+- return this;
+- }
++ public Band init() {
++ super.init();
++ // This is all just to keep the asserts happy:
++ setCapacity(0);
++ if (phase() == EXPECT_PHASE) {
++ // Fast forward:
++ setPhase(READ_PHASE);
++ setPhase(DISBURSE_PHASE);
++ }
++ return this;
++ }
+
+- Band[] bands = new Band[10];
+- int bandCount = 0;
++ Band[] bands = new Band[10];
++ int bandCount = 0;
+
+- int size() {
+- return bandCount;
+- }
+- Band get(int i) {
+- assert(i < bandCount);
+- return bands[i];
+- }
+- Band[] toArray() {
+- return (Band[]) realloc(bands, bandCount);
+- }
++ int size() {
++ return bandCount;
++ }
++ Band get(int i) {
++ assert(i < bandCount);
++ return bands[i];
++ }
++ Band[] toArray() {
++ return (Band[]) realloc(bands, bandCount);
++ }
+
+- void add(Band b) {
+- assert(bandCount == 0 || notePrevForAssert(b, bands[bandCount-1]));
+- if (bandCount == bands.length) {
+- bands = (Band[]) realloc(bands);
+- }
+- bands[bandCount++] = b;
+- }
++ void add(Band b) {
++ assert(bandCount == 0 || notePrevForAssert(b, bands[bandCount-1]));
++ if (bandCount == bands.length) {
++ bands = (Band[]) realloc(bands);
++ }
++ bands[bandCount++] = b;
++ }
+
+- ByteBand newByteBand(String name) {
+- ByteBand b = new ByteBand(name);
+- b.init(); add(b);
+- return b;
+- }
+- IntBand newIntBand(String name) {
+- IntBand b = new IntBand(name, regularCoding);
+- b.init(); add(b);
+- return b;
+- }
+- IntBand newIntBand(String name, Coding regularCoding) {
+- IntBand b = new IntBand(name, regularCoding);
+- b.init(); add(b);
+- return b;
+- }
+- MultiBand newMultiBand(String name, Coding regularCoding) {
+- MultiBand b = new MultiBand(name, regularCoding);
+- b.init(); add(b);
+- return b;
+- }
+- CPRefBand newCPRefBand(String name, byte cpTag) {
+- CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
+- b.init(); add(b);
+- return b;
+- }
+- CPRefBand newCPRefBand(String name, Coding regularCoding,
+- byte cpTag) {
+- CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
+- b.init(); add(b);
+- return b;
+- }
+- CPRefBand newCPRefBand(String name, Coding regularCoding,
+- byte cpTag, boolean nullOK) {
+- CPRefBand b = new CPRefBand(name, regularCoding, cpTag, nullOK);
+- b.init(); add(b);
+- return b;
+- }
++ ByteBand newByteBand(String name) {
++ ByteBand b = new ByteBand(name);
++ b.init(); add(b);
++ return b;
++ }
++ IntBand newIntBand(String name) {
++ IntBand b = new IntBand(name, regularCoding);
++ b.init(); add(b);
++ return b;
++ }
++ IntBand newIntBand(String name, Coding regularCoding) {
++ IntBand b = new IntBand(name, regularCoding);
++ b.init(); add(b);
++ return b;
++ }
++ MultiBand newMultiBand(String name, Coding regularCoding) {
++ MultiBand b = new MultiBand(name, regularCoding);
++ b.init(); add(b);
++ return b;
++ }
++ CPRefBand newCPRefBand(String name, byte cpTag) {
++ CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
++ b.init(); add(b);
++ return b;
++ }
++ CPRefBand newCPRefBand(String name, Coding regularCoding,
++ byte cpTag) {
++ CPRefBand b = new CPRefBand(name, regularCoding, cpTag);
++ b.init(); add(b);
++ return b;
++ }
++ CPRefBand newCPRefBand(String name, Coding regularCoding,
++ byte cpTag, boolean nullOK) {
++ CPRefBand b = new CPRefBand(name, regularCoding, cpTag, nullOK);
++ b.init(); add(b);
++ return b;
++ }
+
+- int bandCount() { return bandCount; }
++ int bandCount() { return bandCount; }
+
+- private int cap = -1;
+- public int capacity() { return cap; }
+- public void setCapacity(int cap) { this.cap = cap; }
++ private int cap = -1;
++ public int capacity() { return cap; }
++ public void setCapacity(int cap) { this.cap = cap; }
+
+- public int length() { return 0; }
+- public int valuesRemainingForDebug() { return 0; }
++ public int length() { return 0; }
++ public int valuesRemainingForDebug() { return 0; }
+
+- protected void chooseBandCodings() throws IOException {
+- // coding decision pass
+- for (int i = 0; i < bandCount; i++) {
+- Band b = bands[i];
+- b.chooseBandCodings();
+- }
+- }
++ protected void chooseBandCodings() throws IOException {
++ // coding decision pass
++ for (int i = 0; i < bandCount; i++) {
++ Band b = bands[i];
++ b.chooseBandCodings();
++ }
++ }
+
+- protected long computeOutputSize() {
+- // coding decision pass
+- long sum = 0;
+- for (int i = 0; i < bandCount; i++) {
+- Band b = bands[i];
+- long bsize = b.outputSize();
+- assert(bsize >= 0) : b;
+- sum += bsize;
+- }
+- // do not cache
+- return sum;
+- }
++ protected long computeOutputSize() {
++ // coding decision pass
++ long sum = 0;
++ for (int i = 0; i < bandCount; i++) {
++ Band b = bands[i];
++ long bsize = b.outputSize();
++ assert(bsize >= 0) : b;
++ sum += bsize;
++ }
++ // do not cache
++ return sum;
++ }
+
+- protected void writeDataTo(OutputStream out) throws IOException {
+- long preCount = 0;
+- if (outputCounter != null) preCount = outputCounter.getCount();
+- for (int i = 0; i < bandCount; i++) {
+- Band b = bands[i];
+- b.writeTo(out);
+- if (outputCounter != null) {
+- long postCount = outputCounter.getCount();
+- long len = postCount - preCount;
+- preCount = postCount;
+- if ((verbose > 0 && len > 0) || verbose > 1) {
+- Utils.log.info(" ...wrote "+len+" bytes from "+b);
+- }
+- }
+- }
+- }
++ protected void writeDataTo(OutputStream out) throws IOException {
++ long preCount = 0;
++ if (outputCounter != null) preCount = outputCounter.getCount();
++ for (int i = 0; i < bandCount; i++) {
++ Band b = bands[i];
++ b.writeTo(out);
++ if (outputCounter != null) {
++ long postCount = outputCounter.getCount();
++ long len = postCount - preCount;
++ preCount = postCount;
++ if ((verbose > 0 && len > 0) || verbose > 1) {
++ Utils.log.info(" ...wrote "+len+" bytes from "+b);
++ }
++ }
++ }
++ }
+
+- protected void readDataFrom(InputStream in) throws IOException {
+- assert(false); // not called?
+- for (int i = 0; i < bandCount; i++) {
+- Band b = bands[i];
+- b.readFrom(in);
+- if ((verbose > 0 && b.length() > 0) || verbose > 1) {
+- Utils.log.info(" ...read "+b);
+- }
+- }
+- }
++ protected void readDataFrom(InputStream in) throws IOException {
++ assert(false); // not called?
++ for (int i = 0; i < bandCount; i++) {
++ Band b = bands[i];
++ b.readFrom(in);
++ if ((verbose > 0 && b.length() > 0) || verbose > 1) {
++ Utils.log.info(" ...read "+b);
++ }
++ }
++ }
+
+- public String toString() {
+- return "{"+bandCount()+" bands: "+super.toString()+"}";
+- }
++ public String toString() {
++ return "{"+bandCount()+" bands: "+super.toString()+"}";
++ }
+ }
+
+ /**
+@@ -1310,42 +1310,42 @@ class BandStructure implements Constants
+ */
+ private static
+ class ByteCounter extends FilterOutputStream {
+- // (should go public under the name CountingOutputStream?)
++ // (should go public under the name CountingOutputStream?)
+
+- private long count;
++ private long count;
+
+- public ByteCounter(OutputStream out) {
+- super(out);
+- }
++ public ByteCounter(OutputStream out) {
++ super(out);
++ }
+
+- public long getCount() { return count; }
+- public void setCount(long c) { count = c; }
++ public long getCount() { return count; }
++ public void setCount(long c) { count = c; }
+
+- public void write(int b) throws IOException {
+- count++;
+- if (out != null) out.write(b);
+- }
+- public void write(byte b[], int off, int len) throws IOException {
+- count += len;
+- if (out != null) out.write(b, off, len);
+- }
+- public String toString() {
+- return String.valueOf(getCount());
+- }
++ public void write(int b) throws IOException {
++ count++;
++ if (out != null) out.write(b);
++ }
++ public void write(byte b[], int off, int len) throws IOException {
++ count += len;
++ if (out != null) out.write(b, off, len);
++ }
++ public String toString() {
++ return String.valueOf(getCount());
++ }
+ }
+ ByteCounter outputCounter;
+
+ void writeAllBandsTo(OutputStream out) throws IOException {
+- // Wrap a byte-counter around the output stream.
+- outputCounter = new ByteCounter(out);
+- out = outputCounter;
+- all_bands.writeTo(out);
+- if (verbose > 0) {
+- long nbytes = outputCounter.getCount();
+- Utils.log.info("Wrote total of "+nbytes+" bytes.");
+- assert(nbytes == archiveSize0+archiveSize1);
+- }
+- outputCounter = null;
++ // Wrap a byte-counter around the output stream.
++ outputCounter = new ByteCounter(out);
++ out = outputCounter;
++ all_bands.writeTo(out);
++ if (verbose > 0) {
++ long nbytes = outputCounter.getCount();
++ Utils.log.info("Wrote total of "+nbytes+" bytes.");
++ assert(nbytes == archiveSize0+archiveSize1);
++ }
++ outputCounter = null;
+ }
+
+ // random AO_XXX bits, decoded from the archive header
+@@ -1366,7 +1366,7 @@ class BandStructure implements Constants
+ static final int AH_SPECIAL_FORMAT_LEN = 2; // layouts/band-headers
+ static final int AH_CP_NUMBER_LEN = 4; // int/float/long/double
+ static final int AH_LENGTH_MIN = AH_LENGTH
+- -(AH_SPECIAL_FORMAT_LEN+AH_FILE_HEADER_LEN+AH_CP_NUMBER_LEN);
++ -(AH_SPECIAL_FORMAT_LEN+AH_FILE_HEADER_LEN+AH_CP_NUMBER_LEN);
+
+ // Common structure of attribute band groups:
+ static final int AB_FLAGS_HI = 0;
+@@ -1376,22 +1376,22 @@ class BandStructure implements Constants
+ static final int AB_ATTR_CALLS = 4;
+
+ static IntBand getAttrBand(MultiBand xxx_attr_bands, int which) {
+- IntBand b = (IntBand) xxx_attr_bands.get(which);
+- switch (which) {
+- case AB_FLAGS_HI:
+- assert(b.name().endsWith("_flags_hi")); break;
+- case AB_FLAGS_LO:
+- assert(b.name().endsWith("_flags_lo")); break;
+- case AB_ATTR_COUNT:
+- assert(b.name().endsWith("_attr_count")); break;
+- case AB_ATTR_INDEXES:
+- assert(b.name().endsWith("_attr_indexes")); break;
+- case AB_ATTR_CALLS:
+- assert(b.name().endsWith("_attr_calls")); break;
+- default:
+- assert(false); break;
+- }
+- return b;
++ IntBand b = (IntBand) xxx_attr_bands.get(which);
++ switch (which) {
++ case AB_FLAGS_HI:
++ assert(b.name().endsWith("_flags_hi")); break;
++ case AB_FLAGS_LO:
++ assert(b.name().endsWith("_flags_lo")); break;
++ case AB_ATTR_COUNT:
++ assert(b.name().endsWith("_attr_count")); break;
++ case AB_ATTR_INDEXES:
++ assert(b.name().endsWith("_attr_indexes")); break;
++ case AB_ATTR_CALLS:
++ assert(b.name().endsWith("_attr_calls")); break;
++ default:
++ assert(false); break;
++ }
++ return b;
+ }
+
+ static private final boolean NULL_IS_OK = true;
+@@ -1602,55 +1602,55 @@ class BandStructure implements Constants
+
+ /** Given CP indexes, distribute tag-specific indexes to bands. */
+ protected void setBandIndexes() {
+- // Handle prior calls to setBandIndex:
+- for (Iterator i = needPredefIndex.iterator(); i.hasNext(); ) {
+- Object[] need = (Object[]) i.next();
+- CPRefBand b = (CPRefBand) need[0];
+- Byte which = (Byte) need[1];
+- b.setIndex(getCPIndex(which.byteValue()));
+- }
+- needPredefIndex = null; // no more predefs
++ // Handle prior calls to setBandIndex:
++ for (Iterator i = needPredefIndex.iterator(); i.hasNext(); ) {
++ Object[] need = (Object[]) i.next();
++ CPRefBand b = (CPRefBand) need[0];
++ Byte which = (Byte) need[1];
++ b.setIndex(getCPIndex(which.byteValue()));
++ }
++ needPredefIndex = null; // no more predefs
+
+- if (verbose > 3) {
+- printCDecl(all_bands);
+- }
++ if (verbose > 3) {
++ printCDecl(all_bands);
++ }
+ }
+
+ protected void setBandIndex(CPRefBand b, byte which) {
+- Object[] need = { b, new Byte(which) };
+- if (which == CONSTANT_Literal) {
+- // I.e., attribute layouts KQ (no null) or KQN (null ok).
+- allKQBands.add(b);
+- } else if (needPredefIndex != null) {
+- needPredefIndex.add(need);
+- } else {
+- // Not in predefinition mode; getCPIndex now works.
+- b.setIndex(getCPIndex(which));
+- }
++ Object[] need = { b, new Byte(which) };
++ if (which == CONSTANT_Literal) {
++ // I.e., attribute layouts KQ (no null) or KQN (null ok).
++ allKQBands.add(b);
++ } else if (needPredefIndex != null) {
++ needPredefIndex.add(need);
++ } else {
++ // Not in predefinition mode; getCPIndex now works.
++ b.setIndex(getCPIndex(which));
++ }
+ }
+
+ protected void setConstantValueIndex(Class.Field f) {
+- Index ix = null;
+- if (f != null) {
+- byte tag = f.getLiteralTag();
+- ix = getCPIndex(tag);
+- if (verbose > 2)
+- Utils.log.fine("setConstantValueIndex "+f+" "+ConstantPool.tagName(tag)+" => "+ix);
+- assert(ix != null);
+- }
+- // Typically, allKQBands is the singleton of field_ConstantValue_KQ.
+- for (Iterator i = allKQBands.iterator(); i.hasNext(); ) {
+- CPRefBand xxx_KQ = (CPRefBand) i.next();
+- xxx_KQ.setIndex(ix);
+- }
++ Index ix = null;
++ if (f != null) {
++ byte tag = f.getLiteralTag();
++ ix = getCPIndex(tag);
++ if (verbose > 2)
++ Utils.log.fine("setConstantValueIndex "+f+" "+ConstantPool.tagName(tag)+" => "+ix);
++ assert(ix != null);
++ }
++ // Typically, allKQBands is the singleton of field_ConstantValue_KQ.
++ for (Iterator i = allKQBands.iterator(); i.hasNext(); ) {
++ CPRefBand xxx_KQ = (CPRefBand) i.next();
++ xxx_KQ.setIndex(ix);
++ }
+ }
+
+ // Table of bands which contain metadata.
+ protected MultiBand[] metadataBands = new MultiBand[ATTR_CONTEXT_LIMIT];
+ {
+- metadataBands[ATTR_CONTEXT_CLASS] = class_metadata_bands;
+- metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands;
+- metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands;
++ metadataBands[ATTR_CONTEXT_CLASS] = class_metadata_bands;
++ metadataBands[ATTR_CONTEXT_FIELD] = field_metadata_bands;
++ metadataBands[ATTR_CONTEXT_METHOD] = method_metadata_bands;
+ }
+
+ // Attribute layouts.
+@@ -1686,660 +1686,660 @@ class BandStructure implements Constants
+ // Mapping from attribute index (<32 are flag bits) to attributes.
+ protected ArrayList[] attrDefs = new ArrayList[ATTR_CONTEXT_LIMIT];
+ {
+- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
+- assert(attrIndexLimit[i] == 0);
+- attrIndexLimit[i] = 32; // just for the sake of predefs.
+- attrDefs[i] = new ArrayList(Collections.nCopies(attrIndexLimit[i], null));
+- }
++ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
++ assert(attrIndexLimit[i] == 0);
++ attrIndexLimit[i] = 32; // just for the sake of predefs.
++ attrDefs[i] = new ArrayList(Collections.nCopies(attrIndexLimit[i], null));
++ }
+
+- // Add predefined attribute definitions:
+- attrInnerClassesEmpty =
+- predefineAttribute(CLASS_ATTR_InnerClasses, ATTR_CONTEXT_CLASS, null,
+- "InnerClasses", "");
+- assert(attrInnerClassesEmpty == Package.attrInnerClassesEmpty);
+- predefineAttribute(CLASS_ATTR_SourceFile, ATTR_CONTEXT_CLASS,
+- new Band[] { class_SourceFile_RUN },
+- "SourceFile", "RUNH");
+- predefineAttribute(CLASS_ATTR_EnclosingMethod, ATTR_CONTEXT_CLASS,
+- new Band[] {
+- class_EnclosingMethod_RC,
+- class_EnclosingMethod_RDN
+- },
+- "EnclosingMethod", "RCHRDNH");
+- attrClassFileVersion =
+- predefineAttribute(CLASS_ATTR_ClassFile_version, ATTR_CONTEXT_CLASS,
+- new Band[] {
+- class_ClassFile_version_minor_H,
+- class_ClassFile_version_major_H
+- },
+- ".ClassFile.version", "HH");
+- predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_CLASS,
+- new Band[] { class_Signature_RS },
+- "Signature", "RSH");
+- predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_CLASS, null,
+- "Deprecated", "");
+- //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_CLASS, null,
+- // "Synthetic", "");
+- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CLASS, null,
+- ".Overflow", "");
+- attrConstantValue =
+- predefineAttribute(FIELD_ATTR_ConstantValue, ATTR_CONTEXT_FIELD,
+- new Band[] { field_ConstantValue_KQ },
+- "ConstantValue", "KQH");
+- predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_FIELD,
+- new Band[] { field_Signature_RS },
+- "Signature", "RSH");
+- predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_FIELD, null,
+- "Deprecated", "");
+- //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_FIELD, null,
+- // "Synthetic", "");
+- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_FIELD, null,
+- ".Overflow", "");
+- attrCodeEmpty =
+- predefineAttribute(METHOD_ATTR_Code, ATTR_CONTEXT_METHOD, null,
+- "Code", "");
+- predefineAttribute(METHOD_ATTR_Exceptions, ATTR_CONTEXT_METHOD,
+- new Band[] {
+- method_Exceptions_N,
+- method_Exceptions_RC
+- },
+- "Exceptions", "NH[RCH]");
+- assert(attrCodeEmpty == Package.attrCodeEmpty);
+- predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD,
+- new Band[] { method_Signature_RS },
+- "Signature", "RSH");
+- predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_METHOD, null,
+- "Deprecated", "");
+- //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_METHOD, null,
+- // "Synthetic", "");
+- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_METHOD, null,
+- ".Overflow", "");
++ // Add predefined attribute definitions:
++ attrInnerClassesEmpty =
++ predefineAttribute(CLASS_ATTR_InnerClasses, ATTR_CONTEXT_CLASS, null,
++ "InnerClasses", "");
++ assert(attrInnerClassesEmpty == Package.attrInnerClassesEmpty);
++ predefineAttribute(CLASS_ATTR_SourceFile, ATTR_CONTEXT_CLASS,
++ new Band[] { class_SourceFile_RUN },
++ "SourceFile", "RUNH");
++ predefineAttribute(CLASS_ATTR_EnclosingMethod, ATTR_CONTEXT_CLASS,
++ new Band[] {
++ class_EnclosingMethod_RC,
++ class_EnclosingMethod_RDN
++ },
++ "EnclosingMethod", "RCHRDNH");
++ attrClassFileVersion =
++ predefineAttribute(CLASS_ATTR_ClassFile_version, ATTR_CONTEXT_CLASS,
++ new Band[] {
++ class_ClassFile_version_minor_H,
++ class_ClassFile_version_major_H
++ },
++ ".ClassFile.version", "HH");
++ predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_CLASS,
++ new Band[] { class_Signature_RS },
++ "Signature", "RSH");
++ predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_CLASS, null,
++ "Deprecated", "");
++ //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_CLASS, null,
++ // "Synthetic", "");
++ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CLASS, null,
++ ".Overflow", "");
++ attrConstantValue =
++ predefineAttribute(FIELD_ATTR_ConstantValue, ATTR_CONTEXT_FIELD,
++ new Band[] { field_ConstantValue_KQ },
++ "ConstantValue", "KQH");
++ predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_FIELD,
++ new Band[] { field_Signature_RS },
++ "Signature", "RSH");
++ predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_FIELD, null,
++ "Deprecated", "");
++ //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_FIELD, null,
++ // "Synthetic", "");
++ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_FIELD, null,
++ ".Overflow", "");
++ attrCodeEmpty =
++ predefineAttribute(METHOD_ATTR_Code, ATTR_CONTEXT_METHOD, null,
++ "Code", "");
++ predefineAttribute(METHOD_ATTR_Exceptions, ATTR_CONTEXT_METHOD,
++ new Band[] {
++ method_Exceptions_N,
++ method_Exceptions_RC
++ },
++ "Exceptions", "NH[RCH]");
++ assert(attrCodeEmpty == Package.attrCodeEmpty);
++ predefineAttribute(X_ATTR_Signature, ATTR_CONTEXT_METHOD,
++ new Band[] { method_Signature_RS },
++ "Signature", "RSH");
++ predefineAttribute(X_ATTR_Deprecated, ATTR_CONTEXT_METHOD, null,
++ "Deprecated", "");
++ //predefineAttribute(X_ATTR_Synthetic, ATTR_CONTEXT_METHOD, null,
++ // "Synthetic", "");
++ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_METHOD, null,
++ ".Overflow", "");
+
+- for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
+- MultiBand xxx_metadata_bands = metadataBands[ctype];
+- if (xxx_metadata_bands == null)
+- continue; // no code attrs
++ for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
++ MultiBand xxx_metadata_bands = metadataBands[ctype];
++ if (xxx_metadata_bands == null)
++ continue; // no code attrs
+
+- // These arguments cause the bands to be built
+- // automatically for this complicated layout:
+- predefineAttribute(X_ATTR_RuntimeVisibleAnnotations,
+- ATTR_CONTEXT_NAME[ctype]+"_RVA_",
+- xxx_metadata_bands,
+- Attribute.lookup(null, ctype,
+- "RuntimeVisibleAnnotations"));
+- predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations,
+- ATTR_CONTEXT_NAME[ctype]+"_RIA_",
+- xxx_metadata_bands,
+- Attribute.lookup(null, ctype,
+- "RuntimeInvisibleAnnotations"));
+- if (ctype != ATTR_CONTEXT_METHOD)
+- continue;
++ // These arguments cause the bands to be built
++ // automatically for this complicated layout:
++ predefineAttribute(X_ATTR_RuntimeVisibleAnnotations,
++ ATTR_CONTEXT_NAME[ctype]+"_RVA_",
++ xxx_metadata_bands,
++ Attribute.lookup(null, ctype,
++ "RuntimeVisibleAnnotations"));
++ predefineAttribute(X_ATTR_RuntimeInvisibleAnnotations,
++ ATTR_CONTEXT_NAME[ctype]+"_RIA_",
++ xxx_metadata_bands,
++ Attribute.lookup(null, ctype,
++ "RuntimeInvisibleAnnotations"));
++ if (ctype != ATTR_CONTEXT_METHOD)
++ continue;
+
+- predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
+- "method_RVPA_", xxx_metadata_bands,
+- Attribute.lookup(null, ctype,
+- "RuntimeVisibleParameterAnnotations"));
+- predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
+- "method_RIPA_", xxx_metadata_bands,
+- Attribute.lookup(null, ctype,
+- "RuntimeInvisibleParameterAnnotations"));
+- predefineAttribute(METHOD_ATTR_AnnotationDefault,
+- "method_AD_", xxx_metadata_bands,
+- Attribute.lookup(null, ctype,
+- "AnnotationDefault"));
+- }
++ predefineAttribute(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
++ "method_RVPA_", xxx_metadata_bands,
++ Attribute.lookup(null, ctype,
++ "RuntimeVisibleParameterAnnotations"));
++ predefineAttribute(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
++ "method_RIPA_", xxx_metadata_bands,
++ Attribute.lookup(null, ctype,
++ "RuntimeInvisibleParameterAnnotations"));
++ predefineAttribute(METHOD_ATTR_AnnotationDefault,
++ "method_AD_", xxx_metadata_bands,
++ Attribute.lookup(null, ctype,
++ "AnnotationDefault"));
++ }
+
+
+- Attribute.Layout stackMapDef = Attribute.lookup(null, ATTR_CONTEXT_CODE, "StackMapTable").layout();
+- predefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE,
+- stackmap_bands.toArray(),
+- stackMapDef.name(), stackMapDef.layout());
++ Attribute.Layout stackMapDef = Attribute.lookup(null, ATTR_CONTEXT_CODE, "StackMapTable").layout();
++ predefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE,
++ stackmap_bands.toArray(),
++ stackMapDef.name(), stackMapDef.layout());
+
+- predefineAttribute(CODE_ATTR_LineNumberTable, ATTR_CONTEXT_CODE,
+- new Band[] {
+- code_LineNumberTable_N,
+- code_LineNumberTable_bci_P,
+- code_LineNumberTable_line
+- },
+- "LineNumberTable", "NH[PHH]");
+- predefineAttribute(CODE_ATTR_LocalVariableTable, ATTR_CONTEXT_CODE,
+- new Band[] {
+- code_LocalVariableTable_N,
+- code_LocalVariableTable_bci_P,
+- code_LocalVariableTable_span_O,
+- code_LocalVariableTable_name_RU,
+- code_LocalVariableTable_type_RS,
+- code_LocalVariableTable_slot
+- },
+- "LocalVariableTable", "NH[PHOHRUHRSHH]");
+- predefineAttribute(CODE_ATTR_LocalVariableTypeTable, ATTR_CONTEXT_CODE,
+- new Band[] {
+- code_LocalVariableTypeTable_N,
+- code_LocalVariableTypeTable_bci_P,
+- code_LocalVariableTypeTable_span_O,
+- code_LocalVariableTypeTable_name_RU,
+- code_LocalVariableTypeTable_type_RS,
+- code_LocalVariableTypeTable_slot
+- },
+- "LocalVariableTypeTable", "NH[PHOHRUHRSHH]");
+- predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CODE, null,
+- ".Overflow", "");
++ predefineAttribute(CODE_ATTR_LineNumberTable, ATTR_CONTEXT_CODE,
++ new Band[] {
++ code_LineNumberTable_N,
++ code_LineNumberTable_bci_P,
++ code_LineNumberTable_line
++ },
++ "LineNumberTable", "NH[PHH]");
++ predefineAttribute(CODE_ATTR_LocalVariableTable, ATTR_CONTEXT_CODE,
++ new Band[] {
++ code_LocalVariableTable_N,
++ code_LocalVariableTable_bci_P,
++ code_LocalVariableTable_span_O,
++ code_LocalVariableTable_name_RU,
++ code_LocalVariableTable_type_RS,
++ code_LocalVariableTable_slot
++ },
++ "LocalVariableTable", "NH[PHOHRUHRSHH]");
++ predefineAttribute(CODE_ATTR_LocalVariableTypeTable, ATTR_CONTEXT_CODE,
++ new Band[] {
++ code_LocalVariableTypeTable_N,
++ code_LocalVariableTypeTable_bci_P,
++ code_LocalVariableTypeTable_span_O,
++ code_LocalVariableTypeTable_name_RU,
++ code_LocalVariableTypeTable_type_RS,
++ code_LocalVariableTypeTable_slot
++ },
++ "LocalVariableTypeTable", "NH[PHOHRUHRSHH]");
++ predefineAttribute(X_ATTR_OVERFLOW, ATTR_CONTEXT_CODE, null,
++ ".Overflow", "");
+
+- // Clear the record of having seen these definitions,
+- // so they may be redefined without error.
+- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
+- attrDefSeen[i] = 0;
+- }
++ // Clear the record of having seen these definitions,
++ // so they may be redefined without error.
++ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
++ attrDefSeen[i] = 0;
++ }
+
+- // Set up the special masks:
+- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
+- attrOverflowMask[i] = (1<<X_ATTR_OVERFLOW);
+- attrIndexLimit[i] = 0; // will make a final decision later
+- }
+- attrClassFileVersionMask = (1<<CLASS_ATTR_ClassFile_version);
++ // Set up the special masks:
++ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
++ attrOverflowMask[i] = (1<<X_ATTR_OVERFLOW);
++ attrIndexLimit[i] = 0; // will make a final decision later
++ }
++ attrClassFileVersionMask = (1<<CLASS_ATTR_ClassFile_version);
+ }
+
+ private void adjustToMajver() {
+- if (getPackageMajver() < JAVA6_PACKAGE_MAJOR_VERSION) {
+- if (verbose > 0) Utils.log.fine("Legacy package version");
+- // Revoke definition of pre-1.6 attribute type.
+- undefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE);
+- }
++ if (getPackageMajver() < JAVA6_PACKAGE_MAJOR_VERSION) {
++ if (verbose > 0) Utils.log.fine("Legacy package version");
++ // Revoke definition of pre-1.6 attribute type.
++ undefineAttribute(CODE_ATTR_StackMapTable, ATTR_CONTEXT_CODE);
++ }
+ }
+
+ protected void initAttrIndexLimit() {
+- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
+- assert(attrIndexLimit[i] == 0); // decide on it now!
+- attrIndexLimit[i] = (haveFlagsHi(i)? 63: 32);
+- assert(attrDefs[i].size() == 32); // all predef indexes are <32
+- int addMore = attrIndexLimit[i] - attrDefs[i].size();
+- attrDefs[i].addAll(Collections.nCopies(addMore, null));
+- }
++ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
++ assert(attrIndexLimit[i] == 0); // decide on it now!
++ attrIndexLimit[i] = (haveFlagsHi(i)? 63: 32);
++ assert(attrDefs[i].size() == 32); // all predef indexes are <32
++ int addMore = attrIndexLimit[i] - attrDefs[i].size();
++ attrDefs[i].addAll(Collections.nCopies(addMore, null));
++ }
+ }
+
+ protected boolean haveFlagsHi(int ctype) {
+- int mask = 1<<(LG_AO_HAVE_XXX_FLAGS_HI+ctype);
+- switch (ctype) {
+- case ATTR_CONTEXT_CLASS:
+- assert(mask == AO_HAVE_CLASS_FLAGS_HI); break;
+- case ATTR_CONTEXT_FIELD:
+- assert(mask == AO_HAVE_FIELD_FLAGS_HI); break;
+- case ATTR_CONTEXT_METHOD:
+- assert(mask == AO_HAVE_METHOD_FLAGS_HI); break;
+- case ATTR_CONTEXT_CODE:
+- assert(mask == AO_HAVE_CODE_FLAGS_HI); break;
+- default:
+- assert(false);
+- }
+- return testBit(archiveOptions, mask);
++ int mask = 1<<(LG_AO_HAVE_XXX_FLAGS_HI+ctype);
++ switch (ctype) {
++ case ATTR_CONTEXT_CLASS:
++ assert(mask == AO_HAVE_CLASS_FLAGS_HI); break;
++ case ATTR_CONTEXT_FIELD:
++ assert(mask == AO_HAVE_FIELD_FLAGS_HI); break;
++ case ATTR_CONTEXT_METHOD:
++ assert(mask == AO_HAVE_METHOD_FLAGS_HI); break;
++ case ATTR_CONTEXT_CODE:
++ assert(mask == AO_HAVE_CODE_FLAGS_HI); break;
++ default:
++ assert(false);
++ }
++ return testBit(archiveOptions, mask);
+ }
+
+ protected ArrayList getPredefinedAttrs(int ctype) {
+- assert(attrIndexLimit[ctype] != 0);
+- ArrayList res = new ArrayList(attrIndexLimit[ctype]);
+- // Remove nulls and non-predefs.
+- for (int ai = 0; ai < attrIndexLimit[ctype]; ai++) {
+- if (testBit(attrDefSeen[ctype], 1L<<ai)) continue;
+- Attribute.Layout def = (Attribute.Layout) attrDefs[ctype].get(ai);
+- if (def == null) continue; // unused flag bit
+- assert(isPredefinedAttr(ctype, ai));
+- res.add(def);
+- }
+- return res;
++ assert(attrIndexLimit[ctype] != 0);
++ ArrayList res = new ArrayList(attrIndexLimit[ctype]);
++ // Remove nulls and non-predefs.
++ for (int ai = 0; ai < attrIndexLimit[ctype]; ai++) {
++ if (testBit(attrDefSeen[ctype], 1L<<ai)) continue;
++ Attribute.Layout def = (Attribute.Layout) attrDefs[ctype].get(ai);
++ if (def == null) continue; // unused flag bit
++ assert(isPredefinedAttr(ctype, ai));
++ res.add(def);
++ }
++ return res;
+ }
+
+ protected boolean isPredefinedAttr(int ctype, int ai) {
+- assert(attrIndexLimit[ctype] != 0);
+- // Overflow attrs are never predefined.
+- if (ai >= attrIndexLimit[ctype]) return false;
+- // If the bit is set, it was explicitly def'd.
+- if (testBit(attrDefSeen[ctype], 1L<<ai)) return false;
+- return (attrDefs[ctype].get(ai) != null);
++ assert(attrIndexLimit[ctype] != 0);
++ // Overflow attrs are never predefined.
++ if (ai >= attrIndexLimit[ctype]) return false;
++ // If the bit is set, it was explicitly def'd.
++ if (testBit(attrDefSeen[ctype], 1L<<ai)) return false;
++ return (attrDefs[ctype].get(ai) != null);
+ }
+
+ protected void adjustSpecialAttrMasks() {
+- // Clear special masks if new definitions have been seen for them.
+- attrClassFileVersionMask &= ~ attrDefSeen[ATTR_CONTEXT_CLASS];
+- // It is possible to clear the overflow mask (bit 16).
+- for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
+- attrOverflowMask[i] &= ~ attrDefSeen[i];
+- }
++ // Clear special masks if new definitions have been seen for them.
++ attrClassFileVersionMask &= ~ attrDefSeen[ATTR_CONTEXT_CLASS];
++ // It is possible to clear the overflow mask (bit 16).
++ for (int i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
++ attrOverflowMask[i] &= ~ attrDefSeen[i];
++ }
+ }
+
+ protected Attribute makeClassFileVersionAttr(int minver, int majver) {
+- byte[] bytes = {
+- (byte)(minver >> 8), (byte)minver,
+- (byte)(majver >> 8), (byte)majver
+- };
+- return attrClassFileVersion.addContent(bytes);
++ byte[] bytes = {
++ (byte)(minver >> 8), (byte)minver,
++ (byte)(majver >> 8), (byte)majver
++ };
++ return attrClassFileVersion.addContent(bytes);
+ }
+
+ protected short[] parseClassFileVersionAttr(Attribute attr) {
+- assert(attr.layout() == attrClassFileVersion);
+- assert(attr.size() == 4);
+- byte[] bytes = attr.bytes();
+- int minver = ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF);
+- int majver = ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF);
+- return new short[]{ (short) minver, (short) majver };
++ assert(attr.layout() == attrClassFileVersion);
++ assert(attr.size() == 4);
++ byte[] bytes = attr.bytes();
++ int minver = ((bytes[0] & 0xFF) << 8) | (bytes[1] & 0xFF);
++ int majver = ((bytes[2] & 0xFF) << 8) | (bytes[3] & 0xFF);
++ return new short[]{ (short) minver, (short) majver };
+ }
+
+ private boolean assertBandOKForElems(Band[] ab, Attribute.Layout.Element[] elems) {
+- for (int i = 0; i < elems.length; i++) {
+- assert(assertBandOKForElem(ab, elems[i]));
+- }
+- return true;
++ for (int i = 0; i < elems.length; i++) {
++ assert(assertBandOKForElem(ab, elems[i]));
++ }
++ return true;
+ }
+ private boolean assertBandOKForElem(Band[] ab, Attribute.Layout.Element e) {
+- Band b = null;
+- if (e.bandIndex != Attribute.NO_BAND_INDEX)
+- b = ab[e.bandIndex];
+- Coding rc = UNSIGNED5;
+- boolean wantIntBand = true;
+- switch (e.kind) {
+- case Attribute.EK_INT:
+- if (e.flagTest(Attribute.EF_SIGN)) {
+- rc = SIGNED5;
+- } else if (e.len == 1) {
+- rc = BYTE1;
+- }
+- break;
+- case Attribute.EK_BCI:
+- if (!e.flagTest(Attribute.EF_DELTA)) {
+- rc = BCI5;
+- } else {
+- rc = BRANCH5;
+- }
+- break;
+- case Attribute.EK_BCO:
+- rc = BRANCH5;
+- break;
+- case Attribute.EK_FLAG:
+- if (e.len == 1) rc = BYTE1;
+- break;
+- case Attribute.EK_REPL:
+- if (e.len == 1) rc = BYTE1;
+- assertBandOKForElems(ab, e.body);
+- break;
+- case Attribute.EK_UN:
+- if (e.flagTest(Attribute.EF_SIGN)) {
+- rc = SIGNED5;
+- } else if (e.len == 1) {
+- rc = BYTE1;
+- }
+- assertBandOKForElems(ab, e.body);
+- break;
+- case Attribute.EK_CASE:
+- assert(b == null);
+- assertBandOKForElems(ab, e.body);
+- return true; // no direct band
+- case Attribute.EK_CALL:
+- assert(b == null);
+- return true; // no direct band
+- case Attribute.EK_CBLE:
+- assert(b == null);
+- assertBandOKForElems(ab, e.body);
+- return true; // no direct band
+- case Attribute.EK_REF:
+- wantIntBand = false;
+- assert(b instanceof CPRefBand);
+- assert(((CPRefBand)b).nullOK == e.flagTest(Attribute.EF_NULL));
+- break;
+- default: assert(false);
+- }
+- assert(b.regularCoding == rc)
+- : (e+" // "+b);
+- if (wantIntBand)
+- assert(b instanceof IntBand);
+- return true;
++ Band b = null;
++ if (e.bandIndex != Attribute.NO_BAND_INDEX)
++ b = ab[e.bandIndex];
++ Coding rc = UNSIGNED5;
++ boolean wantIntBand = true;
++ switch (e.kind) {
++ case Attribute.EK_INT:
++ if (e.flagTest(Attribute.EF_SIGN)) {
++ rc = SIGNED5;
++ } else if (e.len == 1) {
++ rc = BYTE1;
++ }
++ break;
++ case Attribute.EK_BCI:
++ if (!e.flagTest(Attribute.EF_DELTA)) {
++ rc = BCI5;
++ } else {
++ rc = BRANCH5;
++ }
++ break;
++ case Attribute.EK_BCO:
++ rc = BRANCH5;
++ break;
++ case Attribute.EK_FLAG:
++ if (e.len == 1) rc = BYTE1;
++ break;
++ case Attribute.EK_REPL:
++ if (e.len == 1) rc = BYTE1;
++ assertBandOKForElems(ab, e.body);
++ break;
++ case Attribute.EK_UN:
++ if (e.flagTest(Attribute.EF_SIGN)) {
++ rc = SIGNED5;
++ } else if (e.len == 1) {
++ rc = BYTE1;
++ }
++ assertBandOKForElems(ab, e.body);
++ break;
++ case Attribute.EK_CASE:
++ assert(b == null);
++ assertBandOKForElems(ab, e.body);
++ return true; // no direct band
++ case Attribute.EK_CALL:
++ assert(b == null);
++ return true; // no direct band
++ case Attribute.EK_CBLE:
++ assert(b == null);
++ assertBandOKForElems(ab, e.body);
++ return true; // no direct band
++ case Attribute.EK_REF:
++ wantIntBand = false;
++ assert(b instanceof CPRefBand);
++ assert(((CPRefBand)b).nullOK == e.flagTest(Attribute.EF_NULL));
++ break;
++ default: assert(false);
++ }
++ assert(b.regularCoding == rc)
++ : (e+" // "+b);
++ if (wantIntBand)
++ assert(b instanceof IntBand);
++ return true;
+ }
+
+ private
+ Attribute.Layout predefineAttribute(int index, int ctype, Band[] ab,
+- String name, String layout) {
+- // Use Attribute.find to get uniquification of layouts.
+- Attribute.Layout def = Attribute.find(ctype, name, layout).layout();
+- //def.predef = true;
+- if (index >= 0) {
+- setAttributeLayoutIndex(def, index);
+- }
+- if (ab == null) {
+- ab = new Band[0];
+- }
+- assert(attrBandTable.get(def) == null); // no redef
+- attrBandTable.put(def, ab);
+- assert(def.bandCount == ab.length)
+- : (def+" // "+Arrays.asList(ab));
+- // Let's make sure the band types match:
+- assert(assertBandOKForElems(ab, def.elems));
+- return def;
++ String name, String layout) {
++ // Use Attribute.find to get uniquification of layouts.
++ Attribute.Layout def = Attribute.find(ctype, name, layout).layout();
++ //def.predef = true;
++ if (index >= 0) {
++ setAttributeLayoutIndex(def, index);
++ }
++ if (ab == null) {
++ ab = new Band[0];
++ }
++ assert(attrBandTable.get(def) == null); // no redef
++ attrBandTable.put(def, ab);
++ assert(def.bandCount == ab.length)
++ : (def+" // "+Arrays.asList(ab));
++ // Let's make sure the band types match:
++ assert(assertBandOKForElems(ab, def.elems));
++ return def;
+ }
+
+ // This version takes bandPrefix/addHere instead of prebuilt Band[] ab.
+ private
+ Attribute.Layout predefineAttribute(int index,
+- String bandPrefix, MultiBand addHere,
+- Attribute attr) {
+- //Attribute.Layout def = Attribute.find(ctype, name, layout).layout();
+- Attribute.Layout def = attr.layout();
+- int ctype = def.ctype();
+- return predefineAttribute(index, ctype,
+- makeNewAttributeBands(bandPrefix, def,
+- addHere),
+- def.name(), def.layout());
++ String bandPrefix, MultiBand addHere,
++ Attribute attr) {
++ //Attribute.Layout def = Attribute.find(ctype, name, layout).layout();
++ Attribute.Layout def = attr.layout();
++ int ctype = def.ctype();
++ return predefineAttribute(index, ctype,
++ makeNewAttributeBands(bandPrefix, def,
++ addHere),
++ def.name(), def.layout());
+ }
+
+ private
+ void undefineAttribute(int index, int ctype) {
+- if (verbose > 1) {
+- System.out.println("Removing predefined "+ATTR_CONTEXT_NAME[ctype]+
+- " attribute on bit "+index);
+- }
+- List defList = attrDefs[ctype];
+- Attribute.Layout def = (Attribute.Layout) defList.get(index);
+- assert(def != null);
+- defList.set(index, null);
+- attrIndexTable.put(def, null);
+- // Clear the def bit. (For predefs, it's already clear.)
+- assert(index < 64);
+- attrDefSeen[ctype] &= ~(1L<<index);
+- attrFlagMask[ctype] &= ~(1L<<index);
+- Band[] ab = (Band[]) attrBandTable.get(def);
+- for (int j = 0; j < ab.length; j++) {
+- ab[j].doneWithUnusedBand();
+- }
++ if (verbose > 1) {
++ System.out.println("Removing predefined "+ATTR_CONTEXT_NAME[ctype]+
++ " attribute on bit "+index);
++ }
++ List defList = attrDefs[ctype];
++ Attribute.Layout def = (Attribute.Layout) defList.get(index);
++ assert(def != null);
++ defList.set(index, null);
++ attrIndexTable.put(def, null);
++ // Clear the def bit. (For predefs, it's already clear.)
++ assert(index < 64);
++ attrDefSeen[ctype] &= ~(1L<<index);
++ attrFlagMask[ctype] &= ~(1L<<index);
++ Band[] ab = (Band[]) attrBandTable.get(def);
++ for (int j = 0; j < ab.length; j++) {
++ ab[j].doneWithUnusedBand();
++ }
+ }
+
+ // Bands which contain non-predefined attrs.
+ protected MultiBand[] attrBands = new MultiBand[ATTR_CONTEXT_LIMIT];
+ {
+- attrBands[ATTR_CONTEXT_CLASS] = class_attr_bands;
+- attrBands[ATTR_CONTEXT_FIELD] = field_attr_bands;
+- attrBands[ATTR_CONTEXT_METHOD] = method_attr_bands;
+- attrBands[ATTR_CONTEXT_CODE] = code_attr_bands;
++ attrBands[ATTR_CONTEXT_CLASS] = class_attr_bands;
++ attrBands[ATTR_CONTEXT_FIELD] = field_attr_bands;
++ attrBands[ATTR_CONTEXT_METHOD] = method_attr_bands;
++ attrBands[ATTR_CONTEXT_CODE] = code_attr_bands;
+ }
+
+ // Create bands for all non-predefined attrs.
+ void makeNewAttributeBands() {
+- // Retract special flag bit bindings, if they were taken over.
+- adjustSpecialAttrMasks();
++ // Retract special flag bit bindings, if they were taken over.
++ adjustSpecialAttrMasks();
+
+- for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
+- String cname = ATTR_CONTEXT_NAME[ctype];
+- MultiBand xxx_attr_bands = attrBands[ctype];
+- long defSeen = attrDefSeen[ctype];
+- // Note: attrDefSeen is always a subset of attrFlagMask.
+- assert((defSeen & ~attrFlagMask[ctype]) == 0);
+- for (int i = 0; i < attrDefs[ctype].size(); i++) {
+- Attribute.Layout def = (Attribute.Layout)
+- attrDefs[ctype].get(i);
+- if (def == null) continue; // unused flag bit
+- if (def.bandCount == 0) continue; // empty attr
+- if (i < attrIndexLimit[ctype] && !testBit(defSeen, 1L<<i)) {
+- // There are already predefined bands here.
+- assert(attrBandTable.get(def) != null);
+- continue;
+- }
+- int base = xxx_attr_bands.size();
+- String pfx = cname+"_"+def.name()+"_"; // debug only
+- if (verbose > 1)
+- Utils.log.fine("Making new bands for "+def);
+- Band[] newAB = makeNewAttributeBands(pfx, def,
+- xxx_attr_bands);
+- assert(newAB.length == def.bandCount);
+- Band[] prevAB = (Band[]) attrBandTable.put(def, newAB);
+- if (prevAB != null) {
+- // We won't be using these predefined bands.
+- for (int j = 0; j < prevAB.length; j++) {
+- prevAB[j].doneWithUnusedBand();
+- }
+- }
+- }
+- }
+- //System.out.println(prevForAssertMap);
++ for (int ctype = 0; ctype < ATTR_CONTEXT_LIMIT; ctype++) {
++ String cname = ATTR_CONTEXT_NAME[ctype];
++ MultiBand xxx_attr_bands = attrBands[ctype];
++ long defSeen = attrDefSeen[ctype];
++ // Note: attrDefSeen is always a subset of attrFlagMask.
++ assert((defSeen & ~attrFlagMask[ctype]) == 0);
++ for (int i = 0; i < attrDefs[ctype].size(); i++) {
++ Attribute.Layout def = (Attribute.Layout)
++ attrDefs[ctype].get(i);
++ if (def == null) continue; // unused flag bit
++ if (def.bandCount == 0) continue; // empty attr
++ if (i < attrIndexLimit[ctype] && !testBit(defSeen, 1L<<i)) {
++ // There are already predefined bands here.
++ assert(attrBandTable.get(def) != null);
++ continue;
++ }
++ int base = xxx_attr_bands.size();
++ String pfx = cname+"_"+def.name()+"_"; // debug only
++ if (verbose > 1)
++ Utils.log.fine("Making new bands for "+def);
++ Band[] newAB = makeNewAttributeBands(pfx, def,
++ xxx_attr_bands);
++ assert(newAB.length == def.bandCount);
++ Band[] prevAB = (Band[]) attrBandTable.put(def, newAB);
++ if (prevAB != null) {
++ // We won't be using these predefined bands.
++ for (int j = 0; j < prevAB.length; j++) {
++ prevAB[j].doneWithUnusedBand();
++ }
++ }
++ }
++ }
++ //System.out.println(prevForAssertMap);
+ }
+ private
+ Band[] makeNewAttributeBands(String pfx, Attribute.Layout def,
+- MultiBand addHere) {
+- int base = addHere.size();
+- makeNewAttributeBands(pfx, def.elems, addHere);
+- int nb = addHere.size() - base;
+- Band[] newAB = new Band[nb];
+- for (int i = 0; i < nb; i++) {
+- newAB[i] = addHere.get(base+i);
+- }
+- return newAB;
++ MultiBand addHere) {
++ int base = addHere.size();
++ makeNewAttributeBands(pfx, def.elems, addHere);
++ int nb = addHere.size() - base;
++ Band[] newAB = new Band[nb];
++ for (int i = 0; i < nb; i++) {
++ newAB[i] = addHere.get(base+i);
++ }
++ return newAB;
+ }
+ // Recursive helper, operates on a "body" or other sequence of elems:
+ private
+ void makeNewAttributeBands(String pfx, Attribute.Layout.Element[] elems,
+- MultiBand ab) {
+- for (int i = 0; i < elems.length; i++) {
+- Attribute.Layout.Element e = elems[i];
+- String name = pfx+ab.size()+"_"+e.layout;
+- {
+- int tem;
+- if ((tem = name.indexOf('[')) > 0)
+- name = name.substring(0, tem);
+- if ((tem = name.indexOf('(')) > 0)
+- name = name.substring(0, tem);
+- if (name.endsWith("H"))
+- name = name.substring(0, name.length()-1);
+- }
+- Band nb;
+- switch (e.kind) {
+- case Attribute.EK_INT:
+- nb = newElemBand(e, name, ab);
+- break;
+- case Attribute.EK_BCI:
+- if (!e.flagTest(Attribute.EF_DELTA)) {
+- // PH: transmit R(bci), store bci
+- nb = ab.newIntBand(name, BCI5);
+- } else {
+- // POH: transmit D(R(bci)), store bci
+- nb = ab.newIntBand(name, BRANCH5);
+- }
+- // Note: No case for BYTE1 here.
+- break;
+- case Attribute.EK_BCO:
+- // OH: transmit D(R(bci)), store D(bci)
+- nb = ab.newIntBand(name, BRANCH5);
+- // Note: No case for BYTE1 here.
+- break;
+- case Attribute.EK_FLAG:
+- assert(!e.flagTest(Attribute.EF_SIGN));
+- nb = newElemBand(e, name, ab);
+- break;
+- case Attribute.EK_REPL:
+- assert(!e.flagTest(Attribute.EF_SIGN));
+- nb = newElemBand(e, name, ab);
+- makeNewAttributeBands(pfx, e.body, ab);
+- break;
+- case Attribute.EK_UN:
+- nb = newElemBand(e, name, ab);
+- makeNewAttributeBands(pfx, e.body, ab);
+- break;
+- case Attribute.EK_CASE:
+- if (!e.flagTest(Attribute.EF_BACK)) {
+- // If it's not a duplicate body, make the bands.
+- makeNewAttributeBands(pfx, e.body, ab);
+- }
+- continue; // no new band to make
+- case Attribute.EK_REF:
+- byte refKind = e.refKind;
+- boolean nullOK = e.flagTest(Attribute.EF_NULL);
+- nb = ab.newCPRefBand(name, UNSIGNED5, refKind, nullOK);
+- // Note: No case for BYTE1 here.
+- break;
+- case Attribute.EK_CALL:
+- continue; // no new band to make
+- case Attribute.EK_CBLE:
+- makeNewAttributeBands(pfx, e.body, ab);
+- continue; // no new band to make
+- default: assert(false); continue;
+- }
+- if (verbose > 1) {
+- Utils.log.fine("New attribute band "+nb);
+- }
+- }
++ MultiBand ab) {
++ for (int i = 0; i < elems.length; i++) {
++ Attribute.Layout.Element e = elems[i];
++ String name = pfx+ab.size()+"_"+e.layout;
++ {
++ int tem;
++ if ((tem = name.indexOf('[')) > 0)
++ name = name.substring(0, tem);
++ if ((tem = name.indexOf('(')) > 0)
++ name = name.substring(0, tem);
++ if (name.endsWith("H"))
++ name = name.substring(0, name.length()-1);
++ }
++ Band nb;
++ switch (e.kind) {
++ case Attribute.EK_INT:
++ nb = newElemBand(e, name, ab);
++ break;
++ case Attribute.EK_BCI:
++ if (!e.flagTest(Attribute.EF_DELTA)) {
++ // PH: transmit R(bci), store bci
++ nb = ab.newIntBand(name, BCI5);
++ } else {
++ // POH: transmit D(R(bci)), store bci
++ nb = ab.newIntBand(name, BRANCH5);
++ }
++ // Note: No case for BYTE1 here.
++ break;
++ case Attribute.EK_BCO:
++ // OH: transmit D(R(bci)), store D(bci)
++ nb = ab.newIntBand(name, BRANCH5);
++ // Note: No case for BYTE1 here.
++ break;
++ case Attribute.EK_FLAG:
++ assert(!e.flagTest(Attribute.EF_SIGN));
++ nb = newElemBand(e, name, ab);
++ break;
++ case Attribute.EK_REPL:
++ assert(!e.flagTest(Attribute.EF_SIGN));
++ nb = newElemBand(e, name, ab);
++ makeNewAttributeBands(pfx, e.body, ab);
++ break;
++ case Attribute.EK_UN:
++ nb = newElemBand(e, name, ab);
++ makeNewAttributeBands(pfx, e.body, ab);
++ break;
++ case Attribute.EK_CASE:
++ if (!e.flagTest(Attribute.EF_BACK)) {
++ // If it's not a duplicate body, make the bands.
++ makeNewAttributeBands(pfx, e.body, ab);
++ }
++ continue; // no new band to make
++ case Attribute.EK_REF:
++ byte refKind = e.refKind;
++ boolean nullOK = e.flagTest(Attribute.EF_NULL);
++ nb = ab.newCPRefBand(name, UNSIGNED5, refKind, nullOK);
++ // Note: No case for BYTE1 here.
++ break;
++ case Attribute.EK_CALL:
++ continue; // no new band to make
++ case Attribute.EK_CBLE:
++ makeNewAttributeBands(pfx, e.body, ab);
++ continue; // no new band to make
++ default: assert(false); continue;
++ }
++ if (verbose > 1) {
++ Utils.log.fine("New attribute band "+nb);
++ }
++ }
+ }
+ private
+ Band newElemBand(Attribute.Layout.Element e, String name, MultiBand ab) {
+- if (e.flagTest(Attribute.EF_SIGN)) {
+- return ab.newIntBand(name, SIGNED5);
+- } else if (e.len == 1) {
+- return ab.newIntBand(name, BYTE1); // Not ByteBand, please.
+- } else {
+- return ab.newIntBand(name, UNSIGNED5);
+- }
++ if (e.flagTest(Attribute.EF_SIGN)) {
++ return ab.newIntBand(name, SIGNED5);
++ } else if (e.len == 1) {
++ return ab.newIntBand(name, BYTE1); // Not ByteBand, please.
++ } else {
++ return ab.newIntBand(name, UNSIGNED5);
++ }
+ }
+
+ protected int setAttributeLayoutIndex(Attribute.Layout def, int index) {
+- int ctype = def.ctype;
+- assert(ATTR_INDEX_OVERFLOW <= index && index < attrIndexLimit[ctype]);
+- List defList = attrDefs[ctype];
+- if (index == ATTR_INDEX_OVERFLOW) {
+- // Overflow attribute.
+- index = defList.size();
+- defList.add(def);
+- if (verbose > 0)
+- Utils.log.info("Adding new attribute at "+def +": "+index);
+- attrIndexTable.put(def, new Integer(index));
+- return index;
+- }
++ int ctype = def.ctype;
++ assert(ATTR_INDEX_OVERFLOW <= index && index < attrIndexLimit[ctype]);
++ List defList = attrDefs[ctype];
++ if (index == ATTR_INDEX_OVERFLOW) {
++ // Overflow attribute.
++ index = defList.size();
++ defList.add(def);
++ if (verbose > 0)
++ Utils.log.info("Adding new attribute at "+def +": "+index);
++ attrIndexTable.put(def, new Integer(index));
++ return index;
++ }
+
+- // Detect redefinitions:
+- if (testBit(attrDefSeen[ctype], 1L<<index)) {
+- throw new RuntimeException("Multiple explicit definition at "+index+": "+def);
+- }
+- attrDefSeen[ctype] |= (1L<<index);
++ // Detect redefinitions:
++ if (testBit(attrDefSeen[ctype], 1L<<index)) {
++ throw new RuntimeException("Multiple explicit definition at "+index+": "+def);
++ }
++ attrDefSeen[ctype] |= (1L<<index);
+
+- // Adding a new fixed attribute.
+- assert(0 <= index && index < attrIndexLimit[ctype]);
+- if (verbose > (attrClassFileVersionMask == 0? 2:0))
+- Utils.log.fine("Fixing new attribute at "+index
+- +": "+def
+- +(defList.get(index) == null? "":
+- "; replacing "+defList.get(index)));
+- attrFlagMask[ctype] |= (1L<<index);
+- // Remove index binding of any previous fixed attr.
+- attrIndexTable.put(defList.get(index), null);
+- defList.set(index, def);
+- attrIndexTable.put(def, new Integer(index));
+- return index;
++ // Adding a new fixed attribute.
++ assert(0 <= index && index < attrIndexLimit[ctype]);
++ if (verbose > (attrClassFileVersionMask == 0? 2:0))
++ Utils.log.fine("Fixing new attribute at "+index
++ +": "+def
++ +(defList.get(index) == null? "":
++ "; replacing "+defList.get(index)));
++ attrFlagMask[ctype] |= (1L<<index);
++ // Remove index binding of any previous fixed attr.
++ attrIndexTable.put(defList.get(index), null);
++ defList.set(index, def);
++ attrIndexTable.put(def, new Integer(index));
++ return index;
+ }
+
+ // encodings found in the code_headers band
+ private static final int[][] shortCodeLimits = {
+- { 12, 12 }, // s<12, l<12, e=0 [1..144]
+- { 8, 8 }, // s<8, l<8, e=1 [145..208]
+- { 7, 7 }, // s<7, l<7, e=2 [209..256]
++ { 12, 12 }, // s<12, l<12, e=0 [1..144]
++ { 8, 8 }, // s<8, l<8, e=1 [145..208]
++ { 7, 7 }, // s<7, l<7, e=2 [209..256]
+ };
+ public final int shortCodeHeader_h_limit = shortCodeLimits.length;
+
+ // return 0 if it won't encode, else a number in [1..255]
+ static int shortCodeHeader(Code code) {
+- int s = code.max_stack;
+- int l0 = code.max_locals;
+- int h = code.handler_class.length;
+- if (h >= shortCodeLimits.length) return LONG_CODE_HEADER;
+- int siglen = code.getMethod().getArgumentSize();
+- assert(l0 >= siglen); // enough locals for signature!
+- if (l0 < siglen) return LONG_CODE_HEADER;
+- int l1 = l0 - siglen; // do not count locals required by the signature
+- int lims = shortCodeLimits[h][0];
+- int liml = shortCodeLimits[h][1];
+- if (s >= lims || l1 >= liml) return LONG_CODE_HEADER;
+- int sc = shortCodeHeader_h_base(h);
+- sc += s + lims*l1;
+- if (sc > 255) return LONG_CODE_HEADER;
+- assert(shortCodeHeader_max_stack(sc) == s);
+- assert(shortCodeHeader_max_na_locals(sc) == l1);
+- assert(shortCodeHeader_handler_count(sc) == h);
+- return sc;
++ int s = code.max_stack;
++ int l0 = code.max_locals;
++ int h = code.handler_class.length;
++ if (h >= shortCodeLimits.length) return LONG_CODE_HEADER;
++ int siglen = code.getMethod().getArgumentSize();
++ assert(l0 >= siglen); // enough locals for signature!
++ if (l0 < siglen) return LONG_CODE_HEADER;
++ int l1 = l0 - siglen; // do not count locals required by the signature
++ int lims = shortCodeLimits[h][0];
++ int liml = shortCodeLimits[h][1];
++ if (s >= lims || l1 >= liml) return LONG_CODE_HEADER;
++ int sc = shortCodeHeader_h_base(h);
++ sc += s + lims*l1;
++ if (sc > 255) return LONG_CODE_HEADER;
++ assert(shortCodeHeader_max_stack(sc) == s);
++ assert(shortCodeHeader_max_na_locals(sc) == l1);
++ assert(shortCodeHeader_handler_count(sc) == h);
++ return sc;
+ }
+
+ static final int LONG_CODE_HEADER = 0;
+ static int shortCodeHeader_handler_count(int sc) {
+- assert(sc > 0 && sc <= 255);
+- for (int h = 0; ; h++) {
+- if (sc < shortCodeHeader_h_base(h+1))
+- return h;
+- }
++ assert(sc > 0 && sc <= 255);
++ for (int h = 0; ; h++) {
++ if (sc < shortCodeHeader_h_base(h+1))
++ return h;
++ }
+ }
+ static int shortCodeHeader_max_stack(int sc) {
+- int h = shortCodeHeader_handler_count(sc);
+- int lims = shortCodeLimits[h][0];
+- return (sc - shortCodeHeader_h_base(h)) % lims;
++ int h = shortCodeHeader_handler_count(sc);
++ int lims = shortCodeLimits[h][0];
++ return (sc - shortCodeHeader_h_base(h)) % lims;
+ }
+ static int shortCodeHeader_max_na_locals(int sc) {
+- int h = shortCodeHeader_handler_count(sc);
+- int lims = shortCodeLimits[h][0];
+- return (sc - shortCodeHeader_h_base(h)) / lims;
++ int h = shortCodeHeader_handler_count(sc);
++ int lims = shortCodeLimits[h][0];
++ return (sc - shortCodeHeader_h_base(h)) / lims;
+ }
+
+ private static int shortCodeHeader_h_base(int h) {
+- assert(h <= shortCodeLimits.length);
+- int sc = 1;
+- for (int h0 = 0; h0 < h; h0++) {
+- int lims = shortCodeLimits[h0][0];
+- int liml = shortCodeLimits[h0][1];
+- sc += lims * liml;
+- }
+- return sc;
++ assert(h <= shortCodeLimits.length);
++ int sc = 1;
++ for (int h0 = 0; h0 < h; h0++) {
++ int lims = shortCodeLimits[h0][0];
++ int liml = shortCodeLimits[h0][1];
++ sc += lims * liml;
++ }
++ return sc;
+ }
+
+ // utilities for accessing the bc_label band:
+ protected void putLabel(IntBand bc_label, Code c, int pc, int targetPC) {
+- bc_label.putInt(c.encodeBCI(targetPC) - c.encodeBCI(pc));
++ bc_label.putInt(c.encodeBCI(targetPC) - c.encodeBCI(pc));
+ }
+ protected int getLabel(IntBand bc_label, Code c, int pc) {
+- return c.decodeBCI(bc_label.getInt() + c.encodeBCI(pc));
++ return c.decodeBCI(bc_label.getInt() + c.encodeBCI(pc));
+ }
+
+ protected CPRefBand getCPRefOpBand(int bc) {
+- switch (Instruction.getCPRefOpTag(bc)) {
+- case CONSTANT_Class:
+- return bc_classref;
+- case CONSTANT_Fieldref:
+- return bc_fieldref;
+- case CONSTANT_Methodref:
+- return bc_methodref;
+- case CONSTANT_InterfaceMethodref:
+- return bc_imethodref;
+- case CONSTANT_Literal:
+- switch (bc) {
+- case _ildc: case _ildc_w:
+- return bc_intref;
+- case _fldc: case _fldc_w:
+- return bc_floatref;
+- case _lldc2_w:
+- return bc_longref;
+- case _dldc2_w:
+- return bc_doubleref;
+- case _aldc: case _aldc_w:
+- return bc_stringref;
+- case _cldc: case _cldc_w:
+- return bc_classref;
+- }
+- break;
+- }
+- assert(false);
+- return null;
++ switch (Instruction.getCPRefOpTag(bc)) {
++ case CONSTANT_Class:
++ return bc_classref;
++ case CONSTANT_Fieldref:
++ return bc_fieldref;
++ case CONSTANT_Methodref:
++ return bc_methodref;
++ case CONSTANT_InterfaceMethodref:
++ return bc_imethodref;
++ case CONSTANT_Literal:
++ switch (bc) {
++ case _ildc: case _ildc_w:
++ return bc_intref;
++ case _fldc: case _fldc_w:
++ return bc_floatref;
++ case _lldc2_w:
++ return bc_longref;
++ case _dldc2_w:
++ return bc_doubleref;
++ case _aldc: case _aldc_w:
++ return bc_stringref;
++ case _cldc: case _cldc_w:
++ return bc_classref;
++ }
++ break;
++ }
++ assert(false);
++ return null;
+ }
+
+ protected CPRefBand selfOpRefBand(int self_bc) {
+- assert(Instruction.isSelfLinkerOp(self_bc));
+- int idx = (self_bc - _self_linker_op);
+- boolean isSuper = (idx >= _self_linker_super_flag);
+- if (isSuper) idx -= _self_linker_super_flag;
+- boolean isAload = (idx >= _self_linker_aload_flag);
+- if (isAload) idx -= _self_linker_aload_flag;
+- int origBC = _first_linker_op + idx;
+- boolean isField = Instruction.isFieldOp(origBC);
+- if (!isSuper)
+- return isField? bc_thisfield: bc_thismethod;
+- else
+- return isField? bc_superfield: bc_supermethod;
++ assert(Instruction.isSelfLinkerOp(self_bc));
++ int idx = (self_bc - _self_linker_op);
++ boolean isSuper = (idx >= _self_linker_super_flag);
++ if (isSuper) idx -= _self_linker_super_flag;
++ boolean isAload = (idx >= _self_linker_aload_flag);
++ if (isAload) idx -= _self_linker_aload_flag;
++ int origBC = _first_linker_op + idx;
++ boolean isField = Instruction.isFieldOp(origBC);
++ if (!isSuper)
++ return isField? bc_thisfield: bc_thismethod;
++ else
++ return isField? bc_superfield: bc_supermethod;
+ }
+
+ ////////////////////////////////////////////////////////////////////
+@@ -2347,317 +2347,319 @@ class BandStructure implements Constants
+ static int nextSeqForDebug;
+ static File dumpDir;
+ static OutputStream getDumpStream(Band b, String ext) throws IOException {
+- return getDumpStream(b.name, b.seqForDebug, ext, b);
++ return getDumpStream(b.name, b.seqForDebug, ext, b);
+ }
+ static OutputStream getDumpStream(Index ix, String ext) throws IOException {
+- if (ix.size() == 0) return new ByteArrayOutputStream();
+- int seq = ConstantPool.TAG_ORDER[ix.cpMap[0].tag];
+- return getDumpStream(ix.debugName, seq, ext, ix);
++ if (ix.size() == 0) return new ByteArrayOutputStream();
++ int seq = ConstantPool.TAG_ORDER[ix.cpMap[0].tag];
++ return getDumpStream(ix.debugName, seq, ext, ix);
+ }
+ static OutputStream getDumpStream(String name, int seq, String ext, Object b) throws IOException {
+- if (dumpDir == null) {
+- dumpDir = File.createTempFile("BD_", "", new File("."));
+- dumpDir.delete();
+- if (dumpDir.mkdir())
+- Utils.log.info("Dumping bands to "+dumpDir);
+- }
+- name = name.replace('(', ' ').replace(')', ' ');
+- name = name.replace('/', ' ');
+- name = name.replace('*', ' ');
+- name = name.trim().replace(' ','_');
+- name = ((10000+seq) + "_" + name).substring(1);
+- File dumpFile = new File(dumpDir, name+ext);
+- Utils.log.info("Dumping "+b+" to "+dumpFile);
+- return new BufferedOutputStream(new FileOutputStream(dumpFile));
++ if (dumpDir == null) {
++ dumpDir = File.createTempFile("BD_", "", new File("."));
++ dumpDir.delete();
++ if (dumpDir.mkdir())
++ Utils.log.info("Dumping bands to "+dumpDir);
++ }
++ name = name.replace('(', ' ').replace(')', ' ');
++ name = name.replace('/', ' ');
++ name = name.replace('*', ' ');
++ name = name.trim().replace(' ','_');
++ name = ((10000+seq) + "_" + name).substring(1);
++ File dumpFile = new File(dumpDir, name+ext);
++ Utils.log.info("Dumping "+b+" to "+dumpFile);
++ return new BufferedOutputStream(new FileOutputStream(dumpFile));
+ }
+
+ // DEBUG ONLY: Validate me at each length change.
+ static boolean assertCanChangeLength(Band b) {
+- switch (b.phase) {
+- case COLLECT_PHASE:
+- case READ_PHASE:
+- return true;
+- }
+- return false;
++ switch (b.phase) {
++ case COLLECT_PHASE:
++ case READ_PHASE:
++ return true;
++ }
++ return false;
+ }
+
+ // DEBUG ONLY: Validate a phase.
+ static boolean assertPhase(Band b, int phaseExpected) {
+- if (b.phase() != phaseExpected) {
+- Utils.log.warning("phase expected "+phaseExpected+" was "+b.phase()+" in "+b);
+- return false;
+- }
+- return true;
++ if (b.phase() != phaseExpected) {
++ Utils.log.warning("phase expected "+phaseExpected+" was "+b.phase()+" in "+b);
++ return false;
++ }
++ return true;
+ }
+
+
+ // DEBUG ONLY: Tells whether verbosity is turned on.
+ static int verbose() {
+- return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
++ return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
+ }
+
+
+ // DEBUG ONLY: Validate me at each phase change.
+ static boolean assertPhaseChangeOK(Band b, int p0, int p1) {
+- switch (p0*10+p1) {
+- /// Writing phases:
+- case NO_PHASE*10+COLLECT_PHASE:
+- // Ready to collect data from the input classes.
+- assert(!b.isReader());
+- assert(b.capacity() >= 0);
+- assert(b.length() == 0);
+- return true;
+- case COLLECT_PHASE*10+FROZEN_PHASE:
+- case FROZEN_PHASE*10+FROZEN_PHASE:
+- assert(b.length() == 0);
+- return true;
+- case COLLECT_PHASE*10+WRITE_PHASE:
+- case FROZEN_PHASE*10+WRITE_PHASE:
+- // Data is all collected. Ready to write bytes to disk.
+- return true;
+- case WRITE_PHASE*10+DONE_PHASE:
+- // Done writing to disk. Ready to reset, in principle.
+- return true;
++ switch (p0*10+p1) {
++ /// Writing phases:
++ case NO_PHASE*10+COLLECT_PHASE:
++ // Ready to collect data from the input classes.
++ assert(!b.isReader());
++ assert(b.capacity() >= 0);
++ assert(b.length() == 0);
++ return true;
++ case COLLECT_PHASE*10+FROZEN_PHASE:
++ case FROZEN_PHASE*10+FROZEN_PHASE:
++ assert(b.length() == 0);
++ return true;
++ case COLLECT_PHASE*10+WRITE_PHASE:
++ case FROZEN_PHASE*10+WRITE_PHASE:
++ // Data is all collected. Ready to write bytes to disk.
++ return true;
++ case WRITE_PHASE*10+DONE_PHASE:
++ // Done writing to disk. Ready to reset, in principle.
++ return true;
+
+- /// Reading phases:
+- case NO_PHASE*10+EXPECT_PHASE:
+- assert(b.isReader());
+- assert(b.capacity() < 0);
+- return true;
+- case EXPECT_PHASE*10+READ_PHASE:
+- // Ready to read values from disk.
+- assert(Math.max(0,b.capacity()) >= b.valuesExpected());
+- assert(b.length() <= 0);
+- return true;
+- case READ_PHASE*10+DISBURSE_PHASE:
+- // Ready to disburse values.
+- assert(b.valuesRemainingForDebug() == b.length());
+- return true;
+- case DISBURSE_PHASE*10+DONE_PHASE:
+- // Done disbursing values. Ready to reset, in principle.
+- assert(assertDoneDisbursing(b));
+- return true;
+- }
+- if (p0 == p1)
+- Utils.log.warning("Already in phase "+p0);
+- else
+- Utils.log.warning("Unexpected phase "+p0+" -> "+p1);
+- return false;
++ /// Reading phases:
++ case NO_PHASE*10+EXPECT_PHASE:
++ assert(b.isReader());
++ assert(b.capacity() < 0);
++ return true;
++ case EXPECT_PHASE*10+READ_PHASE:
++ // Ready to read values from disk.
++ assert(Math.max(0,b.capacity()) >= b.valuesExpected());
++ assert(b.length() <= 0);
++ return true;
++ case READ_PHASE*10+DISBURSE_PHASE:
++ // Ready to disburse values.
++ assert(b.valuesRemainingForDebug() == b.length());
++ return true;
++ case DISBURSE_PHASE*10+DONE_PHASE:
++ // Done disbursing values. Ready to reset, in principle.
++ assert(assertDoneDisbursing(b));
++ return true;
++ }
++ if (p0 == p1)
++ Utils.log.warning("Already in phase "+p0);
++ else
++ Utils.log.warning("Unexpected phase "+p0+" -> "+p1);
++ return false;
+ }
+
+ static private boolean assertDoneDisbursing(Band b) {
+- if (b.phase != DISBURSE_PHASE) {
+- Utils.log.warning("assertDoneDisbursing: still in phase "+b.phase+": "+b);
+- if (verbose() <= 1) return false; // fail now
+- }
+- int left = b.valuesRemainingForDebug();
+- if (left > 0) {
+- Utils.log.warning("assertDoneDisbursing: "+left+" values left in "+b);
+- if (verbose() <= 1) return false; // fail now
+- }
+- if (b instanceof MultiBand) {
+- MultiBand mb = (MultiBand) b;
+- for (int i = 0; i < mb.bandCount; i++) {
+- Band sub = mb.bands[i];
+- if (sub.phase != DONE_PHASE) {
+- Utils.log.warning("assertDoneDisbursing: sub-band still in phase "+sub.phase+": "+sub);
+- if (verbose() <= 1) return false; // fail now
+- }
+- }
+- }
+- return true;
++ if (b.phase != DISBURSE_PHASE) {
++ Utils.log.warning("assertDoneDisbursing: still in phase "+b.phase+": "+b);
++ if (verbose() <= 1) return false; // fail now
++ }
++ int left = b.valuesRemainingForDebug();
++ if (left > 0) {
++ Utils.log.warning("assertDoneDisbursing: "+left+" values left in "+b);
++ if (verbose() <= 1) return false; // fail now
++ }
++ if (b instanceof MultiBand) {
++ MultiBand mb = (MultiBand) b;
++ for (int i = 0; i < mb.bandCount; i++) {
++ Band sub = mb.bands[i];
++ if (sub.phase != DONE_PHASE) {
++ Utils.log.warning("assertDoneDisbursing: sub-band still in phase "+sub.phase+": "+sub);
++ if (verbose() <= 1) return false; // fail now
++ }
++ }
++ }
++ return true;
+ }
+
+ static private void printCDecl(Band b) {
+- if (b instanceof MultiBand) {
+- MultiBand mb = (MultiBand) b;
+- for (int i = 0; i < mb.bandCount; i++) {
+- printCDecl(mb.bands[i]);
+- }
+- return;
+- }
+- String ixS = "NULL";
+- if (b instanceof CPRefBand) {
+- Index ix = ((CPRefBand)b).index;
+- if (ix != null) ixS = "INDEX("+ix.debugName+")";
+- }
+- Coding[] knownc = { BYTE1, CHAR3, BCI5, BRANCH5, UNSIGNED5,
+- UDELTA5, SIGNED5, DELTA5, MDELTA5 };
+- String[] knowns = { "BYTE1", "CHAR3", "BCI5", "BRANCH5", "UNSIGNED5",
+- "UDELTA5", "SIGNED5", "DELTA5", "MDELTA5" };
+- Coding rc = b.regularCoding;
+- int rci = Arrays.asList(knownc).indexOf(rc);
+- String cstr;
+- if (rci >= 0)
+- cstr = knowns[rci];
+- else
+- cstr = "CODING"+rc.keyString();
+- System.out.println(" BAND_INIT(\""+b.name()+"\""
+- +", "+cstr+", "+ixS+"),");
++ if (b instanceof MultiBand) {
++ MultiBand mb = (MultiBand) b;
++ for (int i = 0; i < mb.bandCount; i++) {
++ printCDecl(mb.bands[i]);
++ }
++ return;
++ }
++ String ixS = "NULL";
++ if (b instanceof CPRefBand) {
++ Index ix = ((CPRefBand)b).index;
++ if (ix != null) ixS = "INDEX("+ix.debugName+")";
++ }
++ Coding[] knownc = { BYTE1, CHAR3, BCI5, BRANCH5, UNSIGNED5,
++ UDELTA5, SIGNED5, DELTA5, MDELTA5 };
++ String[] knowns = { "BYTE1", "CHAR3", "BCI5", "BRANCH5", "UNSIGNED5",
++ "UDELTA5", "SIGNED5", "DELTA5", "MDELTA5" };
++ Coding rc = b.regularCoding;
++ int rci = Arrays.asList(knownc).indexOf(rc);
++ String cstr;
++ if (rci >= 0)
++ cstr = knowns[rci];
++ else
++ cstr = "CODING"+rc.keyString();
++ System.out.println(" BAND_INIT(\""+b.name()+"\""
++ +", "+cstr+", "+ixS+"),");
+ }
+
+ private HashMap prevForAssertMap;
+
+ // DEBUG ONLY: Record something about the band order.
+ boolean notePrevForAssert(Band b, Band p) {
+- if (prevForAssertMap == null)
+- prevForAssertMap = new HashMap();
+- prevForAssertMap.put(b, p);
+- return true;
++ if (prevForAssertMap == null)
++ prevForAssertMap = new HashMap();
++ prevForAssertMap.put(b, p);
++ return true;
+ }
+
+ // DEBUG ONLY: Validate next input band.
+ private boolean assertReadyToReadFrom(Band b, InputStream in) throws IOException {
+- Band p = (Band) prevForAssertMap.get(b);
+- // Any previous band must be done reading before this one starts.
+- if (p != null && phaseCmp(p.phase(), DISBURSE_PHASE) < 0) {
+- Utils.log.warning("Previous band not done reading.");
+- Utils.log.info(" Previous band: "+p);
+- Utils.log.info(" Next band: "+b);
+- Thread.dumpStack();
+- assert(verbose > 0); // die unless verbose is true
+- }
+- String name = b.name;
+- if (optDebugBands && !name.startsWith("(")) {
+- // Verify synchronization between reader & writer:
+- StringBuffer buf = new StringBuffer();
+- int ch;
+- while ((ch = in.read()) > 0)
+- buf.append((char)ch);
+- String inName = buf.toString();
+- if (!inName.equals(name)) {
+- StringBuffer sb = new StringBuffer();
+- sb.append("Expected "+name+" but read: ");
+- inName += (char)ch;
+- while (inName.length() < 10)
+- inName += (char)in.read();
+- for (int i = 0; i < inName.length(); i++)
+- sb.append(inName.charAt(i));
+- Utils.log.warning(sb.toString());
+- return false;
+- }
+- }
+- return true;
++ Band p = (Band) prevForAssertMap.get(b);
++ // Any previous band must be done reading before this one starts.
++ if (p != null && phaseCmp(p.phase(), DISBURSE_PHASE) < 0) {
++ Utils.log.warning("Previous band not done reading.");
++ Utils.log.info(" Previous band: "+p);
++ Utils.log.info(" Next band: "+b);
++ Thread.dumpStack();
++ assert(verbose > 0); // die unless verbose is true
++ }
++ String name = b.name;
++ if (optDebugBands && !name.startsWith("(")) {
++ // Verify synchronization between reader & writer:
++ StringBuffer buf = new StringBuffer();
++ int ch;
++ while ((ch = in.read()) > 0)
++ buf.append((char)ch);
++ String inName = buf.toString();
++ if (!inName.equals(name)) {
++ StringBuffer sb = new StringBuffer();
++ sb.append("Expected "+name+" but read: ");
++ inName += (char)ch;
++ while (inName.length() < 10)
++ inName += (char)in.read();
++ for (int i = 0; i < inName.length(); i++)
++ sb.append(inName.charAt(i));
++ Utils.log.warning(sb.toString());
++ return false;
++ }
++ }
++ return true;
+ }
+
+ // DEBUG ONLY: Make sure a bunch of cprefs are correct.
+ private boolean assertValidCPRefs(CPRefBand b) {
+- if (b.index == null) return true;
+- int limit = b.index.size()+1;
+- for (int i = 0; i < b.length(); i++) {
+- int v = b.valueAtForDebug(i);
+- if (v < 0 || v >= limit) {
+- Utils.log.warning("CP ref out of range "+
+- "["+i+"] = "+v+" in "+b);
+- return false;
+- }
+- }
+- return true;
++ if (b.index == null) return true;
++ int limit = b.index.size()+1;
++ for (int i = 0; i < b.length(); i++) {
++ int v = b.valueAtForDebug(i);
++ if (v < 0 || v >= limit) {
++ Utils.log.warning("CP ref out of range "+
++ "["+i+"] = "+v+" in "+b);
++ return false;
++ }
++ }
++ return true;
+ }
+
+ // DEBUG ONLY: Maybe write a debugging cookie to next output band.
+ private boolean assertReadyToWriteTo(Band b, OutputStream out) throws IOException {
+- Band p = (Band) prevForAssertMap.get(b);
+- // Any previous band must be done writing before this one starts.
+- if (p != null && phaseCmp(p.phase(), DONE_PHASE) < 0) {
+- Utils.log.warning("Previous band not done writing.");
+- Utils.log.info(" Previous band: "+p);
+- Utils.log.info(" Next band: "+b);
+- Thread.dumpStack();
+- assert(verbose > 0); // die unless verbose is true
+- }
+- String name = b.name;
+- if (optDebugBands && !name.startsWith("(")) {
+- // Verify synchronization between reader & writer:
+- for (int j = 0; j < name.length(); j++) {
+- out.write((byte)name.charAt(j));
+- }
+- out.write((byte)0);
+- }
+- return true;
++ Band p = (Band) prevForAssertMap.get(b);
++ // Any previous band must be done writing before this one starts.
++ if (p != null && phaseCmp(p.phase(), DONE_PHASE) < 0) {
++ Utils.log.warning("Previous band not done writing.");
++ Utils.log.info(" Previous band: "+p);
++ Utils.log.info(" Next band: "+b);
++ Thread.dumpStack();
++ assert(verbose > 0); // die unless verbose is true
++ }
++ String name = b.name;
++ if (optDebugBands && !name.startsWith("(")) {
++ // Verify synchronization between reader & writer:
++ for (int j = 0; j < name.length(); j++) {
++ out.write((byte)name.charAt(j));
++ }
++ out.write((byte)0);
++ }
++ return true;
+ }
+
+ protected static boolean testBit(int flags, int bitMask) {
+- return (flags & bitMask) != 0;
++ return (flags & bitMask) != 0;
+ }
+ protected static int setBit(int flags, int bitMask, boolean z) {
+- return z ? (flags | bitMask) : (flags &~ bitMask);
++ return z ? (flags | bitMask) : (flags &~ bitMask);
+ }
+ protected static boolean testBit(long flags, long bitMask) {
+- return (flags & bitMask) != 0;
++ return (flags & bitMask) != 0;
+ }
+ protected static long setBit(long flags, long bitMask, boolean z) {
+- return z ? (flags | bitMask) : (flags &~ bitMask);
++ return z ? (flags | bitMask) : (flags &~ bitMask);
+ }
+
+
+ static void printArrayTo(PrintStream ps, int[] values, int start, int end) {
+- int len = end-start;
+- for (int i = 0; i < len; i++) {
+- if (i % 10 == 0)
+- ps.println();
+- else
+- ps.print(" ");
+- ps.print(values[start+i]);
+- }
+- ps.println();
++ int len = end-start;
++ for (int i = 0; i < len; i++) {
++ if (i % 10 == 0)
++ ps.println();
++ else
++ ps.print(" ");
++ ps.print(values[start+i]);
++ }
++ ps.println();
+ }
+
+ static void printArrayTo(PrintStream ps, Entry[] cpMap, int start, int end) {
+- StringBuffer buf = new StringBuffer();
+- int len = end-start;
+- for (int i = 0; i < len; i++) {
+- String s = cpMap[start+i].stringValue();
+- buf.setLength(0);
+- for (int j = 0; j < s.length(); j++) {
+- char ch = s.charAt(j);
+- if (!(ch < ' ' || ch > '~' || ch == '\\')) {
+- buf.append(ch);
+- } else if (ch == '\n') {
+- buf.append("\\n");
+- } else if (ch == '\t') {
+- buf.append("\\t");
+- } else if (ch == '\r') {
+- buf.append("\\r");
+- } else {
+- buf.append("\\x"+Integer.toHexString(ch));
+- }
+- }
+- ps.println(buf);
+- }
++ StringBuffer buf = new StringBuffer();
++ int len = end-start;
++ for (int i = 0; i < len; i++) {
++ String s = cpMap[start+i].stringValue();
++ buf.setLength(0);
++ for (int j = 0; j < s.length(); j++) {
++ char ch = s.charAt(j);
++ if (!(ch < ' ' || ch > '~' || ch == '\\')) {
++ buf.append(ch);
++ } else if (ch == '\n') {
++ buf.append("\\n");
++ } else if (ch == '\t') {
++ buf.append("\\t");
++ } else if (ch == '\r') {
++ buf.append("\\r");
++ } else {
++ buf.append("\\x"+Integer.toHexString(ch));
++ }
++ }
++ ps.println(buf);
++ }
+ }
+
+
+ // Utilities for reallocating:
+ protected static Object[] realloc(Object[] a, int len) {
+- java.lang.Class elt = a.getClass().getComponentType();
+- Object[] na = (Object[]) java.lang.reflect.Array.newInstance(elt, len);
+- System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
+- return na;
++ java.lang.Class elt = a.getClass().getComponentType();
++ Object[] na = (Object[]) java.lang.reflect.Array.newInstance(elt, len);
++ System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
++ return na;
+ }
+ protected static Object[] realloc(Object[] a) {
+- return realloc(a, Math.max(10, a.length*2));
++ return realloc(a, Math.max(10, a.length*2));
+ }
+ static private int[] noInts = {};
+ protected static int[] realloc(int[] a, int len) {
+- if (len == 0) return noInts;
+- if (a == null) return new int[len];
+- int[] na = new int[len];
+- System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
+- return na;
++ if (len == 0) return noInts;
++ if (a == null) return new int[len];
++ int[] na = new int[len];
++ System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
++ return na;
+ }
+ protected static int[] realloc(int[] a) {
+- return realloc(a, Math.max(10, a.length*2));
++ return realloc(a, Math.max(10, a.length*2));
+ }
+ static private byte[] noBytes = {};
+ protected static byte[] realloc(byte[] a, int len) {
+- if (len == 0) return noBytes;
+- if (a == null) return new byte[len];
+- byte[] na = new byte[len];
+- System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
+- return na;
++ if (len == 0) return noBytes;
++ if (a == null) return new byte[len];
++ byte[] na = new byte[len];
++ System.arraycopy(a, 0, na, 0, Math.min(a.length, len));
++ return na;
+ }
+ protected static byte[] realloc(byte[] a) {
+- return realloc(a, Math.max(10, a.length*2));
++ return realloc(a, Math.max(10, a.length*2));
+ }
+ }
++
++
+diff --git a/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java b/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
+--- jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
++++ jdk/src/share/classes/com/sun/java/util/jar/pack/ConstantPool.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -22,7 +22,7 @@
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-
++
+ package com.sun.java.util.jar.pack;
+
+ import java.io.*;
+@@ -37,7 +37,7 @@ class ConstantPool implements Constants
+ private ConstantPool() {} // do not instantiate
+
+ static int verbose() {
+- return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
++ return Utils.currentPropMap().getInteger(Utils.DEBUG_VERBOSE);
+ }
+
+ // Uniquification tables for factory methods:
+@@ -53,659 +53,659 @@ class ConstantPool implements Constants
+ * Also used to back up more complex constant pool entries, like Class.
+ */
+ public static synchronized Utf8Entry getUtf8Entry(String value) {
+- Utf8Entry e = (Utf8Entry) utf8Entries.get(value);
+- if (e == null) {
+- e = new Utf8Entry(value);
+- utf8Entries.put(e.stringValue(), e);
+- }
+- return e;
++ Utf8Entry e = (Utf8Entry) utf8Entries.get(value);
++ if (e == null) {
++ e = new Utf8Entry(value);
++ utf8Entries.put(e.stringValue(), e);
++ }
++ return e;
+ }
+ /** Factory for Class constants. */
+ public static synchronized ClassEntry getClassEntry(String name) {
+- ClassEntry e = (ClassEntry) classEntries.get(name);
+- if (e == null) {
+- e = (ClassEntry) new ClassEntry(getUtf8Entry(name));
+- assert(name.equals(e.stringValue()));
+- classEntries.put(e.stringValue(), e);
+- }
+- return e;
++ ClassEntry e = (ClassEntry) classEntries.get(name);
++ if (e == null) {
++ e = (ClassEntry) new ClassEntry(getUtf8Entry(name));
++ assert(name.equals(e.stringValue()));
++ classEntries.put(e.stringValue(), e);
++ }
++ return e;
+ }
+ /** Factory for literal constants (String, Integer, etc.). */
+ public static synchronized LiteralEntry getLiteralEntry(Comparable value) {
+- LiteralEntry e = (LiteralEntry) literalEntries.get(value);
+- if (e == null) {
+- if (value instanceof String)
+- e = new StringEntry(getUtf8Entry((String)value));
+- else
+- e = new NumberEntry((Number)value);
+- literalEntries.put(value, e);
+- }
+- return e;
++ LiteralEntry e = (LiteralEntry) literalEntries.get(value);
++ if (e == null) {
++ if (value instanceof String)
++ e = new StringEntry(getUtf8Entry((String)value));
++ else
++ e = new NumberEntry((Number)value);
++ literalEntries.put(value, e);
++ }
++ return e;
+ }
+ /** Factory for literal constants (String, Integer, etc.). */
+ public static synchronized StringEntry getStringEntry(String value) {
+- return (StringEntry) getLiteralEntry(value);
++ return (StringEntry) getLiteralEntry(value);
+ }
+
+ /** Factory for signature (type) constants. */
+ public static synchronized SignatureEntry getSignatureEntry(String type) {
+- SignatureEntry e = (SignatureEntry) signatureEntries.get(type);
+- if (e == null) {
+- e = new SignatureEntry(type);
+- assert(e.stringValue().equals(type));
+- signatureEntries.put(type, e);
+- }
+- return e;
++ SignatureEntry e = (SignatureEntry) signatureEntries.get(type);
++ if (e == null) {
++ e = new SignatureEntry(type);
++ assert(e.stringValue().equals(type));
++ signatureEntries.put(type, e);
++ }
++ return e;
+ }
+ // Convenience overloading.
+ public static SignatureEntry getSignatureEntry(Utf8Entry formRef, ClassEntry[] classRefs) {
+- return getSignatureEntry(SignatureEntry.stringValueOf(formRef, classRefs));
++ return getSignatureEntry(SignatureEntry.stringValueOf(formRef, classRefs));
+ }
+
+ /** Factory for descriptor (name-and-type) constants. */
+ public static synchronized DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, SignatureEntry typeRef) {
+- String key = DescriptorEntry.stringValueOf(nameRef, typeRef);
+- DescriptorEntry e = (DescriptorEntry) descriptorEntries.get(key);
+- if (e == null) {
+- e = new DescriptorEntry(nameRef, typeRef);
+- assert(e.stringValue().equals(key))
+- : (e.stringValue()+" != "+(key));
+- descriptorEntries.put(key, e);
+- }
+- return e;
++ String key = DescriptorEntry.stringValueOf(nameRef, typeRef);
++ DescriptorEntry e = (DescriptorEntry) descriptorEntries.get(key);
++ if (e == null) {
++ e = new DescriptorEntry(nameRef, typeRef);
++ assert(e.stringValue().equals(key))
++ : (e.stringValue()+" != "+(key));
++ descriptorEntries.put(key, e);
++ }
++ return e;
+ }
+ // Convenience overloading.
+ public static DescriptorEntry getDescriptorEntry(Utf8Entry nameRef, Utf8Entry typeRef) {
+- return getDescriptorEntry(nameRef, getSignatureEntry(typeRef.stringValue()));
++ return getDescriptorEntry(nameRef, getSignatureEntry(typeRef.stringValue()));
+ }
+
+ /** Factory for member reference constants. */
+ public static synchronized MemberEntry getMemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) {
+- String key = MemberEntry.stringValueOf(tag, classRef, descRef);
+- MemberEntry e = (MemberEntry) memberEntries.get(key);
+- if (e == null) {
+- e = new MemberEntry(tag, classRef, descRef);
+- assert(e.stringValue().equals(key))
+- : (e.stringValue()+" != "+(key));
+- memberEntries.put(key, e);
+- }
+- return e;
++ String key = MemberEntry.stringValueOf(tag, classRef, descRef);
++ MemberEntry e = (MemberEntry) memberEntries.get(key);
++ if (e == null) {
++ e = new MemberEntry(tag, classRef, descRef);
++ assert(e.stringValue().equals(key))
++ : (e.stringValue()+" != "+(key));
++ memberEntries.put(key, e);
++ }
++ return e;
+ }
+
+
+ /** Entries in the constant pool. */
+ public static abstract
+ class Entry implements Comparable {
+- protected final byte tag; // a CONSTANT_foo code
+- protected int valueHash; // cached hashCode
++ protected final byte tag; // a CONSTANT_foo code
++ protected int valueHash; // cached hashCode
+
+- protected Entry(byte tag) {
+- this.tag = tag;
+- }
++ protected Entry(byte tag) {
++ this.tag = tag;
++ }
+
+- public final byte getTag() {
+- return tag;
+- }
++ public final byte getTag() {
++ return tag;
++ }
+
+- public Entry getRef(int i) {
+- return null;
+- }
++ public Entry getRef(int i) {
++ return null;
++ }
+
+- public boolean sameTagAs(Object o) {
+- return (o instanceof Entry) && ((Entry)o).tag == tag;
+- }
+- public boolean eq(Entry that) { // same reference
+- assert(that != null);
+- return this == that || this.equals(that);
+- }
++ public boolean sameTagAs(Object o) {
++ return (o instanceof Entry) && ((Entry)o).tag == tag;
++ }
++ public boolean eq(Entry that) { // same reference
++ assert(that != null);
++ return this == that || this.equals(that);
++ }
+
+- // Equality of Entries is value-based.
+- public abstract boolean equals(Object o);
+- public final int hashCode() {
+- if (valueHash == 0) {
+- valueHash = computeValueHash();
+- if (valueHash == 0) valueHash = 1;
+- }
+- return valueHash;
+- }
+- protected abstract int computeValueHash();
++ // Equality of Entries is value-based.
++ public abstract boolean equals(Object o);
++ public final int hashCode() {
++ if (valueHash == 0) {
++ valueHash = computeValueHash();
++ if (valueHash == 0) valueHash = 1;
++ }
++ return valueHash;
++ }
++ protected abstract int computeValueHash();
+
+- public abstract int compareTo(Object o);
++ public abstract int compareTo(Object o);
+
+- protected int superCompareTo(Object o) {
+- Entry that = (Entry) o;
++ protected int superCompareTo(Object o) {
++ Entry that = (Entry) o;
+
+- if (this.tag != that.tag) {
+- return TAG_ORDER[this.tag] - TAG_ORDER[that.tag];
+- }
++ if (this.tag != that.tag) {
++ return TAG_ORDER[this.tag] - TAG_ORDER[that.tag];
++ }
+
+- return 0; // subclasses must refine this
+- }
++ return 0; // subclasses must refine this
++ }
+
+- public final boolean isDoubleWord() {
+- return tag == CONSTANT_Double || tag == CONSTANT_Long;
+- }
++ public final boolean isDoubleWord() {
++ return tag == CONSTANT_Double || tag == CONSTANT_Long;
++ }
+
+- public final boolean tagMatches(int tag) {
+- return (this.tag == tag);
+- }
++ public final boolean tagMatches(int tag) {
++ return (this.tag == tag);
++ }
+
+- public String toString() {
+- String valuePrint = stringValue();
+- if (verbose() > 4) {
+- if (valueHash != 0)
+- valuePrint += " hash="+valueHash;
+- valuePrint += " id="+System.identityHashCode(this);
+- }
+- return tagName(tag)+"="+valuePrint;
+- }
+- public abstract String stringValue();
++ public String toString() {
++ String valuePrint = stringValue();
++ if (verbose() > 4) {
++ if (valueHash != 0)
++ valuePrint += " hash="+valueHash;
++ valuePrint += " id="+System.identityHashCode(this);
++ }
++ return tagName(tag)+"="+valuePrint;
++ }
++ public abstract String stringValue();
+ }
+
+ public static
+ class Utf8Entry extends Entry {
+- final String value;
++ final String value;
+
+- Utf8Entry(String value) {
+- super(CONSTANT_Utf8);
+- this.value = value.intern();
+- hashCode(); // force computation of valueHash
+- }
+- protected int computeValueHash() {
+- return value.hashCode();
+- }
+- public boolean equals(Object o) {
+- if (!sameTagAs(o)) return false;
+- // Use reference equality of interned strings:
+- return ((Utf8Entry)o).value == value;
+- }
+- public int compareTo(Object o) {
+- int x = superCompareTo(o);
+- if (x == 0) {
+- x = value.compareTo(((Utf8Entry)o).value);
+- }
+- return x;
+- }
+- public String stringValue() {
+- return value;
+- }
++ Utf8Entry(String value) {
++ super(CONSTANT_Utf8);
++ this.value = value.intern();
++ hashCode(); // force computation of valueHash
++ }
++ protected int computeValueHash() {
++ return value.hashCode();
++ }
++ public boolean equals(Object o) {
++ if (!sameTagAs(o)) return false;
++ // Use reference equality of interned strings:
++ return ((Utf8Entry)o).value == value;
++ }
++ public int compareTo(Object o) {
++ int x = superCompareTo(o);
++ if (x == 0) {
++ x = value.compareTo(((Utf8Entry)o).value);
++ }
++ return x;
++ }
++ public String stringValue() {
++ return value;
++ }
+ }
+
+ static boolean isMemberTag(byte tag) {
+- switch (tag) {
+- case CONSTANT_Fieldref:
+- case CONSTANT_Methodref:
+- case CONSTANT_InterfaceMethodref:
+- return true;
+- }
+- return false;
++ switch (tag) {
++ case CONSTANT_Fieldref:
++ case CONSTANT_Methodref:
++ case CONSTANT_InterfaceMethodref:
++ return true;
++ }
++ return false;
+ }
+
+ static byte numberTagOf(Number value) {
+- if (value instanceof Integer) return CONSTANT_Integer;
+- if (value instanceof Float) return CONSTANT_Float;
+- if (value instanceof Long) return CONSTANT_Long;
+- if (value instanceof Double) return CONSTANT_Double;
+- throw new RuntimeException("bad literal value "+value);
++ if (value instanceof Integer) return CONSTANT_Integer;
++ if (value instanceof Float) return CONSTANT_Float;
++ if (value instanceof Long) return CONSTANT_Long;
++ if (value instanceof Double) return CONSTANT_Double;
++ throw new RuntimeException("bad literal value "+value);
+ }
+
+ public static abstract
+ class LiteralEntry extends Entry {
+- protected LiteralEntry(byte tag) {
+- super(tag);
+- }
++ protected LiteralEntry(byte tag) {
++ super(tag);
++ }
+
+- public abstract Comparable literalValue();
++ public abstract Comparable literalValue();
+ }
+
+ public static
+ class NumberEntry extends LiteralEntry {
+- final Number value;
+- NumberEntry(Number value) {
+- super(numberTagOf(value));
+- this.value = value;
+- hashCode(); // force computation of valueHash
+- }
+- protected int computeValueHash() {
+- return value.hashCode();
+- }
++ final Number value;
++ NumberEntry(Number value) {
++ super(numberTagOf(value));
++ this.value = value;
++ hashCode(); // force computation of valueHash
++ }
++ protected int computeValueHash() {
++ return value.hashCode();
++ }
+
+- public boolean equals(Object o) {
+- if (!sameTagAs(o)) return false;
+- return (((NumberEntry)o).value).equals(value);
+- }
+- public int compareTo(Object o) {
+- int x = superCompareTo(o);
+- if (x == 0) {
+- x = ((Comparable)value).compareTo(((NumberEntry)o).value);
+- }
+- return x;
+- }
+- public Number numberValue() {
+- return value;
+- }
+- public Comparable literalValue() {
+- return (Comparable) value;
+- }
+- public String stringValue() {
+- return value.toString();
+- }
++ public boolean equals(Object o) {
++ if (!sameTagAs(o)) return false;
++ return (((NumberEntry)o).value).equals(value);
++ }
++ public int compareTo(Object o) {
++ int x = superCompareTo(o);
++ if (x == 0) {
++ x = ((Comparable)value).compareTo(((NumberEntry)o).value);
++ }
++ return x;
++ }
++ public Number numberValue() {
++ return value;
++ }
++ public Comparable literalValue() {
++ return (Comparable) value;
++ }
++ public String stringValue() {
++ return value.toString();
++ }
+ }
+
+ public static
+ class StringEntry extends LiteralEntry {
+- final Utf8Entry ref;
+- public Entry getRef(int i) { return i == 0 ? ref : null; }
++ final Utf8Entry ref;
++ public Entry getRef(int i) { return i == 0 ? ref : null; }
+
+- StringEntry(Entry ref) {
+- super(CONSTANT_String);
+- this.ref = (Utf8Entry) ref;
+- hashCode(); // force computation of valueHash
+- }
+- protected int computeValueHash() {
+- return ref.hashCode() + tag;
+- }
+- public boolean equals(Object o) {
+- if (!sameTagAs(o)) return false;
+- return ((StringEntry)o).ref.eq(ref);
+- }
+- public int compareTo(Object o) {
+- int x = superCompareTo(o);
+- if (x == 0) {
+- x = ref.compareTo(((StringEntry)o).ref);
+- }
+- return x;
+- }
+- public Comparable literalValue() {
+- return ref.stringValue();
+- }
+- public String stringValue() {
+- return ref.stringValue();
+- }
++ StringEntry(Entry ref) {
++ super(CONSTANT_String);
++ this.ref = (Utf8Entry) ref;
++ hashCode(); // force computation of valueHash
++ }
++ protected int computeValueHash() {
++ return ref.hashCode() + tag;
++ }
++ public boolean equals(Object o) {
++ if (!sameTagAs(o)) return false;
++ return ((StringEntry)o).ref.eq(ref);
++ }
++ public int compareTo(Object o) {
++ int x = superCompareTo(o);
++ if (x == 0) {
++ x = ref.compareTo(((StringEntry)o).ref);
++ }
++ return x;
++ }
++ public Comparable literalValue() {
++ return ref.stringValue();
++ }
++ public String stringValue() {
++ return ref.stringValue();
++ }
+ }
+
+ public static
+ class ClassEntry extends Entry {
+- final Utf8Entry ref;
+- public Entry getRef(int i) { return i == 0 ? ref : null; }
++ final Utf8Entry ref;
++ public Entry getRef(int i) { return i == 0 ? ref : null; }
+
+- protected int computeValueHash() {
+- return ref.hashCode() + tag;
+- }
+- ClassEntry(Entry ref) {
+- super(CONSTANT_Class);
+- this.ref = (Utf8Entry) ref;
+- hashCode(); // force computation of valueHash
+- }
+- public boolean equals(Object o) {
+- if (!sameTagAs(o)) return false;
+- return ((ClassEntry)o).ref.eq(ref);
+- }
+- public int compareTo(Object o) {
+- int x = superCompareTo(o);
+- if (x == 0) {
+- x = ref.compareTo(((ClassEntry)o).ref);
+- }
+- return x;
+- }
+- public String stringValue() {
+- return ref.stringValue();
+- }
++ protected int computeValueHash() {
++ return ref.hashCode() + tag;
++ }
++ ClassEntry(Entry ref) {
++ super(CONSTANT_Class);
++ this.ref = (Utf8Entry) ref;
++ hashCode(); // force computation of valueHash
++ }
++ public boolean equals(Object o) {
++ if (!sameTagAs(o)) return false;
++ return ((ClassEntry)o).ref.eq(ref);
++ }
++ public int compareTo(Object o) {
++ int x = superCompareTo(o);
++ if (x == 0) {
++ x = ref.compareTo(((ClassEntry)o).ref);
++ }
++ return x;
++ }
++ public String stringValue() {
++ return ref.stringValue();
++ }
+ }
+
+ public static
+ class DescriptorEntry extends Entry {
+- final Utf8Entry nameRef;
+- final SignatureEntry typeRef;
+- public Entry getRef(int i) {
+- if (i == 0) return nameRef;
+- if (i == 1) return typeRef;
+- return null;
+- }
+- DescriptorEntry(Entry nameRef, Entry typeRef) {
+- super(CONSTANT_NameandType);
+- if (typeRef instanceof Utf8Entry) {
+- typeRef = getSignatureEntry(typeRef.stringValue());
+- }
+- this.nameRef = (Utf8Entry) nameRef;
+- this.typeRef = (SignatureEntry) typeRef;
+- hashCode(); // force computation of valueHash
+- }
+- protected int computeValueHash() {
+- int hc2 = typeRef.hashCode();
+- return (nameRef.hashCode() + (hc2 << 8)) ^ hc2;
+- }
+- public boolean equals(Object o) {
+- if (!sameTagAs(o)) return false;
+- DescriptorEntry that = (DescriptorEntry)o;
+- return this.nameRef.eq(that.nameRef)
+- && this.typeRef.eq(that.typeRef);
+- }
+- public int compareTo(Object o) {
+- int x = superCompareTo(o);
+- if (x == 0) {
+- DescriptorEntry that = (DescriptorEntry)o;
+- // Primary key is typeRef, not nameRef.
+- x = this.typeRef.compareTo(that.typeRef);
+- if (x == 0)
+- x = this.nameRef.compareTo(that.nameRef);
+- }
+- return x;
+- }
+- public String stringValue() {
+- return stringValueOf(nameRef, typeRef);
+- }
+- static
+- String stringValueOf(Entry nameRef, Entry typeRef) {
+- return typeRef.stringValue()+","+nameRef.stringValue();
+- }
++ final Utf8Entry nameRef;
++ final SignatureEntry typeRef;
++ public Entry getRef(int i) {
++ if (i == 0) return nameRef;
++ if (i == 1) return typeRef;
++ return null;
++ }
++ DescriptorEntry(Entry nameRef, Entry typeRef) {
++ super(CONSTANT_NameandType);
++ if (typeRef instanceof Utf8Entry) {
++ typeRef = getSignatureEntry(typeRef.stringValue());
++ }
++ this.nameRef = (Utf8Entry) nameRef;
++ this.typeRef = (SignatureEntry) typeRef;
++ hashCode(); // force computation of valueHash
++ }
++ protected int computeValueHash() {
++ int hc2 = typeRef.hashCode();
++ return (nameRef.hashCode() + (hc2 << 8)) ^ hc2;
++ }
++ public boolean equals(Object o) {
++ if (!sameTagAs(o)) return false;
++ DescriptorEntry that = (DescriptorEntry)o;
++ return this.nameRef.eq(that.nameRef)
++ && this.typeRef.eq(that.typeRef);
++ }
++ public int compareTo(Object o) {
++ int x = superCompareTo(o);
++ if (x == 0) {
++ DescriptorEntry that = (DescriptorEntry)o;
++ // Primary key is typeRef, not nameRef.
++ x = this.typeRef.compareTo(that.typeRef);
++ if (x == 0)
++ x = this.nameRef.compareTo(that.nameRef);
++ }
++ return x;
++ }
++ public String stringValue() {
++ return stringValueOf(nameRef, typeRef);
++ }
++ static
++ String stringValueOf(Entry nameRef, Entry typeRef) {
++ return typeRef.stringValue()+","+nameRef.stringValue();
++ }
+
+- public String prettyString() {
+- return nameRef.stringValue()+typeRef.prettyString();
+- }
++ public String prettyString() {
++ return nameRef.stringValue()+typeRef.prettyString();
++ }
+
+- public boolean isMethod() {
+- return typeRef.isMethod();
+- }
++ public boolean isMethod() {
++ return typeRef.isMethod();
++ }
+
+- public byte getLiteralTag() {
+- return typeRef.getLiteralTag();
+- }
++ public byte getLiteralTag() {
++ return typeRef.getLiteralTag();
++ }
+ }
+
+ public static
+ class MemberEntry extends Entry {
+- final ClassEntry classRef;
+- final DescriptorEntry descRef;
+- public Entry getRef(int i) {
+- if (i == 0) return classRef;
+- if (i == 1) return descRef;
+- return null;
+- }
+- protected int computeValueHash() {
+- int hc2 = descRef.hashCode();
+- return (classRef.hashCode() + (hc2 << 8)) ^ hc2;
+- }
++ final ClassEntry classRef;
++ final DescriptorEntry descRef;
++ public Entry getRef(int i) {
++ if (i == 0) return classRef;
++ if (i == 1) return descRef;
++ return null;
++ }
++ protected int computeValueHash() {
++ int hc2 = descRef.hashCode();
++ return (classRef.hashCode() + (hc2 << 8)) ^ hc2;
++ }
+
+- MemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) {
+- super(tag);
+- assert(isMemberTag(tag));
+- this.classRef = classRef;
+- this.descRef = descRef;
+- hashCode(); // force computation of valueHash
+- }
+- public boolean equals(Object o) {
+- if (!sameTagAs(o)) return false;
+- MemberEntry that = (MemberEntry)o;
+- return this.classRef.eq(that.classRef)
+- && this.descRef.eq(that.descRef);
+- }
+- public int compareTo(Object o) {
+- int x = superCompareTo(o);
+- if (x == 0) {
+- MemberEntry that = (MemberEntry)o;
+- // Primary key is classRef.
+- x = this.classRef.compareTo(that.classRef);
+- if (x == 0)
+- x = this.descRef.compareTo(that.descRef);
+- }
+- return x;
+- }
+- public String stringValue() {
+- return stringValueOf(tag, classRef, descRef);
+- }
+- static
+- String stringValueOf(byte tag, ClassEntry classRef, DescriptorEntry descRef) {
+- assert(isMemberTag(tag));
+- String pfx;
+- switch (tag) {
+- case CONSTANT_Fieldref: pfx = "Field:"; break;
+- case CONSTANT_Methodref: pfx = "Method:"; break;
+- case CONSTANT_InterfaceMethodref: pfx = "IMethod:"; break;
+- default: pfx = tag+"???"; break;
+- }
+- return pfx+classRef.stringValue()+","+descRef.stringValue();
+- }
++ MemberEntry(byte tag, ClassEntry classRef, DescriptorEntry descRef) {
++ super(tag);
++ assert(isMemberTag(tag));
++ this.classRef = classRef;
++ this.descRef = descRef;
++ hashCode(); // force computation of valueHash
++ }
++ public boolean equals(Object o) {
++ if (!sameTagAs(o)) return false;
++ MemberEntry that = (MemberEntry)o;
++ return this.classRef.eq(that.classRef)
++ && this.descRef.eq(that.descRef);
++ }
++ public int compareTo(Object o) {
++ int x = superCompareTo(o);
++ if (x == 0) {
++ MemberEntry that = (MemberEntry)o;
++ // Primary key is classRef.
++ x = this.classRef.compareTo(that.classRef);
++ if (x == 0)
++ x = this.descRef.compareTo(that.descRef);
++ }
++ return x;
++ }
++ public String stringValue() {
++ return stringValueOf(tag, classRef, descRef);
++ }
++ static
++ String stringValueOf(byte tag, ClassEntry classRef, DescriptorEntry descRef) {
++ assert(isMemberTag(tag));
++ String pfx;
++ switch (tag) {
++ case CONSTANT_Fieldref: pfx = "Field:"; break;
++ case CONSTANT_Methodref: pfx = "Method:"; break;
++ case CONSTANT_InterfaceMethodref: pfx = "IMethod:"; break;
++ default: pfx = tag+"???"; break;
++ }
++ return pfx+classRef.stringValue()+","+descRef.stringValue();
++ }
+
+- public boolean isMethod() {
+- return descRef.isMethod();
+- }
++ public boolean isMethod() {
++ return descRef.isMethod();
++ }
+ }
+
+ public static
+ class SignatureEntry extends Entry {
+- final Utf8Entry formRef;
+- final ClassEntry[] classRefs;
+- String value;
+- Utf8Entry asUtf8Entry;
+- public Entry getRef(int i) {
+- if (i == 0) return formRef;
+- return i-1 < classRefs.length ? classRefs[i-1] : null;
+- }
+- SignatureEntry(String value) {
+- super(CONSTANT_Signature);
+- value = value.intern(); // always do this
+- this.value = value;
+- String[] parts = structureSignature(value);
+- formRef = getUtf8Entry(parts[0]);
+- classRefs = new ClassEntry[parts.length-1];
+- for (int i = 1; i < parts.length; i++)
+- classRefs[i-1] = getClassEntry(parts[i]);
+- hashCode(); // force computation of valueHash
+- }
+- protected int computeValueHash() {
+- stringValue(); // force computation of value
+- return value.hashCode() + tag;
+- }
++ final Utf8Entry formRef;
++ final ClassEntry[] classRefs;
++ String value;
++ Utf8Entry asUtf8Entry;
++ public Entry getRef(int i) {
++ if (i == 0) return formRef;
++ return i-1 < classRefs.length ? classRefs[i-1] : null;
++ }
++ SignatureEntry(String value) {
++ super(CONSTANT_Signature);
++ value = value.intern(); // always do this
++ this.value = value;
++ String[] parts = structureSignature(value);
++ formRef = getUtf8Entry(parts[0]);
++ classRefs = new ClassEntry[parts.length-1];
++ for (int i = 1; i < parts.length; i++)
++ classRefs[i-1] = getClassEntry(parts[i]);
++ hashCode(); // force computation of valueHash
++ }
++ protected int computeValueHash() {
++ stringValue(); // force computation of value
++ return value.hashCode() + tag;
++ }
+
+- public Utf8Entry asUtf8Entry() {
+- if (asUtf8Entry == null) {
+- asUtf8Entry = getUtf8Entry(stringValue());
+- }
+- return asUtf8Entry;
+- }
++ public Utf8Entry asUtf8Entry() {
++ if (asUtf8Entry == null) {
++ asUtf8Entry = getUtf8Entry(stringValue());
++ }
++ return asUtf8Entry;
++ }
+
+- public boolean equals(Object o) {
+- if (!sameTagAs(o)) return false;
+- return ((SignatureEntry)o).value == value;
+- }
+- public int compareTo(Object o) {
+- int x = superCompareTo(o);
+- if (x == 0) {
+- SignatureEntry that = (SignatureEntry)o;
+- x = compareSignatures(this.value, that.value);
+- }
+- return x;
+- }
+- public String stringValue() {
+- if (value == null) {
+- value = stringValueOf(formRef, classRefs);
+- }
+- return value;
+- }
+- static
+- String stringValueOf(Utf8Entry formRef, ClassEntry[] classRefs) {
+- String[] parts = new String[1+classRefs.length];
+- parts[0] = formRef.stringValue();
+- for (int i = 1; i < parts.length; i++)
+- parts[i] = classRefs[i-1].stringValue();
+- return flattenSignature(parts).intern();
+- }
++ public boolean equals(Object o) {
++ if (!sameTagAs(o)) return false;
++ return ((SignatureEntry)o).value == value;
++ }
++ public int compareTo(Object o) {
++ int x = superCompareTo(o);
++ if (x == 0) {
++ SignatureEntry that = (SignatureEntry)o;
++ x = compareSignatures(this.value, that.value);
++ }
++ return x;
++ }
++ public String stringValue() {
++ if (value == null) {
++ value = stringValueOf(formRef, classRefs);
++ }
++ return value;
++ }
++ static
++ String stringValueOf(Utf8Entry formRef, ClassEntry[] classRefs) {
++ String[] parts = new String[1+classRefs.length];
++ parts[0] = formRef.stringValue();
++ for (int i = 1; i < parts.length; i++)
++ parts[i] = classRefs[i-1].stringValue();
++ return flattenSignature(parts).intern();
++ }
+
+- public int computeSize(boolean countDoublesTwice) {
+- String form = formRef.stringValue();
+- int min = 0;
+- int max = 1;
+- if (isMethod()) {
+- min = 1;
+- max = form.indexOf(')');
+- }
+- int size = 0;
+- for (int i = min; i < max; i++) {
+- switch (form.charAt(i)) {
+- case 'D':
+- case 'J':
+- if (countDoublesTwice) size++;
+- break;
+- case '[':
+- // Skip rest of array info.
+- while (form.charAt(i) == '[') ++i;
+- break;
+- case ';':
+- continue;
+- default:
+- assert(0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i)));
+- break;
+- }
+- size++;
+- }
+- return size;
+- }
+- public boolean isMethod() {
+- return formRef.stringValue().charAt(0) == '(';
+- }
+- public byte getLiteralTag() {
+- switch (formRef.stringValue().charAt(0)) {
+- case 'L': return CONSTANT_String;
+- case 'I': return CONSTANT_Integer;
+- case 'J': return CONSTANT_Long;
+- case 'F': return CONSTANT_Float;
+- case 'D': return CONSTANT_Double;
+- case 'B': case 'S': case 'C': case 'Z':
+- return CONSTANT_Integer;
+- }
+- assert(false);
+- return CONSTANT_None;
+- }
+- public String prettyString() {
+- String s;
+- if (isMethod()) {
+- s = formRef.stringValue();
+- s = s.substring(0, 1+s.indexOf(')'));
+- } else {
+- s = "/" + formRef.stringValue();
+- }
+- int i;
+- while ((i = s.indexOf(';')) >= 0)
+- s = s.substring(0,i) + s.substring(i+1);
+- return s;
+- }
++ public int computeSize(boolean countDoublesTwice) {
++ String form = formRef.stringValue();
++ int min = 0;
++ int max = 1;
++ if (isMethod()) {
++ min = 1;
++ max = form.indexOf(')');
++ }
++ int size = 0;
++ for (int i = min; i < max; i++) {
++ switch (form.charAt(i)) {
++ case 'D':
++ case 'J':
++ if (countDoublesTwice) size++;
++ break;
++ case '[':
++ // Skip rest of array info.
++ while (form.charAt(i) == '[') ++i;
++ break;
++ case ';':
++ continue;
++ default:
++ assert(0 <= JAVA_SIGNATURE_CHARS.indexOf(form.charAt(i)));
++ break;
++ }
++ size++;
++ }
++ return size;
++ }
++ public boolean isMethod() {
++ return formRef.stringValue().charAt(0) == '(';
++ }
++ public byte getLiteralTag() {
++ switch (formRef.stringValue().charAt(0)) {
++ case 'L': return CONSTANT_String;
++ case 'I': return CONSTANT_Integer;
++ case 'J': return CONSTANT_Long;
++ case 'F': return CONSTANT_Float;
++ case 'D': return CONSTANT_Double;
++ case 'B': case 'S': case 'C': case 'Z':
++ return CONSTANT_Integer;
++ }
++ assert(false);
++ return CONSTANT_None;
++ }
++ public String prettyString() {
++ String s;
++ if (isMethod()) {
++ s = formRef.stringValue();
++ s = s.substring(0, 1+s.indexOf(')'));
++ } else {
++ s = "/" + formRef.stringValue();
++ }
++ int i;
++ while ((i = s.indexOf(';')) >= 0)
++ s = s.substring(0,i) + s.substring(i+1);
++ return s;
++ }
+ }
+
+ static int compareSignatures(String s1, String s2) {
+- return compareSignatures(s1, s2, null, null);
++ return compareSignatures(s1, s2, null, null);
+ }
+ static int compareSignatures(String s1, String s2, String[] p1, String[] p2) {
+- final int S1_COMES_FIRST = -1;
+- final int S2_COMES_FIRST = +1;
+- char c1 = s1.charAt(0);
+- char c2 = s2.charAt(0);
+- // fields before methods (because there are fewer of them)
+- if (c1 != '(' && c2 == '(') return S1_COMES_FIRST;
+- if (c2 != '(' && c1 == '(') return S2_COMES_FIRST;
+- if (p1 == null) p1 = structureSignature(s1);
+- if (p2 == null) p2 = structureSignature(s2);
+- /*
+- // non-classes before classes (because there are fewer of them)
+- if (p1.length == 1 && p2.length > 1) return S1_COMES_FIRST;
+- if (p2.length == 1 && p1.length > 1) return S2_COMES_FIRST;
+- // all else being equal, use the same comparison as for Utf8 strings
+- return s1.compareTo(s2);
+- */
+- if (p1.length != p2.length) return p1.length - p2.length;
+- int length = p1.length;
+- for (int i = length; --i >= 0; ) {
+- int res = p1[i].compareTo(p2[i]);
+- if (res != 0) return res;
+- }
+- assert(s1.equals(s2));
+- return 0;
++ final int S1_COMES_FIRST = -1;
++ final int S2_COMES_FIRST = +1;
++ char c1 = s1.charAt(0);
++ char c2 = s2.charAt(0);
++ // fields before methods (because there are fewer of them)
++ if (c1 != '(' && c2 == '(') return S1_COMES_FIRST;
++ if (c2 != '(' && c1 == '(') return S2_COMES_FIRST;
++ if (p1 == null) p1 = structureSignature(s1);
++ if (p2 == null) p2 = structureSignature(s2);
++ /*
++ // non-classes before classes (because there are fewer of them)
++ if (p1.length == 1 && p2.length > 1) return S1_COMES_FIRST;
++ if (p2.length == 1 && p1.length > 1) return S2_COMES_FIRST;
++ // all else being equal, use the same comparison as for Utf8 strings
++ return s1.compareTo(s2);
++ */
++ if (p1.length != p2.length) return p1.length - p2.length;
++ int length = p1.length;
++ for (int i = length; --i >= 0; ) {
++ int res = p1[i].compareTo(p2[i]);
++ if (res != 0) return res;
++ }
++ assert(s1.equals(s2));
++ return 0;
+ }
+
+ static int countClassParts(Utf8Entry formRef) {
+- int num = 0;
+- String s = formRef.stringValue();
+- for (int i = 0; i < s.length(); i++) {
+- if (s.charAt(i) == 'L') ++num;
+- }
+- return num;
++ int num = 0;
++ String s = formRef.stringValue();
++ for (int i = 0; i < s.length(); i++) {
++ if (s.charAt(i) == 'L') ++num;
++ }
++ return num;
+ }
+
+ static String flattenSignature(String[] parts) {
+- String form = parts[0];
+- if (parts.length == 1) return form;
+- int len = form.length();
+- for (int i = 1; i < parts.length; i++) {
+- len += parts[i].length();
+- }
+- char[] sig = new char[len];
+- int j = 0;
+- int k = 1;
+- for (int i = 0; i < form.length(); i++) {
+- char ch = form.charAt(i);
+- sig[j++] = ch;
+- if (ch == 'L') {
+- String cls = parts[k++];
+- cls.getChars(0, cls.length(), sig, j);
+- j += cls.length();
+- //sig[j++] = ';';
+- }
+- }
+- assert(j == len);
+- assert(k == parts.length);
+- return new String(sig);
++ String form = parts[0];
++ if (parts.length == 1) return form;
++ int len = form.length();
++ for (int i = 1; i < parts.length; i++) {
++ len += parts[i].length();
++ }
++ char[] sig = new char[len];
++ int j = 0;
++ int k = 1;
++ for (int i = 0; i < form.length(); i++) {
++ char ch = form.charAt(i);
++ sig[j++] = ch;
++ if (ch == 'L') {
++ String cls = parts[k++];
++ cls.getChars(0, cls.length(), sig, j);
++ j += cls.length();
++ //sig[j++] = ';';
++ }
++ }
++ assert(j == len);
++ assert(k == parts.length);
++ return new String(sig);
+ }
+
+ static private int skipClassNameChars(String sig, int i) {
+- int len = sig.length();
+- for (; i < len; i++) {
+- char ch = sig.charAt(i);
+- if (ch <= ' ') break;
+- if (ch >= ';' && ch <= '@') break;
+- }
+- return i;
++ int len = sig.length();
++ for (; i < len; i++) {
++ char ch = sig.charAt(i);
++ if (ch <= ' ') break;
++ if (ch >= ';' && ch <= '@') break;
++ }
++ return i;
+ }
+
+ static String[] structureSignature(String sig) {
+- sig = sig.intern();
++ sig = sig.intern();
+
+- int formLen = 0;
+- int nparts = 1;
+- for (int i = 0; i < sig.length(); i++) {
+- char ch = sig.charAt(i);
+- formLen++;
+- if (ch == 'L') {
+- nparts++;
+- int i2 = skipClassNameChars(sig, i+1);
+- i = i2-1; // keep the semicolon in the form
+- int i3 = sig.indexOf('<', i+1);
+- if (i3 > 0 && i3 < i2)
+- i = i3-1;
+- }
+- }
+- char[] form = new char[formLen];
+- if (nparts == 1) {
+- String[] parts = { sig };
+- return parts;
+- }
+- String[] parts = new String[nparts];
+- int j = 0;
+- int k = 1;
+- for (int i = 0; i < sig.length(); i++) {
+- char ch = sig.charAt(i);
+- form[j++] = ch;
+- if (ch == 'L') {
+- int i2 = skipClassNameChars(sig, i+1);
+- parts[k++] = sig.substring(i+1, i2);
+- i = i2;
+- --i; // keep the semicolon in the form
+- }
+- }
+- assert(j == formLen);
+- assert(k == parts.length);
+- parts[0] = new String(form);
+- //assert(flattenSignature(parts).equals(sig));
+- return parts;
++ int formLen = 0;
++ int nparts = 1;
++ for (int i = 0; i < sig.length(); i++) {
++ char ch = sig.charAt(i);
++ formLen++;
++ if (ch == 'L') {
++ nparts++;
++ int i2 = skipClassNameChars(sig, i+1);
++ i = i2-1; // keep the semicolon in the form
++ int i3 = sig.indexOf('<', i+1);
++ if (i3 > 0 && i3 < i2)
++ i = i3-1;
++ }
++ }
++ char[] form = new char[formLen];
++ if (nparts == 1) {
++ String[] parts = { sig };
++ return parts;
++ }
++ String[] parts = new String[nparts];
++ int j = 0;
++ int k = 1;
++ for (int i = 0; i < sig.length(); i++) {
++ char ch = sig.charAt(i);
++ form[j++] = ch;
++ if (ch == 'L') {
++ int i2 = skipClassNameChars(sig, i+1);
++ parts[k++] = sig.substring(i+1, i2);
++ i = i2;
++ --i; // keep the semicolon in the form
++ }
++ }
++ assert(j == formLen);
++ assert(k == parts.length);
++ parts[0] = new String(form);
++ //assert(flattenSignature(parts).equals(sig));
++ return parts;
+ }
+
+ // Handy constants:
+@@ -715,182 +715,182 @@ class ConstantPool implements Constants
+ /** An Index is a mapping between CP entries and small integers. */
+ public static
+ class Index extends AbstractList {
+- protected String debugName;
+- protected Entry[] cpMap;
+- protected boolean flattenSigs;
+- protected Entry[] getMap() {
+- return cpMap;
+- }
+- protected Index(String debugName) {
+- this.debugName = debugName;
+- }
+- protected Index(String debugName, Entry[] cpMap) {
+- this(debugName);
+- setMap(cpMap);
+- }
+- protected void setMap(Entry[] cpMap) {
+- clearIndex();
+- this.cpMap = cpMap;
+- }
+- protected Index(String debugName, Collection cpMapList) {
+- this(debugName);
+- setMap(cpMapList);
+- }
+- protected void setMap(Collection cpMapList) {
+- cpMap = new Entry[cpMapList.size()];
+- cpMapList.toArray(cpMap);
+- setMap(cpMap);
+- }
+- public int size() {
+- return cpMap.length;
+- }
+- public Object get(int i) {
+- return cpMap[i];
+- }
+- public Entry getEntry(int i) {
+- // same as get(), with covariant return type
+- return cpMap[i];
+- }
++ protected String debugName;
++ protected Entry[] cpMap;
++ protected boolean flattenSigs;
++ protected Entry[] getMap() {
++ return cpMap;
++ }
++ protected Index(String debugName) {
++ this.debugName = debugName;
++ }
++ protected Index(String debugName, Entry[] cpMap) {
++ this(debugName);
++ setMap(cpMap);
++ }
++ protected void setMap(Entry[] cpMap) {
++ clearIndex();
++ this.cpMap = cpMap;
++ }
++ protected Index(String debugName, Collection cpMapList) {
++ this(debugName);
++ setMap(cpMapList);
++ }
++ protected void setMap(Collection cpMapList) {
++ cpMap = new Entry[cpMapList.size()];
++ cpMapList.toArray(cpMap);
++ setMap(cpMap);
++ }
++ public int size() {
++ return cpMap.length;
++ }
++ public Object get(int i) {
++ return cpMap[i];
++ }
++ public Entry getEntry(int i) {
++ // same as get(), with covariant return type
++ return cpMap[i];
++ }
+
+- // Find index of e in cpMap, or return -1 if none.
+- //
+- // As a special hack, if flattenSigs, signatures are
+- // treated as equivalent entries of cpMap. This is wrong
+- // fron a Collection point of view, because contains()
+- // reports true for signatures, but the iterator()
+- // never produces them!
+- private int findIndexOf(Entry e) {
+- if (indexKey == null) initializeIndex();
+- int probe = findIndexLocation(e);
+- if (indexKey[probe] != e) {
+- if (flattenSigs && e.tag == CONSTANT_Signature) {
+- SignatureEntry se = (SignatureEntry) e;
+- return findIndexOf(se.asUtf8Entry());
+- }
+- return -1;
+- }
+- int index = indexValue[probe];
+- assert(e.equals(cpMap[index]));
+- return index;
+- }
+- public boolean contains(Entry e) {
+- return findIndexOf(e) >= 0;
+- }
+- // Find index of e in cpMap. Should not return -1.
+- public int indexOf(Entry e) {
+- int index = findIndexOf(e);
+- if (index < 0 && verbose() > 0) {
+- System.out.println("not found: "+e);
+- System.out.println(" in: "+this.dumpString());
+- Thread.dumpStack();
+- }
+- assert(index >= 0);
+- return index;
+- }
+- public boolean contains(Object e) {
+- return findIndexOf((Entry)e) >= 0;
+- }
+- public int indexOf(Object e) {
+- return findIndexOf((Entry)e);
+- }
+- public int lastIndexOf(Object e) {
+- return indexOf(e);
+- }
++ // Find index of e in cpMap, or return -1 if none.
++ //
++ // As a special hack, if flattenSigs, signatures are
++ // treated as equivalent entries of cpMap. This is wrong
++ // fron a Collection point of view, because contains()
++ // reports true for signatures, but the iterator()
++ // never produces them!
++ private int findIndexOf(Entry e) {
++ if (indexKey == null) initializeIndex();
++ int probe = findIndexLocation(e);
++ if (indexKey[probe] != e) {
++ if (flattenSigs && e.tag == CONSTANT_Signature) {
++ SignatureEntry se = (SignatureEntry) e;
++ return findIndexOf(se.asUtf8Entry());
++ }
++ return -1;
++ }
++ int index = indexValue[probe];
++ assert(e.equals(cpMap[index]));
++ return index;
++ }
++ public boolean contains(Entry e) {
++ return findIndexOf(e) >= 0;
++ }
++ // Find index of e in cpMap. Should not return -1.
++ public int indexOf(Entry e) {
++ int index = findIndexOf(e);
++ if (index < 0 && verbose() > 0) {
++ System.out.println("not found: "+e);
++ System.out.println(" in: "+this.dumpString());
++ Thread.dumpStack();
++ }
++ assert(index >= 0);
++ return index;
++ }
++ public boolean contains(Object e) {
++ return findIndexOf((Entry)e) >= 0;
++ }
++ public int indexOf(Object e) {
++ return findIndexOf((Entry)e);
++ }
++ public int lastIndexOf(Object e) {
++ return indexOf(e);
++ }
+
+- public boolean assertIsSorted() {
+- for (int i = 1; i < cpMap.length; i++) {
+- if (cpMap[i-1].compareTo(cpMap[i]) > 0) {
+- System.out.println("Not sorted at "+(i-1)+"/"+i+": "+this.dumpString());
+- return false;
+- }
+- }
+- return true;
+- }
++ public boolean assertIsSorted() {
++ for (int i = 1; i < cpMap.length; i++) {
++ if (cpMap[i-1].compareTo(cpMap[i]) > 0) {
++ System.out.println("Not sorted at "+(i-1)+"/"+i+": "+this.dumpString());
++ return false;
++ }
++ }
++ return true;
++ }
+
+- // internal hash table
+- protected Entry[] indexKey;
+- protected int[] indexValue;
+- protected void clearIndex() {
+- indexKey = null;
+- indexValue = null;
+- }
+- private int findIndexLocation(Entry e) {
+- int size = indexKey.length;
+- int hash = e.hashCode();
+- int probe = hash & (size - 1);
+- int stride = ((hash >>> 8) | 1) & (size - 1);
+- for (;;) {
+- Entry e1 = indexKey[probe];
+- if (e1 == e || e1 == null)
+- return probe;
+- probe += stride;
+- if (probe >= size) probe -= size;
+- }
+- }
+- private void initializeIndex() {
+- if (verbose() > 2)
+- System.out.println("initialize Index "+debugName+" ["+size()+"]");
+- int hsize0 = (int)((cpMap.length + 10) * 1.5);
+- int hsize = 1;
+- while (hsize < hsize0) hsize <<= 1;
+- indexKey = new Entry[hsize];
+- indexValue = new int[hsize];
+- for (int i = 0; i < cpMap.length; i++) {
+- Entry e = cpMap[i];
+- if (e == null) continue;
+- int probe = findIndexLocation(e);
+- assert(indexKey[probe] == null); // e has unique index
+- indexKey[probe] = e;
+- indexValue[probe] = i;
+- }
+- }
+- public Object[] toArray(Object[] a) {
+- int sz = size();
+- if (a.length < sz) return super.toArray(a);
+- System.arraycopy(cpMap, 0, a, 0, sz);
+- if (a.length > sz) a[sz] = null;
+- return a;
+- }
+- public Object[] toArray() {
+- return toArray(new Entry[size()]);
+- }
+- public Object clone() {
+- return new Index(debugName, (Entry[]) cpMap.clone());
+- }
+- public String toString() {
+- return "Index "+debugName+" ["+size()+"]";
+- }
+- public String dumpString() {
+- String s = toString();
+- s += " {\n";
+- for (int i = 0; i < cpMap.length; i++) {
+- s += " "+i+": "+cpMap[i]+"\n";
+- }
+- s += "}";
+- return s;
+- }
++ // internal hash table
++ protected Entry[] indexKey;
++ protected int[] indexValue;
++ protected void clearIndex() {
++ indexKey = null;
++ indexValue = null;
++ }
++ private int findIndexLocation(Entry e) {
++ int size = indexKey.length;
++ int hash = e.hashCode();
++ int probe = hash & (size - 1);
++ int stride = ((hash >>> 8) | 1) & (size - 1);
++ for (;;) {
++ Entry e1 = indexKey[probe];
++ if (e1 == e || e1 == null)
++ return probe;
++ probe += stride;
++ if (probe >= size) probe -= size;
++ }
++ }
++ private void initializeIndex() {
++ if (verbose() > 2)
++ System.out.println("initialize Index "+debugName+" ["+size()+"]");
++ int hsize0 = (int)((cpMap.length + 10) * 1.5);
++ int hsize = 1;
++ while (hsize < hsize0) hsize <<= 1;
++ indexKey = new Entry[hsize];
++ indexValue = new int[hsize];
++ for (int i = 0; i < cpMap.length; i++) {
++ Entry e = cpMap[i];
++ if (e == null) continue;
++ int probe = findIndexLocation(e);
++ assert(indexKey[probe] == null); // e has unique index
++ indexKey[probe] = e;
++ indexValue[probe] = i;
++ }
++ }
++ public Object[] toArray(Object[] a) {
++ int sz = size();
++ if (a.length < sz) return super.toArray(a);
++ System.arraycopy(cpMap, 0, a, 0, sz);
++ if (a.length > sz) a[sz] = null;
++ return a;
++ }
++ public Object[] toArray() {
++ return toArray(new Entry[size()]);
++ }
++ public Object clone() {
++ return new Index(debugName, (Entry[]) cpMap.clone());
++ }
++ public String toString() {
++ return "Index "+debugName+" ["+size()+"]";
++ }
++ public String dumpString() {
++ String s = toString();
++ s += " {\n";
++ for (int i = 0; i < cpMap.length; i++) {
++ s += " "+i+": "+cpMap[i]+"\n";
++ }
++ s += "}";
++ return s;
++ }
+ }
+
+ // Index methods.
+
+ public static
+ Index makeIndex(String debugName, Entry[] cpMap) {
+- return new Index(debugName, cpMap);
++ return new Index(debugName, cpMap);
+ }
+
+ public static
+ Index makeIndex(String debugName, Collection cpMapList) {
+- return new Index(debugName, cpMapList);
++ return new Index(debugName, cpMapList);
+ }
+
+ /** Sort this index (destructively) into canonical order. */
+ public static
+ void sort(Index ix) {
+- // %%% Should move this into class Index.
+- ix.clearIndex();
+- Arrays.sort(ix.cpMap);
+- if (verbose() > 2)
+- System.out.println("sorted "+ix.dumpString());
++ // %%% Should move this into class Index.
++ ix.clearIndex();
++ Arrays.sort(ix.cpMap);
++ if (verbose() > 2)
++ System.out.println("sorted "+ix.dumpString());
+ }
+
+ /** Return a set of indexes partitioning these entries.
+@@ -900,210 +900,212 @@ class ConstantPool implements Constants
+ */
+ public static
+ Index[] partition(Index ix, int[] keys) {
+- // %%% Should move this into class Index.
+- ArrayList parts = new ArrayList();
+- Entry[] cpMap = ix.cpMap;
+- assert(keys.length == cpMap.length);
+- for (int i = 0; i < keys.length; i++) {
+- int key = keys[i];
+- if (key < 0) continue;
+- while (key >= parts.size()) parts.add(null);
+- ArrayList part = (ArrayList) parts.get(key);
+- if (part == null) {
+- parts.set(key, part = new ArrayList());
+- }
+- part.add(cpMap[i]);
+- }
+- Index[] indexes = new Index[parts.size()];
+- for (int key = 0; key < indexes.length; key++) {
+- ArrayList part = (ArrayList) parts.get(key);
+- if (part == null) continue;
+- indexes[key] = new Index(ix.debugName+"/part#"+key, part);
+- assert(indexes[key].indexOf(part.get(0)) == 0);
+- }
+- return indexes;
++ // %%% Should move this into class Index.
++ ArrayList parts = new ArrayList();
++ Entry[] cpMap = ix.cpMap;
++ assert(keys.length == cpMap.length);
++ for (int i = 0; i < keys.length; i++) {
++ int key = keys[i];
++ if (key < 0) continue;
++ while (key >= parts.size()) parts.add(null);
++ ArrayList part = (ArrayList) parts.get(key);
++ if (part == null) {
++ parts.set(key, part = new ArrayList());
++ }
++ part.add(cpMap[i]);
++ }
++ Index[] indexes = new Index[parts.size()];
++ for (int key = 0; key < indexes.length; key++) {
++ ArrayList part = (ArrayList) parts.get(key);
++ if (part == null) continue;
++ indexes[key] = new Index(ix.debugName+"/part#"+key, part);
++ assert(indexes[key].indexOf(part.get(0)) == 0);
++ }
++ return indexes;
+ }
+ public static
+ Index[] partitionByTag(Index ix) {
+- // Partition by tag.
+- Entry[] cpMap = ix.cpMap;
+- int[] keys = new int[cpMap.length];
+- for (int i = 0; i < keys.length; i++) {
+- Entry e = cpMap[i];
+- keys[i] = (e == null)? -1: e.tag;
+- }
+- Index[] byTag = partition(ix, keys);
+- for (int tag = 0; tag < byTag.length; tag++) {
+- if (byTag[tag] == null) continue;
+- byTag[tag].debugName = tagName(tag);
+- }
+- if (byTag.length < CONSTANT_Limit) {
+- Index[] longer = new Index[CONSTANT_Limit];
+- System.arraycopy(byTag, 0, longer, 0, byTag.length);
+- byTag = longer;
+- }
+- return byTag;
++ // Partition by tag.
++ Entry[] cpMap = ix.cpMap;
++ int[] keys = new int[cpMap.length];
++ for (int i = 0; i < keys.length; i++) {
++ Entry e = cpMap[i];
++ keys[i] = (e == null)? -1: e.tag;
++ }
++ Index[] byTag = partition(ix, keys);
++ for (int tag = 0; tag < byTag.length; tag++) {
++ if (byTag[tag] == null) continue;
++ byTag[tag].debugName = tagName(tag);
++ }
++ if (byTag.length < CONSTANT_Limit) {
++ Index[] longer = new Index[CONSTANT_Limit];
++ System.arraycopy(byTag, 0, longer, 0, byTag.length);
++ byTag = longer;
++ }
++ return byTag;
+ }
+
+ /** Coherent group of constant pool indexes. */
+ public static
+ class IndexGroup {
+- private Index indexUntyped;
+- private Index[] indexByTag = new Index[CONSTANT_Limit];
+- private int[] untypedFirstIndexByTag;
+- private int totalSize;
+- private Index[][] indexByTagAndClass;
++ private Index indexUntyped;
++ private Index[] indexByTag = new Index[CONSTANT_Limit];
++ private int[] untypedFirstIndexByTag;
++ private int totalSize;
++ private Index[][] indexByTagAndClass;
+
+- /** Index of all CP entries of all types, in definition order. */
+- public Index getUntypedIndex() {
+- if (indexUntyped == null) {
+- untypedIndexOf(null); // warm up untypedFirstIndexByTag
+- Entry[] cpMap = new Entry[totalSize];
+- for (int tag = 0; tag < indexByTag.length; tag++) {
+- Index ix = indexByTag[tag];
+- if (ix == null) continue;
+- int ixLen = ix.cpMap.length;
+- if (ixLen == 0) continue;
+- int fillp = untypedFirstIndexByTag[tag];
+- assert(cpMap[fillp] == null);
+- assert(cpMap[fillp+ixLen-1] == null);
+- System.arraycopy(ix.cpMap, 0, cpMap, fillp, ixLen);
+- }
+- indexUntyped = new Index("untyped", cpMap);
+- }
+- return indexUntyped;
+- }
++ /** Index of all CP entries of all types, in definition order. */
++ public Index getUntypedIndex() {
++ if (indexUntyped == null) {
++ untypedIndexOf(null); // warm up untypedFirstIndexByTag
++ Entry[] cpMap = new Entry[totalSize];
++ for (int tag = 0; tag < indexByTag.length; tag++) {
++ Index ix = indexByTag[tag];
++ if (ix == null) continue;
++ int ixLen = ix.cpMap.length;
++ if (ixLen == 0) continue;
++ int fillp = untypedFirstIndexByTag[tag];
++ assert(cpMap[fillp] == null);
++ assert(cpMap[fillp+ixLen-1] == null);
++ System.arraycopy(ix.cpMap, 0, cpMap, fillp, ixLen);
++ }
++ indexUntyped = new Index("untyped", cpMap);
++ }
++ return indexUntyped;
++ }
+
+- public int untypedIndexOf(Entry e) {
+- if (untypedFirstIndexByTag == null) {
+- untypedFirstIndexByTag = new int[CONSTANT_Limit];
+- int fillp = 0;
+- for (int i = 0; i < TAGS_IN_ORDER.length; i++) {
+- byte tag = TAGS_IN_ORDER[i];
+- Index ix = indexByTag[tag];
+- if (ix == null) continue;
+- int ixLen = ix.cpMap.length;
+- untypedFirstIndexByTag[tag] = fillp;
+- fillp += ixLen;
+- }
+- totalSize = fillp;
+- }
+- if (e == null) return -1;
+- int tag = e.tag;
+- Index ix = indexByTag[tag];
+- if (ix == null) return -1;
+- int idx = ix.findIndexOf(e);
+- if (idx >= 0)
+- idx += untypedFirstIndexByTag[tag];
+- return idx;
+- }
++ public int untypedIndexOf(Entry e) {
++ if (untypedFirstIndexByTag == null) {
++ untypedFirstIndexByTag = new int[CONSTANT_Limit];
++ int fillp = 0;
++ for (int i = 0; i < TAGS_IN_ORDER.length; i++) {
++ byte tag = TAGS_IN_ORDER[i];
++ Index ix = indexByTag[tag];
++ if (ix == null) continue;
++ int ixLen = ix.cpMap.length;
++ untypedFirstIndexByTag[tag] = fillp;
++ fillp += ixLen;
++ }
++ totalSize = fillp;
++ }
++ if (e == null) return -1;
++ int tag = e.tag;
++ Index ix = indexByTag[tag];
++ if (ix == null) return -1;
++ int idx = ix.findIndexOf(e);
++ if (idx >= 0)
++ idx += untypedFirstIndexByTag[tag];
++ return idx;
++ }
+
+- public void initIndexByTag(byte tag, Index ix) {
+- assert(indexByTag[tag] == null); // do not init twice
+- Entry[] cpMap = ix.cpMap;
+- for (int i = 0; i < cpMap.length; i++) {
+- // It must be a homogeneous Entry set.
+- assert(cpMap[i].tag == tag);
+- }
+- if (tag == CONSTANT_Utf8) {
+- // Special case: First Utf8 must always be empty string.
+- assert(cpMap.length == 0 || cpMap[0].stringValue().equals(""));
+- }
+- indexByTag[tag] = ix;
+- // decache indexes derived from this one:
+- untypedFirstIndexByTag = null;
+- indexUntyped = null;
+- if (indexByTagAndClass != null)
+- indexByTagAndClass[tag] = null;
+- }
++ public void initIndexByTag(byte tag, Index ix) {
++ assert(indexByTag[tag] == null); // do not init twice
++ Entry[] cpMap = ix.cpMap;
++ for (int i = 0; i < cpMap.length; i++) {
++ // It must be a homogeneous Entry set.
++ assert(cpMap[i].tag == tag);
++ }
++ if (tag == CONSTANT_Utf8) {
++ // Special case: First Utf8 must always be empty string.
++ assert(cpMap.length == 0 || cpMap[0].stringValue().equals(""));
++ }
++ indexByTag[tag] = ix;
++ // decache indexes derived from this one:
++ untypedFirstIndexByTag = null;
++ indexUntyped = null;
++ if (indexByTagAndClass != null)
++ indexByTagAndClass[tag] = null;
++ }
+
+- /** Index of all CP entries of a given tag. */
+- public Index getIndexByTag(byte tag) {
+- if (tag == CONSTANT_All) {
+- return getUntypedIndex();
+- }
+- Index ix = indexByTag[tag];
+- if (ix == null) {
+- // Make an empty one by default.
+- ix = new Index(tagName(tag), new Entry[0]);
+- indexByTag[tag] = ix;
+- }
+- return ix;
+- }
++ /** Index of all CP entries of a given tag. */
++ public Index getIndexByTag(byte tag) {
++ if (tag == CONSTANT_All) {
++ return getUntypedIndex();
++ }
++ Index ix = indexByTag[tag];
++ if (ix == null) {
++ // Make an empty one by default.
++ ix = new Index(tagName(tag), new Entry[0]);
++ indexByTag[tag] = ix;
++ }
++ return ix;
++ }
+
+- /** Index of all CP entries of a given tag and class. */
+- public Index getMemberIndex(byte tag, ClassEntry classRef) {
+- if (indexByTagAndClass == null)
+- indexByTagAndClass = new Index[CONSTANT_Limit][];
+- Index allClasses = getIndexByTag(CONSTANT_Class);
+- Index[] perClassIndexes = indexByTagAndClass[tag];
+- if (perClassIndexes == null) {
+- // Create the partition now.
+- // Divide up all entries of the given tag according to their class.
+- Index allMembers = getIndexByTag(tag);
+- int[] whichClasses = new int[allMembers.size()];
+- for (int i = 0; i < whichClasses.length; i++) {
+- MemberEntry e = (MemberEntry) allMembers.get(i);
+- int whichClass = allClasses.indexOf(e.classRef);
+- whichClasses[i] = whichClass;
+- }
+- perClassIndexes = partition(allMembers, whichClasses);
+- for (int i = 0; i < perClassIndexes.length; i++)
+- assert(perClassIndexes[i]==null
+- || perClassIndexes[i].assertIsSorted());
+- indexByTagAndClass[tag] = perClassIndexes;
+- }
+- int whichClass = allClasses.indexOf(classRef);
+- return perClassIndexes[whichClass];
+- }
++ /** Index of all CP entries of a given tag and class. */
++ public Index getMemberIndex(byte tag, ClassEntry classRef) {
++ if (classRef == null)
++ throw new RuntimeException("missing class reference for " + tagName(tag));
++ if (indexByTagAndClass == null)
++ indexByTagAndClass = new Index[CONSTANT_Limit][];
++ Index allClasses = getIndexByTag(CONSTANT_Class);
++ Index[] perClassIndexes = indexByTagAndClass[tag];
++ if (perClassIndexes == null) {
++ // Create the partition now.
++ // Divide up all entries of the given tag according to their class.
++ Index allMembers = getIndexByTag(tag);
++ int[] whichClasses = new int[allMembers.size()];
++ for (int i = 0; i < whichClasses.length; i++) {
++ MemberEntry e = (MemberEntry) allMembers.get(i);
++ int whichClass = allClasses.indexOf(e.classRef);
++ whichClasses[i] = whichClass;
++ }
++ perClassIndexes = partition(allMembers, whichClasses);
++ for (int i = 0; i < perClassIndexes.length; i++)
++ assert(perClassIndexes[i]==null
++ || perClassIndexes[i].assertIsSorted());
++ indexByTagAndClass[tag] = perClassIndexes;
++ }
++ int whichClass = allClasses.indexOf(classRef);
++ return perClassIndexes[whichClass];
++ }
+
+- // Given the sequence of all methods of the given name and class,
+- // produce the ordinal of this particular given overloading.
+- public int getOverloadingIndex(MemberEntry methodRef) {
+- Index ix = getMemberIndex(methodRef.tag, methodRef.classRef);
+- Utf8Entry nameRef = methodRef.descRef.nameRef;
+- int ord = 0;
+- for (int i = 0; i < ix.cpMap.length; i++) {
+- MemberEntry e = (MemberEntry) ix.cpMap[i];
+- if (e.equals(methodRef))
+- return ord;
+- if (e.descRef.nameRef.equals(nameRef))
+- // Found a different overloading. Increment the ordinal.
+- ord++;
+- }
+- throw new RuntimeException("should not reach here");
+- }
++ // Given the sequence of all methods of the given name and class,
++ // produce the ordinal of this particular given overloading.
++ public int getOverloadingIndex(MemberEntry methodRef) {
++ Index ix = getMemberIndex(methodRef.tag, methodRef.classRef);
++ Utf8Entry nameRef = methodRef.descRef.nameRef;
++ int ord = 0;
++ for (int i = 0; i < ix.cpMap.length; i++) {
++ MemberEntry e = (MemberEntry) ix.cpMap[i];
++ if (e.equals(methodRef))
++ return ord;
++ if (e.descRef.nameRef.equals(nameRef))
++ // Found a different overloading. Increment the ordinal.
++ ord++;
++ }
++ throw new RuntimeException("should not reach here");
++ }
+
+- // Inverse of getOverloadingIndex
+- public MemberEntry getOverloadingForIndex(byte tag, ClassEntry classRef, String name, int which) {
+- assert(name == name.intern());
+- Index ix = getMemberIndex(tag, classRef);
+- int ord = 0;
+- for (int i = 0; i < ix.cpMap.length; i++) {
+- MemberEntry e = (MemberEntry) ix.cpMap[i];
+- if (e.descRef.nameRef.stringValue() == name) {
+- if (ord == which) return e;
+- ord++;
+- }
+- }
+- throw new RuntimeException("should not reach here");
+- }
++ // Inverse of getOverloadingIndex
++ public MemberEntry getOverloadingForIndex(byte tag, ClassEntry classRef, String name, int which) {
++ assert(name == name.intern());
++ Index ix = getMemberIndex(tag, classRef);
++ int ord = 0;
++ for (int i = 0; i < ix.cpMap.length; i++) {
++ MemberEntry e = (MemberEntry) ix.cpMap[i];
++ if (e.descRef.nameRef.stringValue() == name) {
++ if (ord == which) return e;
++ ord++;
++ }
++ }
++ throw new RuntimeException("should not reach here");
++ }
+
+- public boolean haveNumbers() {
+- for (byte tag = CONSTANT_Integer; tag <= CONSTANT_Double; tag++) {
+- switch (tag) {
+- case CONSTANT_Integer:
+- case CONSTANT_Float:
+- case CONSTANT_Long:
+- case CONSTANT_Double:
+- break;
+- default:
+- assert(false);
+- }
+- if (getIndexByTag(tag).size() > 0) return true;
+- }
+- return false;
+- }
++ public boolean haveNumbers() {
++ for (byte tag = CONSTANT_Integer; tag <= CONSTANT_Double; tag++) {
++ switch (tag) {
++ case CONSTANT_Integer:
++ case CONSTANT_Float:
++ case CONSTANT_Long:
++ case CONSTANT_Double:
++ break;
++ default:
++ assert(false);
++ }
++ if (getIndexByTag(tag).size() > 0) return true;
++ }
++ return false;
++ }
+
+ }
+
+@@ -1114,84 +1116,84 @@ class ConstantPool implements Constants
+ */
+ public static
+ void completeReferencesIn(Set cpRefs, boolean flattenSigs) {
+- cpRefs.remove(null);
+- for (ListIterator work =
+- new ArrayList(cpRefs).listIterator(cpRefs.size());
+- work.hasPrevious(); ) {
+- Entry e = (Entry) work.previous();
+- work.remove(); // pop stack
+- assert(e != null);
+- if (flattenSigs && e.tag == CONSTANT_Signature) {
+- SignatureEntry se = (SignatureEntry) e;
+- Utf8Entry ue = se.asUtf8Entry();
+- // Totally replace e by se.
+- cpRefs.remove(se);
+- cpRefs.add(ue);
+- e = ue; // do not descend into the sig
+- }
+- // Recursively add the refs of e to cpRefs:
+- for (int i = 0; ; i++) {
+- Entry re = e.getRef(i);
+- if (re == null)
+- break; // no more refs in e
+- if (cpRefs.add(re)) // output the ref
+- work.add(re); // push stack, if a new ref
+- }
+- }
++ cpRefs.remove(null);
++ for (ListIterator work =
++ new ArrayList(cpRefs).listIterator(cpRefs.size());
++ work.hasPrevious(); ) {
++ Entry e = (Entry) work.previous();
++ work.remove(); // pop stack
++ assert(e != null);
++ if (flattenSigs && e.tag == CONSTANT_Signature) {
++ SignatureEntry se = (SignatureEntry) e;
++ Utf8Entry ue = se.asUtf8Entry();
++ // Totally replace e by se.
++ cpRefs.remove(se);
++ cpRefs.add(ue);
++ e = ue; // do not descend into the sig
++ }
++ // Recursively add the refs of e to cpRefs:
++ for (int i = 0; ; i++) {
++ Entry re = e.getRef(i);
++ if (re == null)
++ break; // no more refs in e
++ if (cpRefs.add(re)) // output the ref
++ work.add(re); // push stack, if a new ref
++ }
++ }
+ }
+
+ static double percent(int num, int den) {
+- return (int)((10000.0*num)/den + 0.5) / 100.0;
++ return (int)((10000.0*num)/den + 0.5) / 100.0;
+ }
+
+ public static String tagName(int tag) {
+- switch (tag) {
+- case CONSTANT_Utf8: return "Utf8";
+- case CONSTANT_Integer: return "Integer";
+- case CONSTANT_Float: return "Float";
+- case CONSTANT_Long: return "Long";
+- case CONSTANT_Double: return "Double";
+- case CONSTANT_Class: return "Class";
+- case CONSTANT_String: return "String";
+- case CONSTANT_Fieldref: return "Fieldref";
+- case CONSTANT_Methodref: return "Methodref";
+- case CONSTANT_InterfaceMethodref: return "InterfaceMethodref";
+- case CONSTANT_NameandType: return "NameandType";
++ switch (tag) {
++ case CONSTANT_Utf8: return "Utf8";
++ case CONSTANT_Integer: return "Integer";
++ case CONSTANT_Float: return "Float";
++ case CONSTANT_Long: return "Long";
++ case CONSTANT_Double: return "Double";
++ case CONSTANT_Class: return "Class";
++ case CONSTANT_String: return "String";
++ case CONSTANT_Fieldref: return "Fieldref";
++ case CONSTANT_Methodref: return "Methodref";
++ case CONSTANT_InterfaceMethodref: return "InterfaceMethodref";
++ case CONSTANT_NameandType: return "NameandType";
+
+- // pseudo-tags:
+- case CONSTANT_All: return "*All";
+- case CONSTANT_None: return "*None";
+- case CONSTANT_Signature: return "*Signature";
+- }
+- return "tag#"+tag;
++ // pseudo-tags:
++ case CONSTANT_All: return "*All";
++ case CONSTANT_None: return "*None";
++ case CONSTANT_Signature: return "*Signature";
++ }
++ return "tag#"+tag;
+ }
+
+ // archive constant pool definition order
+ static final byte TAGS_IN_ORDER[] = {
+- CONSTANT_Utf8,
+- CONSTANT_Integer, // cp_Int
+- CONSTANT_Float,
+- CONSTANT_Long,
+- CONSTANT_Double,
+- CONSTANT_String,
+- CONSTANT_Class,
+- CONSTANT_Signature,
+- CONSTANT_NameandType, // cp_Descr
+- CONSTANT_Fieldref, // cp_Field
+- CONSTANT_Methodref, // cp_Method
+- CONSTANT_InterfaceMethodref // cp_Imethod
++ CONSTANT_Utf8,
++ CONSTANT_Integer, // cp_Int
++ CONSTANT_Float,
++ CONSTANT_Long,
++ CONSTANT_Double,
++ CONSTANT_String,
++ CONSTANT_Class,
++ CONSTANT_Signature,
++ CONSTANT_NameandType, // cp_Descr
++ CONSTANT_Fieldref, // cp_Field
++ CONSTANT_Methodref, // cp_Method
++ CONSTANT_InterfaceMethodref // cp_Imethod
+ };
+ static final byte TAG_ORDER[];
+ static {
+- TAG_ORDER = new byte[CONSTANT_Limit];
+- for (int i = 0; i < TAGS_IN_ORDER.length; i++) {
+- TAG_ORDER[TAGS_IN_ORDER[i]] = (byte)(i+1);
+- }
+- /*
+- System.out.println("TAG_ORDER[] = {");
+- for (int i = 0; i < TAG_ORDER.length; i++)
+- System.out.println(" "+TAG_ORDER[i]+",");
+- System.out.println("};");
+- */
++ TAG_ORDER = new byte[CONSTANT_Limit];
++ for (int i = 0; i < TAGS_IN_ORDER.length; i++) {
++ TAG_ORDER[TAGS_IN_ORDER[i]] = (byte)(i+1);
++ }
++ /*
++ System.out.println("TAG_ORDER[] = {");
++ for (int i = 0; i < TAG_ORDER.length; i++)
++ System.out.println(" "+TAG_ORDER[i]+",");
++ System.out.println("};");
++ */
+ }
+ }
+diff --git a/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java b/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java
+--- jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java
++++ jdk/src/share/classes/com/sun/java/util/jar/pack/NativeUnpack.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -22,7 +22,6 @@
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-
+
+ package com.sun.java.util.jar.pack;
+
+@@ -81,239 +80,246 @@ class NativeUnpack {
+ private PropMap _props;
+
+ static {
+- // If loading from stand alone build uncomment this.
+- // System.loadLibrary("unpack");
+- java.security.AccessController.doPrivileged(
+- new sun.security.action.LoadLibraryAction("unpack"));
+- initIDs();
++ // If loading from stand alone build uncomment this.
++ // System.loadLibrary("unpack");
++ java.security.AccessController.doPrivileged(
++ new sun.security.action.LoadLibraryAction("unpack"));
++ initIDs();
+ }
+-
++
+ NativeUnpack(UnpackerImpl p200) {
+- super();
+- _p200 = p200;
+- _props = p200._props;
+- p200._nunp = this;
++ super();
++ _p200 = p200;
++ _props = p200._props;
++ p200._nunp = this;
+ }
+
+ // for JNI callbacks
+ static private Object currentInstance() {
+- UnpackerImpl p200 = (UnpackerImpl) Utils.currentInstance.get();
+- return (p200 == null)? null: p200._nunp;
++ UnpackerImpl p200 = (UnpackerImpl) Utils.currentInstance.get();
++ return (p200 == null)? null: p200._nunp;
++ }
++
++ private synchronized long getUnpackerPtr() {
++ return unpackerPtr;
+ }
+
+ // Callback from the unpacker engine to get more data.
+ private long readInputFn(ByteBuffer pbuf, long minlen) throws IOException {
+- if (in == null) return 0; // nothing is readable
+- long maxlen = pbuf.capacity() - pbuf.position();
+- assert(minlen <= maxlen); // don't talk nonsense
+- long numread = 0;
+- int steps = 0;
+- while (numread < minlen) {
+- steps++;
+- // read available input, up to buf.length or maxlen
+- int readlen = _buf.length;
+- if (readlen > (maxlen - numread))
+- readlen = (int)(maxlen - numread);
+- int nr = in.read(_buf, 0, readlen);
+- if (nr <= 0) break;
+- numread += nr;
+- assert(numread <= maxlen);
+- // %%% get rid of this extra copy by using nio?
+- pbuf.put(_buf, 0, nr);
+- }
+- if (_verbose > 1)
+- Utils.log.fine("readInputFn("+minlen+","+maxlen+") => "+numread+" steps="+steps);
+- if (maxlen > 100) {
+- _estByteLimit = _byteCount + maxlen;
+- } else {
+- _estByteLimit = (_byteCount + numread) * 20;
+- }
+- _byteCount += numread;
+- updateProgress();
+- return numread;
++ if (in == null) return 0; // nothing is readable
++ long maxlen = pbuf.capacity() - pbuf.position();
++ assert(minlen <= maxlen); // don't talk nonsense
++ long numread = 0;
++ int steps = 0;
++ while (numread < minlen) {
++ steps++;
++ // read available input, up to buf.length or maxlen
++ int readlen = _buf.length;
++ if (readlen > (maxlen - numread))
++ readlen = (int)(maxlen - numread);
++ int nr = in.read(_buf, 0, readlen);
++ if (nr <= 0) break;
++ numread += nr;
++ assert(numread <= maxlen);
++ // %%% get rid of this extra copy by using nio?
++ pbuf.put(_buf, 0, nr);
++ }
++ if (_verbose > 1)
++ Utils.log.fine("readInputFn("+minlen+","+maxlen+") => "+numread+" steps="+steps);
++ if (maxlen > 100) {
++ _estByteLimit = _byteCount + maxlen;
++ } else {
++ _estByteLimit = (_byteCount + numread) * 20;
++ }
++ _byteCount += numread;
++ updateProgress();
++ return numread;
+ }
+
+ private void updateProgress() {
+- // Progress is a combination of segment reading and file writing.
+- final double READ_WT = 0.33;
+- final double WRITE_WT = 0.67;
+- double readProgress = _segCount;
+- if (_estByteLimit > 0 && _byteCount > 0)
+- readProgress += (double)_byteCount / _estByteLimit;
+- double writeProgress = _fileCount;
+- double scaledProgress
+- = READ_WT * readProgress / Math.max(_estSegLimit,1)
+- + WRITE_WT * writeProgress / Math.max(_estFileLimit,1);
+- int percent = (int) Math.round(100*scaledProgress);
+- if (percent > 100) percent = 100;
+- if (percent > _prevPercent) {
+- _prevPercent = percent;
+- _props.setInteger(Pack200.Unpacker.PROGRESS, percent);
+- if (_verbose > 0)
+- Utils.log.info("progress = "+percent);
+- }
++ // Progress is a combination of segment reading and file writing.
++ final double READ_WT = 0.33;
++ final double WRITE_WT = 0.67;
++ double readProgress = _segCount;
++ if (_estByteLimit > 0 && _byteCount > 0)
++ readProgress += (double)_byteCount / _estByteLimit;
++ double writeProgress = _fileCount;
++ double scaledProgress
++ = READ_WT * readProgress / Math.max(_estSegLimit,1)
++ + WRITE_WT * writeProgress / Math.max(_estFileLimit,1);
++ int percent = (int) Math.round(100*scaledProgress);
++ if (percent > 100) percent = 100;
++ if (percent > _prevPercent) {
++ _prevPercent = percent;
++ _props.setInteger(Pack200.Unpacker.PROGRESS, percent);
++ if (_verbose > 0)
++ Utils.log.info("progress = "+percent);
++ }
+ }
+
+ private void copyInOption(String opt) {
+- String val = _props.getProperty(opt);
+- if (_verbose > 0)
+- Utils.log.info("set "+opt+"="+val);
+- if (val != null) {
+- boolean set = setOption(opt, val);
+- if (!set)
+- Utils.log.warning("Invalid option "+opt+"="+val);
+- }
++ String val = _props.getProperty(opt);
++ if (_verbose > 0)
++ Utils.log.info("set "+opt+"="+val);
++ if (val != null) {
++ boolean set = setOption(opt, val);
++ if (!set)
++ Utils.log.warning("Invalid option "+opt+"="+val);
++ }
+ }
+
+ void run(InputStream inRaw, JarOutputStream jstream,
+- ByteBuffer presetInput) throws IOException {
+- BufferedInputStream in = new BufferedInputStream(inRaw);
+- this.in = in; // for readInputFn to see
+- _verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
+- // Fix for BugId: 4902477, -unpack.modification.time = 1059010598000
++ ByteBuffer presetInput) throws IOException {
++ BufferedInputStream in = new BufferedInputStream(inRaw);
++ this.in = in; // for readInputFn to see
++ _verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
++ // Fix for BugId: 4902477, -unpack.modification.time = 1059010598000
+ // TODO eliminate and fix in unpack.cpp
++
++ final int modtime = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, "0")) ?
++ Constants.NO_MODTIME : _props.getTime(Utils.UNPACK_MODIFICATION_TIME);
+
+- final int modtime = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, "0")) ?
+- Constants.NO_MODTIME : _props.getTime(Utils.UNPACK_MODIFICATION_TIME);
++ copyInOption(Utils.DEBUG_VERBOSE);
++ copyInOption(Pack200.Unpacker.DEFLATE_HINT);
++ if (modtime == Constants.NO_MODTIME) // Dont pass KEEP && NOW
++ copyInOption(Utils.UNPACK_MODIFICATION_TIME);
++ updateProgress(); // reset progress bar
++ for (;;) {
++ // Read the packed bits.
++ long counts = start(presetInput, 0);
++ _byteCount = _estByteLimit = 0; // reset partial scan counts
++ ++_segCount; // just finished scanning a whole segment...
++ int nextSeg = (int)( counts >>> 32 );
++ int nextFile = (int)( counts >>> 0 );
+
+- copyInOption(Utils.DEBUG_VERBOSE);
+- copyInOption(Pack200.Unpacker.DEFLATE_HINT);
+- if (modtime == Constants.NO_MODTIME) // Dont pass KEEP && NOW
+- copyInOption(Utils.UNPACK_MODIFICATION_TIME);
+- updateProgress(); // reset progress bar
+- for (;;) {
+- // Read the packed bits.
+- long counts = start(presetInput, 0);
+- _byteCount = _estByteLimit = 0; // reset partial scan counts
+- ++_segCount; // just finished scanning a whole segment...
+- int nextSeg = (int)( counts >>> 32 );
+- int nextFile = (int)( counts >>> 0 );
++ // Estimate eventual total number of segments and files.
++ _estSegLimit = _segCount + nextSeg;
++ double filesAfterThisSeg = _fileCount + nextFile;
++ _estFileLimit = (int)( (filesAfterThisSeg *
++ _estSegLimit) / _segCount );
+
+- // Estimate eventual total number of segments and files.
+- _estSegLimit = _segCount + nextSeg;
+- double filesAfterThisSeg = _fileCount + nextFile;
+- _estFileLimit = (int)( (filesAfterThisSeg *
+- _estSegLimit) / _segCount );
++ // Write the files.
++ int[] intParts = { 0,0, 0, 0 };
++ // intParts = {size.hi/lo, mod, defl}
++ Object[] parts = { intParts, null, null, null };
++ // parts = { {intParts}, name, data0/1 }
++ while (getNextFile(parts)) {
++ //BandStructure.printArrayTo(System.out, intParts, 0, parts.length);
++ String name = (String) parts[1];
++ long size = ( (long)intParts[0] << 32)
++ + (((long)intParts[1] << 32) >>> 32);
+
+- // Write the files.
+- int[] intParts = { 0,0, 0, 0 };
+- // intParts = {size.hi/lo, mod, defl}
+- Object[] parts = { intParts, null, null, null };
+- // parts = { {intParts}, name, data0/1 }
+- while (getNextFile(parts)) {
+- //BandStructure.printArrayTo(System.out, intParts, 0, parts.length);
+- String name = (String) parts[1];
+- long size = ( (long)intParts[0] << 32)
+- + (((long)intParts[1] << 32) >>> 32);
+-
+- long mtime = (modtime != Constants.NO_MODTIME ) ?
+- modtime : intParts[2] ;
+- boolean deflateHint = (intParts[3] != 0);
+- ByteBuffer data0 = (ByteBuffer) parts[2];
+- ByteBuffer data1 = (ByteBuffer) parts[3];
+- writeEntry(jstream, name, mtime, size, deflateHint,
+- data0, data1);
+- ++_fileCount;
+- updateProgress();
+- }
+- long consumed = finish();
+- if (_verbose > 0)
+- Utils.log.info("bytes consumed = "+consumed);
+- presetInput = getUnusedInput();
+- if (presetInput == null &&
+- !Utils.isPackMagic(Utils.readMagic(in))) {
+- break;
+- }
+- if (_verbose > 0 ) {
+- if (presetInput != null)
+- Utils.log.info("unused input = "+presetInput);
+- }
+- }
++ long mtime = (modtime != Constants.NO_MODTIME ) ?
++ modtime : intParts[2] ;
++ boolean deflateHint = (intParts[3] != 0);
++ ByteBuffer data0 = (ByteBuffer) parts[2];
++ ByteBuffer data1 = (ByteBuffer) parts[3];
++ writeEntry(jstream, name, mtime, size, deflateHint,
++ data0, data1);
++ ++_fileCount;
++ updateProgress();
++ }
++ long consumed = finish();
++ if (_verbose > 0)
++ Utils.log.info("bytes consumed = "+consumed);
++ presetInput = getUnusedInput();
++ if (presetInput == null &&
++ !Utils.isPackMagic(Utils.readMagic(in))) {
++ break;
++ }
++ if (_verbose > 0 ) {
++ if (presetInput != null)
++ Utils.log.info("unused input = "+presetInput);
++ }
++ }
+ }
+
+ void run(InputStream in, JarOutputStream jstream) throws IOException {
+- run(in, jstream, null);
++ run(in, jstream, null);
+ }
+
+ void run(File inFile, JarOutputStream jstream) throws IOException {
+- // %%% maybe memory-map the file, and pass it straight into unpacker
+- ByteBuffer mappedFile = null;
+- FileInputStream fis = new FileInputStream(inFile);
+- run(fis, jstream, mappedFile);
+- fis.close();
+- // Note: caller is responsible to finish with jstream.
++ // %%% maybe memory-map the file, and pass it straight into unpacker
++ ByteBuffer mappedFile = null;
++ FileInputStream fis = new FileInputStream(inFile);
++ run(fis, jstream, mappedFile);
++ fis.close();
++ // Note: caller is responsible to finish with jstream.
+ }
++
++ private void writeEntry(JarOutputStream j, String name,
++ long mtime, long lsize, boolean deflateHint,
++ ByteBuffer data0, ByteBuffer data1) throws IOException {
++ int size = (int)lsize;
++ if (size != lsize)
++ throw new IOException("file too large: "+lsize);
+
+- private void writeEntry(JarOutputStream j, String name,
+- long mtime, long lsize, boolean deflateHint,
+- ByteBuffer data0, ByteBuffer data1) throws IOException {
+- int size = (int)lsize;
+- if (size != lsize)
+- throw new IOException("file too large: "+lsize);
++ CRC32 crc32 = _crc32;
+
+- CRC32 crc32 = _crc32;
++ if (_verbose > 1)
++ Utils.log.fine("Writing entry: "+name+" size="+size
++ +(deflateHint?" deflated":""));
+
+- if (_verbose > 1)
+- Utils.log.fine("Writing entry: "+name+" size="+size
+- +(deflateHint?" deflated":""));
++ if (_buf.length < size) {
++ int newSize = size;
++ while (newSize < _buf.length) {
++ newSize <<= 1;
++ if (newSize <= 0) {
++ newSize = size;
++ break;
++ }
++ }
++ _buf = new byte[newSize];
++ }
++ assert(_buf.length >= size);
+
+- if (_buf.length < size) {
+- int newSize = size;
+- while (newSize < _buf.length) {
+- newSize <<= 1;
+- if (newSize <= 0) {
+- newSize = size;
+- break;
+- }
+- }
+- _buf = new byte[newSize];
+- }
+- assert(_buf.length >= size);
++ int fillp = 0;
++ if (data0 != null) {
++ int size0 = data0.capacity();
++ data0.get(_buf, fillp, size0);
++ fillp += size0;
++ }
++ if (data1 != null) {
++ int size1 = data1.capacity();
++ data1.get(_buf, fillp, size1);
++ fillp += size1;
++ }
++ while (fillp < size) {
++ // Fill in rest of data from the stream itself.
++ int nr = in.read(_buf, fillp, size - fillp);
++ if (nr <= 0) throw new IOException("EOF at end of archive");
++ fillp += nr;
++ }
+
+- int fillp = 0;
+- if (data0 != null) {
+- int size0 = data0.capacity();
+- data0.get(_buf, fillp, size0);
+- fillp += size0;
+- }
+- if (data1 != null) {
+- int size1 = data1.capacity();
+- data1.get(_buf, fillp, size1);
+- fillp += size1;
+- }
+- while (fillp < size) {
+- // Fill in rest of data from the stream itself.
+- int nr = in.read(_buf, fillp, size - fillp);
+- if (nr <= 0) throw new IOException("EOF at end of archive");
+- fillp += nr;
+- }
++ ZipEntry z = new ZipEntry(name);
++ z.setTime( (long)mtime * 1000);
++
++ if (size == 0) {
++ z.setMethod(ZipOutputStream.STORED);
++ z.setSize(0);
++ z.setCrc(0);
++ z.setCompressedSize(0);
++ } else if (!deflateHint) {
++ z.setMethod(ZipOutputStream.STORED);
++ z.setSize(size);
++ z.setCompressedSize(size);
++ crc32.reset();
++ crc32.update(_buf, 0, size);
++ z.setCrc(crc32.getValue());
++ } else {
++ z.setMethod(Deflater.DEFLATED);
++ z.setSize(size);
++ }
+
+- ZipEntry z = new ZipEntry(name);
+- z.setTime( (long)mtime * 1000);
++ j.putNextEntry(z);
+
+- if (size == 0) {
+- z.setMethod(ZipOutputStream.STORED);
+- z.setSize(0);
+- z.setCrc(0);
+- z.setCompressedSize(0);
+- } else if (!deflateHint) {
+- z.setMethod(ZipOutputStream.STORED);
+- z.setSize(size);
+- z.setCompressedSize(size);
+- crc32.reset();
+- crc32.update(_buf, 0, size);
+- z.setCrc(crc32.getValue());
+- } else {
+- z.setMethod(Deflater.DEFLATED);
+- z.setSize(size);
+- }
++ if (size > 0)
++ j.write(_buf, 0, size);
+
+- j.putNextEntry(z);
+-
+- if (size > 0)
+- j.write(_buf, 0, size);
+-
+- j.closeEntry();
+- if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z));
++ j.closeEntry();
++ if (_verbose > 0) Utils.log.info("Writing " + Utils.zeString(z));
+ }
+ }
++
++
++
+diff --git a/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java b/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java
+--- jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java
++++ jdk/src/share/classes/com/sun/java/util/jar/pack/PackerImpl.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -22,7 +22,6 @@
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-
+ package com.sun.java.util.jar.pack;
+
+ import java.util.*;
+@@ -48,9 +47,9 @@ public class PackerImpl implements Pack2
+ * the packer engines.
+ */
+ public PackerImpl() {
+- _props = new PropMap();
+- //_props.getProperty() consults defaultProps invisibly.
+- //_props.putAll(defaultProps);
++ _props = new PropMap();
++ //_props.getProperty() consults defaultProps invisibly.
++ //_props.putAll(defaultProps);
+ }
+
+
+@@ -62,7 +61,7 @@ public class PackerImpl implements Pack2
+ * @return A sorted association of option key strings to option values.
+ */
+ public SortedMap properties() {
+- return _props;
++ return _props;
+ }
+
+
+@@ -76,24 +75,24 @@ public class PackerImpl implements Pack2
+ * @param out an OutputStream
+ * @exception IOException if an error is encountered.
+ */
+- public void pack(JarFile in, OutputStream out) throws IOException {
+- assert(Utils.currentInstance.get() == null);
+- TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
+- TimeZone.getDefault();
+- try {
+- Utils.currentInstance.set(this);
+- if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
++ public synchronized void pack(JarFile in, OutputStream out) throws IOException {
++ assert(Utils.currentInstance.get() == null);
++ TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
++ TimeZone.getDefault();
++ try {
++ Utils.currentInstance.set(this);
++ if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+
+- if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
+- Utils.copyJarFile(in, out);
+- } else {
+- (new DoPack()).run(in, out);
+- in.close();
+- }
+- } finally {
+- Utils.currentInstance.set(null);
+- if (tz != null) TimeZone.setDefault(tz);
+- }
++ if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
++ Utils.copyJarFile(in, out);
++ } else {
++ (new DoPack()).run(in, out);
++ in.close();
++ }
++ } finally {
++ Utils.currentInstance.set(null);
++ if (tz != null) TimeZone.setDefault(tz);
++ }
+ }
+
+ /**
+@@ -110,39 +109,39 @@ public class PackerImpl implements Pack2
+ * @param out an OutputStream
+ * @exception IOException if an error is encountered.
+ */
+- public void pack(JarInputStream in, OutputStream out) throws IOException {
+- assert(Utils.currentInstance.get() == null);
+- TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
+- TimeZone.getDefault();
+- try {
+- Utils.currentInstance.set(this);
+- if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+- if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
+- Utils.copyJarFile(in, out);
+- } else {
+- (new DoPack()).run(in, out);
+- in.close();
+- }
+- } finally {
+- Utils.currentInstance.set(null);
+- if (tz != null) TimeZone.setDefault(tz);
++ public synchronized void pack(JarInputStream in, OutputStream out) throws IOException {
++ assert(Utils.currentInstance.get() == null);
++ TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
++ TimeZone.getDefault();
++ try {
++ Utils.currentInstance.set(this);
++ if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
++ if ("0".equals(_props.getProperty(Pack200.Packer.EFFORT))) {
++ Utils.copyJarFile(in, out);
++ } else {
++ (new DoPack()).run(in, out);
++ in.close();
++ }
++ } finally {
++ Utils.currentInstance.set(null);
++ if (tz != null) TimeZone.setDefault(tz);
+
+- }
++ }
+ }
+ /**
+ * Register a listener for changes to options.
+- * @param listener An object to be invoked when a property is changed.
++ * @param listener An object to be invoked when a property is changed.
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+- _props.addListener(listener);
++ _props.addListener(listener);
+ }
+
+ /**
+ * Remove a listener for the PropertyChange event.
+- * @param listener The PropertyChange listener to be removed.
++ * @param listener The PropertyChange listener to be removed.
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+- _props.removeListener(listener);
++ _props.removeListener(listener);
+ }
+
+
+@@ -151,471 +150,478 @@ public class PackerImpl implements Pack2
+
+ // The packer worker.
+ private class DoPack {
+- final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
++ final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
+
+- {
+- _props.setInteger(Pack200.Packer.PROGRESS, 0);
+- if (verbose > 0) Utils.log.info(_props.toString());
+- }
++ {
++ _props.setInteger(Pack200.Packer.PROGRESS, 0);
++ if (verbose > 0) Utils.log.info(_props.toString());
++ }
+
+- // Here's where the bits are collected before getting packed:
+- final Package pkg = new Package();
++ // Here's where the bits are collected before getting packed:
++ final Package pkg = new Package();
+
+- final String unknownAttrCommand;
+- {
+- String uaMode = _props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS);
+- if (!(Pack200.Packer.STRIP.equals(uaMode) ||
+- Pack200.Packer.PASS.equals(uaMode) ||
+- Pack200.Packer.ERROR.equals(uaMode))) {
+- throw new RuntimeException("Bad option: " + Pack200.Packer.UNKNOWN_ATTRIBUTE + " = " + uaMode);
+- }
+- unknownAttrCommand = uaMode.intern();
+- }
++ final String unknownAttrCommand;
++ {
++ String uaMode = _props.getProperty(Pack200.Packer.UNKNOWN_ATTRIBUTE, Pack200.Packer.PASS);
++ if (!(Pack200.Packer.STRIP.equals(uaMode) ||
++ Pack200.Packer.PASS.equals(uaMode) ||
++ Pack200.Packer.ERROR.equals(uaMode))) {
++ throw new RuntimeException("Bad option: " + Pack200.Packer.UNKNOWN_ATTRIBUTE + " = " + uaMode);
++ }
++ unknownAttrCommand = uaMode.intern();
++ }
+
+- final HashMap attrDefs;
+- final HashMap attrCommands;
+- {
+- HashMap attrDefs = new HashMap();
+- HashMap attrCommands = new HashMap();
+- String[] keys = {
+- Pack200.Packer.CLASS_ATTRIBUTE_PFX,
+- Pack200.Packer.FIELD_ATTRIBUTE_PFX,
+- Pack200.Packer.METHOD_ATTRIBUTE_PFX,
+- Pack200.Packer.CODE_ATTRIBUTE_PFX
+- };
+- int[] ctypes = {
+- Constants.ATTR_CONTEXT_CLASS,
+- Constants.ATTR_CONTEXT_FIELD,
+- Constants.ATTR_CONTEXT_METHOD,
+- Constants.ATTR_CONTEXT_CODE
+- };
+- for (int i = 0; i < ctypes.length; i++) {
+- String pfx = keys[i];
+- Map map = _props.prefixMap(pfx);
+- for (Iterator j = map.keySet().iterator(); j.hasNext(); ) {
+- String key = (String) j.next();
+- assert(key.startsWith(pfx));
+- String name = key.substring(pfx.length());
+- String layout = _props.getProperty(key);
+- Object lkey = Attribute.keyForLookup(ctypes[i], name);
+- if (Pack200.Packer.STRIP.equals(layout) ||
+- Pack200.Packer.PASS.equals(layout) ||
+- Pack200.Packer.ERROR.equals(layout)) {
+- attrCommands.put(lkey, layout.intern());
+- } else {
+- Attribute.define(attrDefs, ctypes[i], name, layout);
+- if (verbose > 1) {
+- Utils.log.fine("Added layout for "+Constants.ATTR_CONTEXT_NAME[i]+" attribute "+name+" = "+layout);
+- }
+- assert(attrDefs.containsKey(lkey));
+- }
+- }
+- }
+- if (attrDefs.size() > 0)
+- this.attrDefs = attrDefs;
+- else
+- this.attrDefs = null;
+- if (attrCommands.size() > 0)
+- this.attrCommands = attrCommands;
+- else
+- this.attrCommands = null;
+- }
++ final HashMap attrDefs;
++ final HashMap attrCommands;
++ {
++ HashMap attrDefs = new HashMap();
++ HashMap attrCommands = new HashMap();
++ String[] keys = {
++ Pack200.Packer.CLASS_ATTRIBUTE_PFX,
++ Pack200.Packer.FIELD_ATTRIBUTE_PFX,
++ Pack200.Packer.METHOD_ATTRIBUTE_PFX,
++ Pack200.Packer.CODE_ATTRIBUTE_PFX
++ };
++ int[] ctypes = {
++ Constants.ATTR_CONTEXT_CLASS,
++ Constants.ATTR_CONTEXT_FIELD,
++ Constants.ATTR_CONTEXT_METHOD,
++ Constants.ATTR_CONTEXT_CODE
++ };
++ for (int i = 0; i < ctypes.length; i++) {
++ String pfx = keys[i];
++ Map map = _props.prefixMap(pfx);
++ for (Iterator j = map.keySet().iterator(); j.hasNext(); ) {
++ String key = (String) j.next();
++ assert(key.startsWith(pfx));
++ String name = key.substring(pfx.length());
++ String layout = _props.getProperty(key);
++ Object lkey = Attribute.keyForLookup(ctypes[i], name);
++ if (Pack200.Packer.STRIP.equals(layout) ||
++ Pack200.Packer.PASS.equals(layout) ||
++ Pack200.Packer.ERROR.equals(layout)) {
++ attrCommands.put(lkey, layout.intern());
++ } else {
++ Attribute.define(attrDefs, ctypes[i], name, layout);
++ if (verbose > 1) {
++ Utils.log.fine("Added layout for "+Constants.ATTR_CONTEXT_NAME[i]+" attribute "+name+" = "+layout);
++ }
++ assert(attrDefs.containsKey(lkey));
++ }
++ }
++ }
++ if (attrDefs.size() > 0)
++ this.attrDefs = attrDefs;
++ else
++ this.attrDefs = null;
++ if (attrCommands.size() > 0)
++ this.attrCommands = attrCommands;
++ else
++ this.attrCommands = null;
++ }
+
+- final boolean keepFileOrder
+- = _props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER);
+- final boolean keepClassOrder
+- = _props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER);
++ final boolean keepFileOrder
++ = _props.getBoolean(Pack200.Packer.KEEP_FILE_ORDER);
++ final boolean keepClassOrder
++ = _props.getBoolean(Utils.PACK_KEEP_CLASS_ORDER);
+
+- final boolean keepModtime
+- = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
+- final boolean latestModtime
+- = Pack200.Packer.LATEST.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
+- final boolean keepDeflateHint
+- = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.DEFLATE_HINT));
+- {
+- if (!keepModtime && !latestModtime) {
+- int modtime = _props.getTime(Pack200.Packer.MODIFICATION_TIME);
+- if (modtime != Constants.NO_MODTIME) {
+- pkg.default_modtime = modtime;
+- }
+- }
+- if (!keepDeflateHint) {
+- boolean deflate_hint = _props.getBoolean(Pack200.Packer.DEFLATE_HINT);
+- if (deflate_hint) {
+- pkg.default_options |= Constants.AO_DEFLATE_HINT;
+- }
+- }
+- }
++ final boolean keepModtime
++ = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
++ final boolean latestModtime
++ = Pack200.Packer.LATEST.equals(_props.getProperty(Pack200.Packer.MODIFICATION_TIME));
++ final boolean keepDeflateHint
++ = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Packer.DEFLATE_HINT));
++ {
++ if (!keepModtime && !latestModtime) {
++ int modtime = _props.getTime(Pack200.Packer.MODIFICATION_TIME);
++ if (modtime != Constants.NO_MODTIME) {
++ pkg.default_modtime = modtime;
++ }
++ }
++ if (!keepDeflateHint) {
++ boolean deflate_hint = _props.getBoolean(Pack200.Packer.DEFLATE_HINT);
++ if (deflate_hint) {
++ pkg.default_options |= Constants.AO_DEFLATE_HINT;
++ }
++ }
++ }
+
+- long totalOutputSize = 0;
+- int segmentCount = 0;
+- long segmentTotalSize = 0;
+- long segmentSize = 0; // running counter
+- final long segmentLimit;
+- {
+- long limit;
+- if (_props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals(""))
+- limit = -1;
+- else
+- limit = _props.getLong(Pack200.Packer.SEGMENT_LIMIT);
+- limit = Math.min(Integer.MAX_VALUE, limit);
+- limit = Math.max(-1, limit);
+- if (limit == -1)
+- limit = Long.MAX_VALUE;
+- segmentLimit = limit;
+- }
++ long totalOutputSize = 0;
++ int segmentCount = 0;
++ long segmentTotalSize = 0;
++ long segmentSize = 0; // running counter
++ final long segmentLimit;
++ {
++ long limit;
++ if (_props.getProperty(Pack200.Packer.SEGMENT_LIMIT, "").equals(""))
++ limit = -1;
++ else
++ limit = _props.getLong(Pack200.Packer.SEGMENT_LIMIT);
++ limit = Math.min(Integer.MAX_VALUE, limit);
++ limit = Math.max(-1, limit);
++ if (limit == -1)
++ limit = Long.MAX_VALUE;
++ segmentLimit = limit;
++ }
+
+- final List passFiles; // parsed pack.pass.file options
+- {
+- // Which class files will be passed through?
+- passFiles = _props.getProperties(Pack200.Packer.PASS_FILE_PFX);
+- for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) {
+- String file = (String) i.next();
+- if (file == null) { i.remove(); continue; }
+- file = Utils.getJarEntryName(file); // normalize '\\' to '/'
+- if (file.endsWith("/"))
+- file = file.substring(0, file.length()-1);
+- i.set(file);
+- }
+- if (verbose > 0) Utils.log.info("passFiles = " + passFiles);
+- }
++ final List passFiles; // parsed pack.pass.file options
++ {
++ // Which class files will be passed through?
++ passFiles = _props.getProperties(Pack200.Packer.PASS_FILE_PFX);
++ for (ListIterator i = passFiles.listIterator(); i.hasNext(); ) {
++ String file = (String) i.next();
++ if (file == null) { i.remove(); continue; }
++ file = Utils.getJarEntryName(file); // normalize '\\' to '/'
++ if (file.endsWith("/"))
++ file = file.substring(0, file.length()-1);
++ i.set(file);
++ }
++ if (verbose > 0) Utils.log.info("passFiles = " + passFiles);
++ }
+
+- {
+- // Fill in permitted range of major/minor version numbers.
+- int ver;
+- if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0)
+- pkg.min_class_majver = (short) ver;
+- if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0)
+- pkg.min_class_minver = (short) ver;
+- if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0)
+- pkg.max_class_majver = (short) ver;
+- if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0)
+- pkg.max_class_minver = (short) ver;
+- if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0)
+- pkg.package_minver = (short) ver;
+- if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0)
+- pkg.package_majver = (short) ver;
+- }
++ {
++ // Fill in permitted range of major/minor version numbers.
++ int ver;
++ if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.majver")) != 0)
++ pkg.min_class_majver = (short) ver;
++ if ((ver = _props.getInteger(Utils.COM_PREFIX+"min.class.minver")) != 0)
++ pkg.min_class_minver = (short) ver;
++ if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.majver")) != 0)
++ pkg.max_class_majver = (short) ver;
++ if ((ver = _props.getInteger(Utils.COM_PREFIX+"max.class.minver")) != 0)
++ pkg.max_class_minver = (short) ver;
++ if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.minver")) != 0)
++ pkg.package_minver = (short) ver;
++ if ((ver = _props.getInteger(Utils.COM_PREFIX+"package.majver")) != 0)
++ pkg.package_majver = (short) ver;
++ }
+
+- {
+- // Hook for testing: Forces use of special archive modes.
+- int opt = _props.getInteger(Utils.COM_PREFIX+"archive.options");
+- if (opt != 0)
+- pkg.default_options |= opt;
+- }
++ {
++ // Hook for testing: Forces use of special archive modes.
++ int opt = _props.getInteger(Utils.COM_PREFIX+"archive.options");
++ if (opt != 0)
++ pkg.default_options |= opt;
++ }
+
+- // (Done collecting options from _props.)
++ // (Done collecting options from _props.)
+
+- boolean isClassFile(String name) {
+- if (!name.endsWith(".class")) return false;
+- for (String prefix = name; ; ) {
+- if (passFiles.contains(prefix)) return false;
+- int chop = prefix.lastIndexOf('/');
+- if (chop < 0) break;
+- prefix = prefix.substring(0, chop);
+- }
+- return true;
+- }
++ boolean isClassFile(String name) {
++ if (!name.endsWith(".class")) return false;
++ for (String prefix = name; ; ) {
++ if (passFiles.contains(prefix)) return false;
++ int chop = prefix.lastIndexOf('/');
++ if (chop < 0) break;
++ prefix = prefix.substring(0, chop);
++ }
++ return true;
++ }
+
+- boolean isMetaInfFile(String name) {
+- return name.startsWith("/" + Utils.METAINF) ||
+- name.startsWith(Utils.METAINF);
+- }
++ boolean isMetaInfFile(String name) {
++ return name.startsWith("/" + Utils.METAINF) ||
++ name.startsWith(Utils.METAINF);
++ }
+
+- // Get a new package, based on the old one.
+- private void makeNextPackage() {
+- pkg.reset();
+- }
++ // Get a new package, based on the old one.
++ private void makeNextPackage() {
++ pkg.reset();
++ }
+
+- class InFile {
+- final String name;
+- final JarFile jf;
+- final JarEntry je;
+- final File f;
+- int modtime = Constants.NO_MODTIME;
+- int options;
+- InFile(String name) {
+- this.name = Utils.getJarEntryName(name);
+- this.f = new File(name);
+- this.jf = null;
+- this.je = null;
+- int timeSecs = getModtime(f.lastModified());
+- if (keepModtime && timeSecs != Constants.NO_MODTIME) {
+- this.modtime = timeSecs;
+- } else if (latestModtime && timeSecs > pkg.default_modtime) {
+- pkg.default_modtime = timeSecs;
+- }
+- }
+- InFile(JarFile jf, JarEntry je) {
+- this.name = Utils.getJarEntryName(je.getName());
+- this.f = null;
+- this.jf = jf;
+- this.je = je;
+- int timeSecs = getModtime(je.getTime());
+- if (keepModtime && timeSecs != Constants.NO_MODTIME) {
+- this.modtime = timeSecs;
+- } else if (latestModtime && timeSecs > pkg.default_modtime) {
+- pkg.default_modtime = timeSecs;
+- }
+- if (keepDeflateHint && je.getMethod() == JarEntry.DEFLATED) {
+- options |= Constants.FO_DEFLATE_HINT;
+- }
+- }
+- InFile(JarEntry je) {
+- this(null, je);
+- }
+- long getInputLength() {
+- long len = (je != null)? je.getSize(): f.length();
+- assert(len >= 0) : this+".len="+len;
+- // Bump size by pathname length and modtime/def-hint bytes.
+- return Math.max(0, len) + name.length() + 5;
+- }
+- int getModtime(long timeMillis) {
+- // Convert milliseconds to seconds.
+- long seconds = (timeMillis+500) / 1000;
+- if ((int)seconds == seconds) {
+- return (int)seconds;
+- } else {
+- Utils.log.warning("overflow in modtime for "+f);
+- return Constants.NO_MODTIME;
+- }
+- }
+- void copyTo(Package.File file) {
+- if (modtime != Constants.NO_MODTIME)
+- file.modtime = modtime;
+- file.options |= options;
+- }
+- InputStream getInputStream() throws IOException {
+- if (jf != null)
+- return jf.getInputStream(je);
+- else
+- return new FileInputStream(f);
+- }
++ class InFile {
++ final String name;
++ final JarFile jf;
++ final JarEntry je;
++ final File f;
++ int modtime = Constants.NO_MODTIME;
++ int options;
++ InFile(String name) {
++ this.name = Utils.getJarEntryName(name);
++ this.f = new File(name);
++ this.jf = null;
++ this.je = null;
++ int timeSecs = getModtime(f.lastModified());
++ if (keepModtime && timeSecs != Constants.NO_MODTIME) {
++ this.modtime = timeSecs;
++ } else if (latestModtime && timeSecs > pkg.default_modtime) {
++ pkg.default_modtime = timeSecs;
++ }
++ }
++ InFile(JarFile jf, JarEntry je) {
++ this.name = Utils.getJarEntryName(je.getName());
++ this.f = null;
++ this.jf = jf;
++ this.je = je;
++ int timeSecs = getModtime(je.getTime());
++ if (keepModtime && timeSecs != Constants.NO_MODTIME) {
++ this.modtime = timeSecs;
++ } else if (latestModtime && timeSecs > pkg.default_modtime) {
++ pkg.default_modtime = timeSecs;
++ }
++ if (keepDeflateHint && je.getMethod() == JarEntry.DEFLATED) {
++ options |= Constants.FO_DEFLATE_HINT;
++ }
++ }
++ InFile(JarEntry je) {
++ this(null, je);
++ }
++ long getInputLength() {
++ long len = (je != null)? je.getSize(): f.length();
++ assert(len >= 0) : this+".len="+len;
++ // Bump size by pathname length and modtime/def-hint bytes.
++ return Math.max(0, len) + name.length() + 5;
++ }
++ int getModtime(long timeMillis) {
++ // Convert milliseconds to seconds.
++ long seconds = (timeMillis+500) / 1000;
++ if ((int)seconds == seconds) {
++ return (int)seconds;
++ } else {
++ Utils.log.warning("overflow in modtime for "+f);
++ return Constants.NO_MODTIME;
++ }
++ }
++ void copyTo(Package.File file) {
++ if (modtime != Constants.NO_MODTIME)
++ file.modtime = modtime;
++ file.options |= options;
++ }
++ InputStream getInputStream() throws IOException {
++ if (jf != null)
++ return jf.getInputStream(je);
++ else
++ return new FileInputStream(f);
++ }
+
+- public String toString() {
+- return name;
+- }
+- }
++ public String toString() {
++ return name;
++ }
++ }
+
+- private int nread = 0; // used only if (verbose > 0)
+- private void noteRead(InFile f) {
+- nread++;
+- if (verbose > 2)
+- Utils.log.fine("...read "+f.name);
+- if (verbose > 0 && (nread % 1000) == 0)
+- Utils.log.info("Have read "+nread+" files...");
+- }
++ private int nread = 0; // used only if (verbose > 0)
++ private void noteRead(InFile f) {
++ nread++;
++ if (verbose > 2)
++ Utils.log.fine("...read "+f.name);
++ if (verbose > 0 && (nread % 1000) == 0)
++ Utils.log.info("Have read "+nread+" files...");
++ }
+
+- void run(JarInputStream in, OutputStream out) throws IOException {
+- // First thing we do is get the manifest, as JIS does
+- // not provide the Manifest as an entry.
+- if (in.getManifest() != null) {
+- ByteArrayOutputStream tmp = new ByteArrayOutputStream();
+- in.getManifest().write(tmp);
+- InputStream tmpIn = new ByteArrayInputStream(tmp.toByteArray());
+- pkg.addFile(readFile(JarFile.MANIFEST_NAME, tmpIn));
+- }
+- for (JarEntry je; (je = in.getNextJarEntry()) != null; ) {
+- InFile inFile = new InFile(je);
++ void run(JarInputStream in, OutputStream out) throws IOException {
++ // First thing we do is get the manifest, as JIS does
++ // not provide the Manifest as an entry.
++ if (in.getManifest() != null) {
++ ByteArrayOutputStream tmp = new ByteArrayOutputStream();
++ in.getManifest().write(tmp);
++ InputStream tmpIn = new ByteArrayInputStream(tmp.toByteArray());
++ pkg.addFile(readFile(JarFile.MANIFEST_NAME, tmpIn));
++ }
++ for (JarEntry je; (je = in.getNextJarEntry()) != null; ) {
++ InFile inFile = new InFile(je);
+
+- String name = inFile.name;
+- Package.File bits = readFile(name, in);
+- Package.File file = null;
+- // (5078608) : discount the resource files in META-INF
+- // from segment computation.
+- long inflen = (isMetaInfFile(name)) ? 0L :
+- inFile.getInputLength();
++ String name = inFile.name;
++ Package.File bits = readFile(name, in);
++ Package.File file = null;
++ // (5078608) : discount the resource files in META-INF
++ // from segment computation.
++ long inflen = (isMetaInfFile(name)) ? 0L :
++ inFile.getInputLength();
+
+- if ((segmentSize += inflen) > segmentLimit) {
+- segmentSize -= inflen;
+- int nextCount = -1; // don't know; it's a stream
+- flushPartial(out, nextCount);
+- }
+- if (verbose > 1)
+- Utils.log.fine("Reading " + name);
++ if ((segmentSize += inflen) > segmentLimit) {
++ segmentSize -= inflen;
++ int nextCount = -1; // don't know; it's a stream
++ flushPartial(out, nextCount);
++ }
++ if (verbose > 1)
++ Utils.log.fine("Reading " + name);
+
+- assert(je.isDirectory() == name.endsWith("/"));
++ assert(je.isDirectory() == name.endsWith("/"));
+
+- if (isClassFile(name)) {
+- file = readClass(name, bits.getInputStream());
+- }
+- if (file == null) {
+- file = bits;
+- pkg.addFile(file);
+- }
+- inFile.copyTo(file);
+- noteRead(inFile);
+- }
+- flushAll(out);
+- }
++ if (isClassFile(name)) {
++ file = readClass(name, bits.getInputStream());
++ }
++ if (file == null) {
++ file = bits;
++ pkg.addFile(file);
++ }
++ inFile.copyTo(file);
++ noteRead(inFile);
++ }
++ flushAll(out);
++ }
+
+- void run(JarFile in, OutputStream out) throws IOException {
+- List inFiles = scanJar(in);
++ void run(JarFile in, OutputStream out) throws IOException {
++ List inFiles = scanJar(in);
+
+- if (verbose > 0)
+- Utils.log.info("Reading " + inFiles.size() + " files...");
++ if (verbose > 0)
++ Utils.log.info("Reading " + inFiles.size() + " files...");
+
+- int numDone = 0;
+- for (Iterator i = inFiles.iterator(); i.hasNext(); ) {
+- InFile inFile = (InFile) i.next();
+- String name = inFile.name;
+- // (5078608) : discount the resource files completely from segmenting
+- long inflen = (isMetaInfFile(name)) ? 0L :
+- inFile.getInputLength() ;
+- if ((segmentSize += inflen) > segmentLimit) {
+- segmentSize -= inflen;
+- // Estimate number of remaining segments:
+- float filesDone = numDone+1;
+- float segsDone = segmentCount+1;
+- float filesToDo = inFiles.size() - filesDone;
+- float segsToDo = filesToDo * (segsDone/filesDone);
+- if (verbose > 1)
+- Utils.log.fine("Estimated segments to do: "+segsToDo);
+- flushPartial(out, (int) Math.ceil(segsToDo));
+- }
+- InputStream strm = inFile.getInputStream();
+- if (verbose > 1)
+- Utils.log.fine("Reading " + name);
+- Package.File file = null;
+- if (isClassFile(name)) {
+- file = readClass(name, strm);
+- if (file == null) {
+- strm.close();
+- strm = inFile.getInputStream();
+- }
+- }
+- if (file == null) {
+- file = readFile(name, strm);
+- pkg.addFile(file);
+- }
+- inFile.copyTo(file);
+- strm.close(); // tidy up
+- noteRead(inFile);
+- numDone += 1;
+- }
+- flushAll(out);
+- }
++ int numDone = 0;
++ for (Iterator i = inFiles.iterator(); i.hasNext(); ) {
++ InFile inFile = (InFile) i.next();
++ String name = inFile.name;
++ // (5078608) : discount the resource files completely from segmenting
++ long inflen = (isMetaInfFile(name)) ? 0L :
++ inFile.getInputLength() ;
++ if ((segmentSize += inflen) > segmentLimit) {
++ segmentSize -= inflen;
++ // Estimate number of remaining segments:
++ float filesDone = numDone+1;
++ float segsDone = segmentCount+1;
++ float filesToDo = inFiles.size() - filesDone;
++ float segsToDo = filesToDo * (segsDone/filesDone);
++ if (verbose > 1)
++ Utils.log.fine("Estimated segments to do: "+segsToDo);
++ flushPartial(out, (int) Math.ceil(segsToDo));
++ }
++ InputStream strm = inFile.getInputStream();
++ if (verbose > 1)
++ Utils.log.fine("Reading " + name);
++ Package.File file = null;
++ if (isClassFile(name)) {
++ file = readClass(name, strm);
++ if (file == null) {
++ strm.close();
++ strm = inFile.getInputStream();
++ }
++ }
++ if (file == null) {
++ file = readFile(name, strm);
++ pkg.addFile(file);
++ }
++ inFile.copyTo(file);
++ strm.close(); // tidy up
++ noteRead(inFile);
++ numDone += 1;
++ }
++ flushAll(out);
++ }
+
+- Package.File readClass(String fname, InputStream in) throws IOException {
+- Package.Class cls = pkg.new Class(fname);
+- in = new BufferedInputStream(in);
+- ClassReader reader = new ClassReader(cls, in);
+- reader.setAttrDefs(attrDefs);
+- reader.setAttrCommands(attrCommands);
+- reader.unknownAttrCommand = unknownAttrCommand;
+- try {
+- reader.read();
+- } catch (Attribute.FormatException ee) {
+- // He passed up the category to us in layout.
+- if (ee.layout.equals(Pack200.Packer.PASS)) {
+- Utils.log.warning("Passing class file uncompressed due to unrecognized attribute: "+fname);
+- Utils.log.info(ee.toString());
+- return null;
+- }
+- // Otherwise, it must be an error.
+- throw ee;
+- }
+- pkg.addClass(cls);
+- return cls.file;
+- }
++ Package.File readClass(String fname, InputStream in) throws IOException {
++ Package.Class cls = pkg.new Class(fname);
++ in = new BufferedInputStream(in);
++ ClassReader reader = new ClassReader(cls, in);
++ reader.setAttrDefs(attrDefs);
++ reader.setAttrCommands(attrCommands);
++ reader.unknownAttrCommand = unknownAttrCommand;
++ try {
++ reader.read();
++ } catch (Attribute.FormatException ee) {
++ // He passed up the category to us in layout.
++ if (ee.layout.equals(Pack200.Packer.PASS)) {
++ Utils.log.warning("Passing class file uncompressed due to unrecognized attribute: "+fname);
++ Utils.log.info(ee.toString());
++ return null;
++ }
++ // Otherwise, it must be an error.
++ throw ee;
++ }
++ pkg.addClass(cls);
++ return cls.file;
++ }
+
+- // Read raw data.
+- Package.File readFile(String fname, InputStream in) throws IOException {
++ // Read raw data.
++ Package.File readFile(String fname, InputStream in) throws IOException {
+
+- Package.File file = pkg.new File(fname);
+- file.readFrom(in);
+- if (file.isDirectory() && file.getFileLength() != 0)
+- throw new IllegalArgumentException("Non-empty directory: "+file.getFileName());
+- return file;
+- }
++ Package.File file = pkg.new File(fname);
++ file.readFrom(in);
++ if (file.isDirectory() && file.getFileLength() != 0)
++ throw new IllegalArgumentException("Non-empty directory: "+file.getFileName());
++ return file;
++ }
+
+- void flushPartial(OutputStream out, int nextCount) throws IOException {
+- if (pkg.files.size() == 0 && pkg.classes.size() == 0) {
+- return; // do not flush an empty segment
+- }
+- flushPackage(out, Math.max(1, nextCount));
+- _props.setInteger(Pack200.Packer.PROGRESS, 25);
+- // In case there will be another segment:
+- makeNextPackage();
+- segmentCount += 1;
+- segmentTotalSize += segmentSize;
+- segmentSize = 0;
+- }
++ void flushPartial(OutputStream out, int nextCount) throws IOException {
++ if (pkg.files.size() == 0 && pkg.classes.size() == 0) {
++ return; // do not flush an empty segment
++ }
++ flushPackage(out, Math.max(1, nextCount));
++ _props.setInteger(Pack200.Packer.PROGRESS, 25);
++ // In case there will be another segment:
++ makeNextPackage();
++ segmentCount += 1;
++ segmentTotalSize += segmentSize;
++ segmentSize = 0;
++ }
+
+- void flushAll(OutputStream out) throws IOException {
+- _props.setInteger(Pack200.Packer.PROGRESS, 50);
+- flushPackage(out, 0);
+- out.flush();
+- _props.setInteger(Pack200.Packer.PROGRESS, 100);
+- segmentCount += 1;
+- segmentTotalSize += segmentSize;
+- segmentSize = 0;
+- if (verbose > 0 && segmentCount > 1) {
+- Utils.log.info("Transmitted "
+- +segmentTotalSize+" input bytes in "
+- +segmentCount+" segments totaling "
+- +totalOutputSize+" bytes");
+- }
+- }
++ void flushAll(OutputStream out) throws IOException {
++ _props.setInteger(Pack200.Packer.PROGRESS, 50);
++ flushPackage(out, 0);
++ out.flush();
++ _props.setInteger(Pack200.Packer.PROGRESS, 100);
++ segmentCount += 1;
++ segmentTotalSize += segmentSize;
++ segmentSize = 0;
++ if (verbose > 0 && segmentCount > 1) {
++ Utils.log.info("Transmitted "
++ +segmentTotalSize+" input bytes in "
++ +segmentCount+" segments totaling "
++ +totalOutputSize+" bytes");
++ }
++ }
+
+
+- /** Write all information in the current package segment
+- * to the output stream.
+- */
+- void flushPackage(OutputStream out, int nextCount) throws IOException {
+- int nfiles = pkg.files.size();
+- if (!keepFileOrder) {
+- // Keeping the order of classes costs about 1%
+- // Keeping the order of all files costs something more.
+- if (verbose > 1) Utils.log.fine("Reordering files.");
+- boolean stripDirectories = true;
+- pkg.reorderFiles(keepClassOrder, stripDirectories);
+- } else {
+- // Package builder must have created a stub for each class.
+- assert(pkg.files.containsAll(pkg.getClassStubs()));
+- // Order of stubs in file list must agree with classes.
+- List res = pkg.files;
+- assert((res = new ArrayList(pkg.files))
+- .retainAll(pkg.getClassStubs()) || true);
+- assert(res.equals(pkg.getClassStubs()));
+- }
+- pkg.trimStubs();
++ /** Write all information in the current package segment
++ * to the output stream.
++ */
++ void flushPackage(OutputStream out, int nextCount) throws IOException {
++ int nfiles = pkg.files.size();
++ if (!keepFileOrder) {
++ // Keeping the order of classes costs about 1%
++ // Keeping the order of all files costs something more.
++ if (verbose > 1) Utils.log.fine("Reordering files.");
++ boolean stripDirectories = true;
++ pkg.reorderFiles(keepClassOrder, stripDirectories);
++ } else {
++ // Package builder must have created a stub for each class.
++ assert(pkg.files.containsAll(pkg.getClassStubs()));
++ // Order of stubs in file list must agree with classes.
++ List res = pkg.files;
++ assert((res = new ArrayList(pkg.files))
++ .retainAll(pkg.getClassStubs()) || true);
++ assert(res.equals(pkg.getClassStubs()));
++ }
++ pkg.trimStubs();
+
+- // Do some stripping, maybe.
+- if (_props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug");
+- if (_props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile");
+- if (_props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant");
+- if (_props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions");
+- if (_props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses");
++ // Do some stripping, maybe.
++ if (_props.getBoolean(Utils.COM_PREFIX+"strip.debug")) pkg.stripAttributeKind("Debug");
++ if (_props.getBoolean(Utils.COM_PREFIX+"strip.compile")) pkg.stripAttributeKind("Compile");
++ if (_props.getBoolean(Utils.COM_PREFIX+"strip.constants")) pkg.stripAttributeKind("Constant");
++ if (_props.getBoolean(Utils.COM_PREFIX+"strip.exceptions")) pkg.stripAttributeKind("Exceptions");
++ if (_props.getBoolean(Utils.COM_PREFIX+"strip.innerclasses")) pkg.stripAttributeKind("InnerClasses");
+
+- // Must choose an archive version; PackageWriter does not.
+- if (pkg.package_majver <= 0) pkg.choosePackageVersion();
++ // Must choose an archive version; PackageWriter does not.
++ if (pkg.package_majver <= 0) pkg.choosePackageVersion();
+
+- PackageWriter pw = new PackageWriter(pkg, out);
+- pw.archiveNextCount = nextCount;
+- pw.write();
+- out.flush();
+- if (verbose > 0) {
+- long outSize = pw.archiveSize0+pw.archiveSize1;
+- totalOutputSize += outSize;
+- long inSize = segmentSize;
+- Utils.log.info("Transmitted "
+- +nfiles+" files of "
+- +inSize+" input bytes in a segment of "
+- +outSize+" bytes");
+- }
+- }
++ PackageWriter pw = new PackageWriter(pkg, out);
++ pw.archiveNextCount = nextCount;
++ pw.write();
++ out.flush();
++ if (verbose > 0) {
++ long outSize = pw.archiveSize0+pw.archiveSize1;
++ totalOutputSize += outSize;
++ long inSize = segmentSize;
++ Utils.log.info("Transmitted "
++ +nfiles+" files of "
++ +inSize+" input bytes in a segment of "
++ +outSize+" bytes");
++ }
++ }
+
+- List scanJar(JarFile jf) throws IOException {
+- // Collect jar entries, preserving order.
+- List inFiles = new ArrayList();
+- for (Enumeration e = jf.entries(); e.hasMoreElements(); ) {
+- JarEntry je = (JarEntry) e.nextElement();
+- InFile inFile = new InFile(jf, je);
+- assert(je.isDirectory() == inFile.name.endsWith("/"));
+- inFiles.add(inFile);
+- }
+- return inFiles;
+- }
++ List scanJar(JarFile jf) throws IOException {
++ // Collect jar entries, preserving order.
++ List inFiles = new ArrayList();
++ for (Enumeration e = jf.entries(); e.hasMoreElements(); ) {
++ JarEntry je = (JarEntry) e.nextElement();
++ InFile inFile = new InFile(jf, je);
++ assert(je.isDirectory() == inFile.name.endsWith("/"));
++ inFiles.add(inFile);
++ }
++ return inFiles;
++ }
+ }
+ }
++
++
++
++
++
++
++
+diff --git a/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java b/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java
+--- jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java
++++ jdk/src/share/classes/com/sun/java/util/jar/pack/UnpackerImpl.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -41,53 +41,53 @@ import java.beans.PropertyChangeEvent;
+
+
+ public class UnpackerImpl implements Pack200.Unpacker {
+-
+-
++
++
+ /**
+ * Register a listener for changes to options.
+ * @param listener An object to be invoked when a property is changed.
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+- _props.addListener(listener);
++ _props.addListener(listener);
+ }
+-
+-
++
++
+ /**
+ * Remove a listener for the PropertyChange event.
+ * @param listener The PropertyChange listener to be removed.
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+- _props.removeListener(listener);
++ _props.removeListener(listener);
+ }
+-
++
+ public UnpackerImpl() {
+- _props = new PropMap();
+- //_props.getProperty() consults defaultProps invisibly.
+- //_props.putAll(defaultProps);
++ _props = new PropMap();
++ //_props.getProperty() consults defaultProps invisibly.
++ //_props.putAll(defaultProps);
+ }
+-
++
+ // Private stuff.
+ final PropMap _props;
+
+-
++
+ /**
+ * Get the set of options for the pack and unpack engines.
+ * @return A sorted association of option key strings to option values.
+ */
+ public SortedMap properties() {
+- return _props;
++ return _props;
+ }
+-
++
+ // Back-pointer to NativeUnpacker, when active.
+ Object _nunp;
+-
+-
++
++
+ public String toString() {
+- return Utils.getVersionString();
++ return Utils.getVersionString();
+ }
+-
++
+ //Driver routines
+-
++
+ // The unpack worker...
+ /**
+ * Takes a packed-stream InputStream, and writes to a JarOutputStream. Internally
+@@ -99,36 +99,36 @@ public class UnpackerImpl implements Pac
+ * @param out a JarOutputStream.
+ * @exception IOException if an error is encountered.
+ */
+- public void unpack(InputStream in0, JarOutputStream out) throws IOException {
+- assert(Utils.currentInstance.get() == null);
+- TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
+- TimeZone.getDefault();
+-
+- try {
+- Utils.currentInstance.set(this);
+- if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+- final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
+- BufferedInputStream in = new BufferedInputStream(in0);
+- if (Utils.isJarMagic(Utils.readMagic(in))) {
+- if (verbose > 0)
+- Utils.log.info("Copying unpacked JAR file...");
+- Utils.copyJarFile(new JarInputStream(in), out);
+- } else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
+- (new DoUnpack()).run(in, out);
+- in.close();
+- Utils.markJarFile(out);
+- } else {
+- (new NativeUnpack(this)).run(in, out);
+- in.close();
+- Utils.markJarFile(out);
+- }
+- } finally {
+- _nunp = null;
+- Utils.currentInstance.set(null);
+- if (tz != null) TimeZone.setDefault(tz);
+- }
++ public synchronized void unpack(InputStream in0, JarOutputStream out) throws IOException {
++ assert(Utils.currentInstance.get() == null);
++ TimeZone tz = (_props.getBoolean(Utils.PACK_DEFAULT_TIMEZONE)) ? null :
++ TimeZone.getDefault();
++
++ try {
++ Utils.currentInstance.set(this);
++ if (tz != null) TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
++ final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
++ BufferedInputStream in = new BufferedInputStream(in0);
++ if (Utils.isJarMagic(Utils.readMagic(in))) {
++ if (verbose > 0)
++ Utils.log.info("Copying unpacked JAR file...");
++ Utils.copyJarFile(new JarInputStream(in), out);
++ } else if (_props.getBoolean(Utils.DEBUG_DISABLE_NATIVE)) {
++ (new DoUnpack()).run(in, out);
++ in.close();
++ Utils.markJarFile(out);
++ } else {
++ (new NativeUnpack(this)).run(in, out);
++ in.close();
++ Utils.markJarFile(out);
++ }
++ } finally {
++ _nunp = null;
++ Utils.currentInstance.set(null);
++ if (tz != null) TimeZone.setDefault(tz);
++ }
+ }
+-
++
+ /**
+ * Takes an input File containing the pack file, and generates a JarOutputStream.
+ * <p>
+@@ -137,121 +137,121 @@ public class UnpackerImpl implements Pac
+ * @param out a JarOutputStream.
+ * @exception IOException if an error is encountered.
+ */
+- public void unpack(File in, JarOutputStream out) throws IOException {
+- // Use the stream-based implementation.
+- // %%% Reconsider if native unpacker learns to memory-map the file.
+- FileInputStream instr = new FileInputStream(in);
+- unpack(instr, out);
+- if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
+- in.delete();
+- }
++ public synchronized void unpack(File in, JarOutputStream out) throws IOException {
++ // Use the stream-based implementation.
++ // %%% Reconsider if native unpacker learns to memory-map the file.
++ FileInputStream instr = new FileInputStream(in);
++ unpack(instr, out);
++ if (_props.getBoolean(Utils.UNPACK_REMOVE_PACKFILE)) {
++ in.delete();
++ }
+ }
+-
++
+ private class DoUnpack {
+- final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
+-
+- {
+- _props.setInteger(Pack200.Unpacker.PROGRESS, 0);
+- }
+-
+- // Here's where the bits are read from disk:
+- final Package pkg = new Package();
+-
+- final boolean keepModtime
+- = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP));
+- final boolean keepDeflateHint
+- = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP));
+- final int modtime;
+- final boolean deflateHint;
+- {
+- if (!keepModtime) {
+- modtime = _props.getTime(Utils.UNPACK_MODIFICATION_TIME);
+- } else {
+- modtime = pkg.default_modtime;
+- }
+-
+- deflateHint = (keepDeflateHint) ? false :
+- _props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT);
+- }
+-
+- // Checksum apparatus.
+- final CRC32 crc = new CRC32();
+- final ByteArrayOutputStream bufOut = new ByteArrayOutputStream();
+- final OutputStream crcOut = new CheckedOutputStream(bufOut, crc);
+-
+- public void run(BufferedInputStream in, JarOutputStream out) throws IOException {
+- if (verbose > 0) {
+- _props.list(System.out);
+- }
+- for (int seg = 1; ; seg++) {
+- unpackSegment(in, out);
+-
+- // Try to get another segment.
+- if (!Utils.isPackMagic(Utils.readMagic(in))) break;
+- if (verbose > 0)
+- Utils.log.info("Finished segment #"+seg);
+- }
+- }
+-
+- private void unpackSegment(InputStream in, JarOutputStream out) throws IOException {
+- _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0");
+- // Process the output directory or jar output.
+- new PackageReader(pkg, in).read();
+-
+- if (_props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug");
+- if (_props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile");
+- _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50");
+- pkg.ensureAllClassFiles();
+- // Now write out the files.
+- HashSet classesToWrite = new HashSet(pkg.getClasses());
+- for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) {
+- Package.File file = (Package.File) i.next();
+- String name = file.nameString;
+- JarEntry je = new JarEntry(Utils.getJarEntryName(name));
+- boolean deflate;
+-
+- deflate = (keepDeflateHint) ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) ||
+- ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) :
+- deflateHint;
+-
+- boolean needCRC = !deflate; // STORE mode requires CRC
+-
+- if (needCRC) crc.reset();
+- bufOut.reset();
+- if (file.isClassStub()) {
+- Package.Class cls = file.getStubClass();
+- assert(cls != null);
+- new ClassWriter(cls, needCRC ? crcOut : bufOut).write();
+- classesToWrite.remove(cls); // for an error check
+- } else {
+- // collect data & maybe CRC
+- file.writeTo(needCRC ? crcOut : bufOut);
+- }
+- je.setMethod(deflate ? JarEntry.DEFLATED : JarEntry.STORED);
+- if (needCRC) {
+- if (verbose > 0)
+- Utils.log.info("stored size="+bufOut.size()+" and crc="+crc.getValue());
+-
+- je.setMethod(JarEntry.STORED);
+- je.setSize(bufOut.size());
+- je.setCrc(crc.getValue());
+- }
+- if (keepModtime) {
+- je.setTime(file.modtime);
+- // Convert back to milliseconds
+- je.setTime((long)file.modtime * 1000);
+- } else {
+- je.setTime((long)modtime * 1000);
+- }
+- out.putNextEntry(je);
+- bufOut.writeTo(out);
+- out.closeEntry();
+- if (verbose > 0)
+- Utils.log.info("Writing "+Utils.zeString((ZipEntry)je));
+- }
+- assert(classesToWrite.isEmpty());
+- _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100");
+- pkg.reset(); // reset for the next segment, if any
+- }
++ final int verbose = _props.getInteger(Utils.DEBUG_VERBOSE);
++
++ {
++ _props.setInteger(Pack200.Unpacker.PROGRESS, 0);
++ }
++
++ // Here's where the bits are read from disk:
++ final Package pkg = new Package();
++
++ final boolean keepModtime
++ = Pack200.Packer.KEEP.equals(_props.getProperty(Utils.UNPACK_MODIFICATION_TIME, Pack200.Packer.KEEP));
++ final boolean keepDeflateHint
++ = Pack200.Packer.KEEP.equals(_props.getProperty(Pack200.Unpacker.DEFLATE_HINT, Pack200.Packer.KEEP));
++ final int modtime;
++ final boolean deflateHint;
++ {
++ if (!keepModtime) {
++ modtime = _props.getTime(Utils.UNPACK_MODIFICATION_TIME);
++ } else {
++ modtime = pkg.default_modtime;
++ }
++
++ deflateHint = (keepDeflateHint) ? false :
++ _props.getBoolean(java.util.jar.Pack200.Unpacker.DEFLATE_HINT);
++ }
++
++ // Checksum apparatus.
++ final CRC32 crc = new CRC32();
++ final ByteArrayOutputStream bufOut = new ByteArrayOutputStream();
++ final OutputStream crcOut = new CheckedOutputStream(bufOut, crc);
++
++ public void run(BufferedInputStream in, JarOutputStream out) throws IOException {
++ if (verbose > 0) {
++ _props.list(System.out);
++ }
++ for (int seg = 1; ; seg++) {
++ unpackSegment(in, out);
++
++ // Try to get another segment.
++ if (!Utils.isPackMagic(Utils.readMagic(in))) break;
++ if (verbose > 0)
++ Utils.log.info("Finished segment #"+seg);
++ }
++ }
++
++ private void unpackSegment(InputStream in, JarOutputStream out) throws IOException {
++ _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"0");
++ // Process the output directory or jar output.
++ new PackageReader(pkg, in).read();
++
++ if (_props.getBoolean("unpack.strip.debug")) pkg.stripAttributeKind("Debug");
++ if (_props.getBoolean("unpack.strip.compile")) pkg.stripAttributeKind("Compile");
++ _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"50");
++ pkg.ensureAllClassFiles();
++ // Now write out the files.
++ HashSet classesToWrite = new HashSet(pkg.getClasses());
++ for (Iterator i = pkg.getFiles().iterator(); i.hasNext(); ) {
++ Package.File file = (Package.File) i.next();
++ String name = file.nameString;
++ JarEntry je = new JarEntry(Utils.getJarEntryName(name));
++ boolean deflate;
++
++ deflate = (keepDeflateHint) ? (((file.options & Constants.FO_DEFLATE_HINT) != 0) ||
++ ((pkg.default_options & Constants.AO_DEFLATE_HINT) != 0)) :
++ deflateHint;
++
++ boolean needCRC = !deflate; // STORE mode requires CRC
++
++ if (needCRC) crc.reset();
++ bufOut.reset();
++ if (file.isClassStub()) {
++ Package.Class cls = file.getStubClass();
++ assert(cls != null);
++ new ClassWriter(cls, needCRC ? crcOut : bufOut).write();
++ classesToWrite.remove(cls); // for an error check
++ } else {
++ // collect data & maybe CRC
++ file.writeTo(needCRC ? crcOut : bufOut);
++ }
++ je.setMethod(deflate ? JarEntry.DEFLATED : JarEntry.STORED);
++ if (needCRC) {
++ if (verbose > 0)
++ Utils.log.info("stored size="+bufOut.size()+" and crc="+crc.getValue());
++
++ je.setMethod(JarEntry.STORED);
++ je.setSize(bufOut.size());
++ je.setCrc(crc.getValue());
++ }
++ if (keepModtime) {
++ je.setTime(file.modtime);
++ // Convert back to milliseconds
++ je.setTime((long)file.modtime * 1000);
++ } else {
++ je.setTime((long)modtime * 1000);
++ }
++ out.putNextEntry(je);
++ bufOut.writeTo(out);
++ out.closeEntry();
++ if (verbose > 0)
++ Utils.log.info("Writing "+Utils.zeString((ZipEntry)je));
++ }
++ assert(classesToWrite.isEmpty());
++ _props.setProperty(java.util.jar.Pack200.Unpacker.PROGRESS,"100");
++ pkg.reset(); // reset for the next segment, if any
++ }
+ }
+ }
+diff --git a/src/share/native/com/sun/java/util/jar/pack/bands.cpp b/src/share/native/com/sun/java/util/jar/pack/bands.cpp
+--- jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp
++++ jdk/src/share/native/com/sun/java/util/jar/pack/bands.cpp
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -81,11 +81,11 @@ void band::readData(int expectedLength)
+ assert(defc->B() > 1 && defc->L() > 0);
+ // must have already read from previous band:
+ assert(bn >= BAND_LIMIT || bn <= 0
+- || bn == e_cp_Utf8_big_chars
+- || endsWith(name, "_lo") // preceded by _hi conditional band
+- || bn == e_file_options // preceded by conditional band
+- || u->rp == u->all_bands[bn-1].maxRP()
+- || u->all_bands[bn-1].defc == null);
++ || bn == e_cp_Utf8_big_chars
++ || endsWith(name, "_lo") // preceded by _hi conditional band
++ || bn == e_file_options // preceded by conditional band
++ || u->rp == u->all_bands[bn-1].maxRP()
++ || u->all_bands[bn-1].defc == null);
+
+ value_stream xvs;
+ coding* valc = defc;
+@@ -136,7 +136,7 @@ void band::readData(int expectedLength)
+
+ #ifndef PRODUCT
+ printcr(3,"readFrom %s at %p [%d values, %d bytes, cp=%d/%d]",
+- (name?name:"(band)"), minRP(), length, size(), cp1, cp2);
++ (name?name:"(band)"), minRP(), length, size(), cp1, cp2);
+ if (u->verbose_bands || u->verbose >= 4) dump();
+
+ if (ix != null && u->verbose != 0 && length > 0) {
+@@ -187,10 +187,14 @@ void band::setIndexByTag(byte tag) {
+
+ entry* band::getRefCommon(cpindex* ix_, bool nullOKwithCaller) {
+ CHECK_0;
++ if (ix_ == NULL) {
++ abort("no index");
++ return NULL;
++ }
+ assert(ix_->ixTag == ixTag
+- || (ixTag == CONSTANT_Literal
+- && ix_->ixTag >= CONSTANT_Integer
+- && ix_->ixTag <= CONSTANT_String));
++ || (ixTag == CONSTANT_Literal
++ && ix_->ixTag >= CONSTANT_Integer
++ && ix_->ixTag <= CONSTANT_String));
+ int n = vs[0].getInt() - nullOK;
+ // Note: band-local nullOK means null encodes as 0.
+ // But nullOKwithCaller means caller is willing to tolerate a null.
+@@ -245,9 +249,9 @@ int band::getIntCount(int tag) {
+ hist0 = U_NEW(int, (HIST0_MAX - HIST0_MIN)+1);
+ CHECK_0;
+ for (int k = length; k > 0; k--) {
+- int x = vs[0].getInt();
+- if (x >= HIST0_MIN && x <= HIST0_MAX)
+- hist0[x - HIST0_MIN] += 1;
++ int x = vs[0].getInt();
++ if (x >= HIST0_MIN && x <= HIST0_MAX)
++ hist0[x - HIST0_MIN] += 1;
+ }
+ rewind();
+ }
+@@ -262,7 +266,7 @@ int band::getIntCount(int tag) {
+ }
+
+ #define INDEX_INIT(tag, nullOK, subindex) \
+- ((tag) + (subindex)*SUBINDEX_BIT + (nullOK)*256)
++ ((tag) + (subindex)*SUBINDEX_BIT + (nullOK)*256)
+
+ #define INDEX(tag) INDEX_INIT(tag, 0, 0)
+ #define NULL_OR_INDEX(tag) INDEX_INIT(tag, 1, 0)
+@@ -437,13 +441,13 @@ const band_init all_band_inits[] = {
+ {0}
+ };
+ #define NUM_BAND_INITS \
+- (sizeof(all_band_inits)/sizeof(all_band_inits[0]))
++ (sizeof(all_band_inits)/sizeof(all_band_inits[0]))
+
+ band* band::makeBands(unpacker* u) {
+ band* all_bands = U_NEW(band, BAND_LIMIT);
+ for (int i = 0; i < BAND_LIMIT; i++) {
+ assert((byte*)&all_band_inits[i+1]
+- < (byte*)all_band_inits+sizeof(all_band_inits));
++ < (byte*)all_band_inits+sizeof(all_band_inits));
+ const band_init& bi = all_band_inits[i];
+ band& b = all_bands[i];
+ coding* defc = coding::findBySpec(bi.defc);
+@@ -472,3 +476,5 @@ void band::initIndexes(unpacker* u) {
+ }
+ }
+ }
++
++
+diff --git a/src/share/native/com/sun/java/util/jar/pack/bands.h b/src/share/native/com/sun/java/util/jar/pack/bands.h
+--- jdk/src/share/native/com/sun/java/util/jar/pack/bands.h
++++ jdk/src/share/native/com/sun/java/util/jar/pack/bands.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -22,7 +22,7 @@
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-
++
+ // -*- C++ -*-
+ struct entry;
+ struct cpindex;
+@@ -50,7 +50,7 @@ struct band {
+
+ // properties for attribute layout elements:
+ byte le_kind; // EK_XXX
+- byte le_bci; // 0,EK_BCI,EK_BCD,EK_BCO
++ byte le_bci; // 0,EK_BCI,EK_BCD,EK_BCO
+ byte le_back; // ==EF_BACK
+ byte le_len; // 0,1,2,4 (size in classfile), or call addr
+ band** le_body; // body of repl, union, call (null-terminated)
+@@ -101,8 +101,8 @@ struct band {
+
+ int getByte() { assert(ix == null); return vs[0].getByte(); }
+ int getInt() { assert(ix == null); return vs[0].getInt(); }
+- entry* getRefN() { assert(ix != null); return getRefCommon(ix, true); }
+- entry* getRef() { assert(ix != null); return getRefCommon(ix, false); }
++ entry* getRefN() { return getRefCommon(ix, true); }
++ entry* getRef() { return getRefCommon(ix, false); }
+ entry* getRefUsing(cpindex* ix2)
+ { assert(ix == null); return getRefCommon(ix2, true); }
+ entry* getRefCommon(cpindex* ix, bool nullOK);
+diff --git a/src/share/native/com/sun/java/util/jar/pack/defines.h b/src/share/native/com/sun/java/util/jar/pack/defines.h
+--- jdk/src/share/native/com/sun/java/util/jar/pack/defines.h
++++ jdk/src/share/native/com/sun/java/util/jar/pack/defines.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -22,10 +22,10 @@
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+-
++
+ // random definitions
+
+-#ifdef _MSC_VER
++#ifdef _MSC_VER
+ #include <windows.h>
+ #include <winuser.h>
+ #else
+@@ -94,15 +94,15 @@ typedef unsigned int uLong; // Historica
+ #else
+ typedef unsigned long uLong;
+ #endif
+-#ifdef _MSC_VER
+-typedef LONGLONG jlong;
+-typedef DWORDLONG julong;
+-#define MKDIR(dir) mkdir(dir)
+-#define getpid() _getpid()
+-#define PATH_MAX MAX_PATH
+-#define dup2(a,b) _dup2(a,b)
++#ifdef _MSC_VER
++typedef LONGLONG jlong;
++typedef DWORDLONG julong;
++#define MKDIR(dir) mkdir(dir)
++#define getpid() _getpid()
++#define PATH_MAX MAX_PATH
++#define dup2(a,b) _dup2(a,b)
+ #define strcasecmp(s1, s2) _stricmp(s1,s2)
+-#define tempname _tempname
++#define tempname _tempname
+ #define sleep Sleep
+ #else
+ typedef signed char byte;
+@@ -123,37 +123,40 @@ enum { false, true };
+
+ #define null (0)
+
+-#ifndef __sparc
++#ifndef __sparc
+ #define intptr_t jlong
+ #endif
+
+ #define ptrlowbits(x) ((int) (intptr_t)(x))
+
++/* Back and forth from jlong to pointer */
++#define ptr2jlong(x) ((jlong)(size_t)(void*)(x))
++#define jlong2ptr(x) ((void*)(size_t)(x))
+
+ // Keys used by Java:
+-#define UNPACK_DEFLATE_HINT "unpack.deflate.hint"
++#define UNPACK_DEFLATE_HINT "unpack.deflate.hint"
+
+-#define COM_PREFIX "com.sun.java.util.jar.pack."
+-#define UNPACK_MODIFICATION_TIME COM_PREFIX"unpack.modification.time"
+-#define DEBUG_VERBOSE COM_PREFIX"verbose"
++#define COM_PREFIX "com.sun.java.util.jar.pack."
++#define UNPACK_MODIFICATION_TIME COM_PREFIX"unpack.modification.time"
++#define DEBUG_VERBOSE COM_PREFIX"verbose"
+
+-#define ZIP_ARCHIVE_MARKER_COMMENT "PACK200"
++#define ZIP_ARCHIVE_MARKER_COMMENT "PACK200"
+
+ // The following are not known to the Java classes:
+-#define UNPACK_LOG_FILE COM_PREFIX"unpack.log.file"
+-#define UNPACK_REMOVE_PACKFILE COM_PREFIX"unpack.remove.packfile"
++#define UNPACK_LOG_FILE COM_PREFIX"unpack.log.file"
++#define UNPACK_REMOVE_PACKFILE COM_PREFIX"unpack.remove.packfile"
+
+
+ // Called from unpacker layers
+-#define _CHECK_DO(t,x) { if (t) {x;} }
++#define _CHECK_DO(t,x) { if (t) {x;} }
+
+-#define CHECK _CHECK_DO(aborting(), return)
+-#define CHECK_(y) _CHECK_DO(aborting(), return y)
+-#define CHECK_0 _CHECK_DO(aborting(), return 0)
++#define CHECK _CHECK_DO(aborting(), return)
++#define CHECK_(y) _CHECK_DO(aborting(), return y)
++#define CHECK_0 _CHECK_DO(aborting(), return 0)
+
+-#define CHECK_NULL(p) _CHECK_DO((p)==null, return)
+-#define CHECK_NULL_(y,p) _CHECK_DO((p)==null, return y)
+-#define CHECK_NULL_0(p) _CHECK_DO((p)==null, return 0)
++#define CHECK_NULL(p) _CHECK_DO((p)==null, return)
++#define CHECK_NULL_(y,p) _CHECK_DO((p)==null, return y)
++#define CHECK_NULL_0(p) _CHECK_DO((p)==null, return 0)
+
+ #define CHECK_COUNT(t) if (t < 0){abort("bad value count");} CHECK
+
+diff --git a/src/share/native/com/sun/java/util/jar/pack/jni.cpp b/src/share/native/com/sun/java/util/jar/pack/jni.cpp
+--- jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp
++++ jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -43,6 +43,9 @@
+ #include "bands.h"
+ #include "constants.h"
+ #include "zip.h"
++
++#include "jni_util.h"
++
+ #include "unpack.h"
+
+
+@@ -50,17 +53,19 @@ static jmethodID currentInstMID;
+ static jmethodID currentInstMID;
+ static jmethodID readInputMID;
+ static jclass NIclazz;
++static jmethodID getUnpackerPtrMID;
+
+ static char* dbg = null;
+
+ #define THROW_IOE(x) JNU_ThrowIOException(env,x)
+
+ static jlong read_input_via_jni(unpacker* self,
+- void* buf, jlong minlen, jlong maxlen);
+-
++ void* buf, jlong minlen, jlong maxlen);
++
+ static unpacker* get_unpacker(JNIEnv *env, jobject pObj, bool noCreate=false) {
+- unpacker* uPtr = (unpacker*) env->GetLongField(pObj, unpackerPtrFID);
+- //fprintf(stderr, "get_unpacker(%p) uPtr=%p\n", pObj, uPtr);
++ unpacker* uPtr;
++ jlong p = env->CallLongMethod(pObj, getUnpackerPtrMID);
++ uPtr = (unpacker*)jlong2ptr(p);
+ if (uPtr == null) {
+ if (noCreate) return null;
+ uPtr = new unpacker();
+@@ -89,11 +94,15 @@ static unpacker* get_unpacker() {
+ if (env == null)
+ return null;
+ jobject pObj = env->CallStaticObjectMethod(NIclazz, currentInstMID);
+- //fprintf(stderr, "get_unpacker() pObj=%p\n", pObj);
+- if (pObj == null)
+- return null;
+- // Got pObj and env; now do it the easy way.
+- return get_unpacker(env, pObj);
++ //fprintf(stderr, "get_unpacker0() pObj=%p\n", pObj);
++ if (pObj != null) {
++ // Got pObj and env; now do it the easy way.
++ return get_unpacker(env, pObj);
++ }
++ // this should really not happen, if it does something is seriously
++ // wrong throw an exception
++ THROW_IOE(ERROR_INTERNAL);
++ return null;
+ }
+
+ static void free_unpacker(JNIEnv *env, jobject pObj, unpacker* uPtr) {
+@@ -113,36 +122,47 @@ unpacker* unpacker::current() {
+
+ // Callback for fetching data, Java style. Calls NativeUnpack.readInputFn().
+ static jlong read_input_via_jni(unpacker* self,
+- void* buf, jlong minlen, jlong maxlen) {
++ void* buf, jlong minlen, jlong maxlen) {
+ JNIEnv* env = (JNIEnv*) self->jnienv;
+ jobject pbuf = env->NewDirectByteBuffer(buf, maxlen);
+ return env->CallLongMethod((jobject) self->jniobj, readInputMID,
+- pbuf, minlen);
++ pbuf, minlen);
+ }
+
+-JNIEXPORT void JNICALL
++JNIEXPORT void JNICALL
+ Java_com_sun_java_util_jar_pack_NativeUnpack_initIDs(JNIEnv *env, jclass clazz) {
++#ifndef PRODUCT
+ dbg = getenv("DEBUG_ATTACH");
+ while( dbg != null) { sleep(10); }
++#endif
+ NIclazz = (jclass) env->NewGlobalRef(clazz);
+ unpackerPtrFID = env->GetFieldID(clazz, "unpackerPtr", "J");
+ currentInstMID = env->GetStaticMethodID(clazz, "currentInstance",
+- "()Ljava/lang/Object;");
++ "()Ljava/lang/Object;");
+ readInputMID = env->GetMethodID(clazz, "readInputFn",
+- "(Ljava/nio/ByteBuffer;J)J");
++ "(Ljava/nio/ByteBuffer;J)J");
++
++ getUnpackerPtrMID = env->GetMethodID(clazz, "getUnpackerPtr", "()J");
++
+ if (unpackerPtrFID == null ||
+ currentInstMID == null ||
+ readInputMID == null ||
+- NIclazz == null) {
++ NIclazz == null ||
++ getUnpackerPtrMID == null) {
+ THROW_IOE("cannot init class members");
+ }
+ }
+
+-JNIEXPORT jlong JNICALL
++JNIEXPORT jlong JNICALL
+ Java_com_sun_java_util_jar_pack_NativeUnpack_start(JNIEnv *env, jobject pObj,
+- jobject pBuf, jlong offset) {
+- unpacker* uPtr = get_unpacker(env, pObj);
+-
++ jobject pBuf, jlong offset) {
++ // try to get the unpacker pointer the hard way first, we do this to ensure
++ // valid object pointers and env is intact, if not now is good time to bail.
++ unpacker* uPtr = get_unpacker();
++ //fprintf(stderr, "start(%p) uPtr=%p initializing\n", pObj, uPtr);
++ if (uPtr == null) {
++ return -1;
++ }
+ // redirect our io to the default log file or whatever.
+ uPtr->redirect_stdio();
+
+@@ -158,6 +178,13 @@ Java_com_sun_java_util_jar_pack_NativeUn
+ else
+ { buf = (char*)buf + (size_t)offset; buflen -= (size_t)offset; }
+ }
++
++ // before we start off we make sure there is no other error by the time we
++ // get here
++ if (uPtr->aborting()) {
++ THROW_IOE(uPtr->get_abort_message());
++ return 0;
++ }
+
+ uPtr->start(buf, buflen);
+ if (uPtr->aborting()) {
+@@ -166,13 +193,13 @@ Java_com_sun_java_util_jar_pack_NativeUn
+ }
+
+ return ((jlong)
+- uPtr->get_segments_remaining() << 32)
++ uPtr->get_segments_remaining() << 32)
+ + uPtr->get_files_remaining();
+ }
+
+-JNIEXPORT jboolean JNICALL
+-Java_com_sun_java_util_jar_pack_NativeUnpack_getNextFile(JNIEnv *env, jobject pObj,
+- jobjectArray pParts) {
++JNIEXPORT jboolean JNICALL
++Java_com_sun_java_util_jar_pack_NativeUnpack_getNextFile(JNIEnv *env, jobject pObj,
++ jobjectArray pParts) {
+
+ unpacker* uPtr = get_unpacker(env, pObj);
+ unpacker::file* filep = uPtr->get_next_file();
+@@ -201,19 +228,19 @@ Java_com_sun_java_util_jar_pack_NativeUn
+ jobject pDataBuf = null;
+ if (filep->data[0].len > 0)
+ pDataBuf = env->NewDirectByteBuffer(filep->data[0].ptr,
+- filep->data[0].len);
++ filep->data[0].len);
+ env->SetObjectArrayElement(pParts, pidx++, pDataBuf);
+ pDataBuf = null;
+ if (filep->data[1].len > 0)
+ pDataBuf = env->NewDirectByteBuffer(filep->data[1].ptr,
+- filep->data[1].len);
++ filep->data[1].len);
+ env->SetObjectArrayElement(pParts, pidx++, pDataBuf);
+
+ return true;
+ }
+
+
+-JNIEXPORT jobject JNICALL
++JNIEXPORT jobject JNICALL
+ Java_com_sun_java_util_jar_pack_NativeUnpack_getUnusedInput(JNIEnv *env, jobject pObj) {
+ unpacker* uPtr = get_unpacker(env, pObj);
+ unpacker::file* filep = &uPtr->cur_file;
+@@ -225,14 +252,18 @@ Java_com_sun_java_util_jar_pack_NativeUn
+
+ // We have fetched all the files.
+ // Now swallow up any remaining input.
+- if (uPtr->input_remaining() == 0)
++ if (uPtr->input_remaining() == 0) {
+ return null;
+- else
+- return env->NewDirectByteBuffer(uPtr->input_scan(),
+- uPtr->input_remaining());
++ }
++ else {
++ bytes remaining_bytes;
++ remaining_bytes.malloc(uPtr->input_remaining());
++ remaining_bytes.copyFrom(uPtr->input_scan(), uPtr->input_remaining());
++ return env->NewDirectByteBuffer(remaining_bytes.ptr, remaining_bytes.len);
++ }
+ }
+
+-JNIEXPORT jlong JNICALL
++JNIEXPORT jlong JNICALL
+ Java_com_sun_java_util_jar_pack_NativeUnpack_finish(JNIEnv *env, jobject pObj) {
+ unpacker* uPtr = get_unpacker(env, pObj, false);
+ if (uPtr == null) return 0;
+@@ -241,9 +272,9 @@ Java_com_sun_java_util_jar_pack_NativeUn
+ return consumed;
+ }
+
+-JNIEXPORT jboolean JNICALL
+-Java_com_sun_java_util_jar_pack_NativeUnpack_setOption(JNIEnv *env, jobject pObj,
+- jstring pProp, jstring pValue) {
++JNIEXPORT jboolean JNICALL
++Java_com_sun_java_util_jar_pack_NativeUnpack_setOption(JNIEnv *env, jobject pObj,
++ jstring pProp, jstring pValue) {
+ unpacker* uPtr = get_unpacker(env, pObj);
+ const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE);
+ const char* value = env->GetStringUTFChars(pValue, JNI_FALSE);
+@@ -253,9 +284,9 @@ Java_com_sun_java_util_jar_pack_NativeUn
+ return retval;
+ }
+
+-JNIEXPORT jstring JNICALL
+-Java_com_sun_java_util_jar_pack_NativeUnpack_getOption(JNIEnv *env, jobject pObj,
+- jstring pProp) {
++JNIEXPORT jstring JNICALL
++Java_com_sun_java_util_jar_pack_NativeUnpack_getOption(JNIEnv *env, jobject pObj,
++ jstring pProp) {
+
+ unpacker* uPtr = get_unpacker(env, pObj);
+ const char* prop = env->GetStringUTFChars(pProp, JNI_FALSE);
+diff --git a/src/share/native/com/sun/java/util/jar/pack/unpack.cpp b/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
+--- jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
++++ jdk/src/share/native/com/sun/java/util/jar/pack/unpack.cpp
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -38,7 +38,7 @@
+ #include <time.h>
+
+
+-
++
+
+ #include "defines.h"
+ #include "bytes.h"
+@@ -185,9 +185,9 @@ struct entry {
+ || (tag2 == CONSTANT_Utf8 && tag == CONSTANT_Signature)
+ #ifndef PRODUCT
+ || (tag2 == CONSTANT_Literal
+- && tag >= CONSTANT_Integer && tag <= CONSTANT_String && tag != CONSTANT_Class)
++ && tag >= CONSTANT_Integer && tag <= CONSTANT_String && tag != CONSTANT_Class)
+ || (tag2 == CONSTANT_Member
+- && tag >= CONSTANT_Fieldref && tag <= CONSTANT_InterfaceMethodref)
++ && tag >= CONSTANT_Fieldref && tag <= CONSTANT_InterfaceMethodref)
+ #endif
+ ;
+ }
+@@ -238,9 +238,9 @@ int entry::typeSize() {
+ // else fall through
+ case 'L':
+ sigp = strchr(sigp, ';');
+- if (sigp == null) {
+- unpack_abort("bad data");
+- return 0;
++ if (sigp == null) {
++ unpack_abort("bad data");
++ return 0;
+ }
+ sigp += 1;
+ break;
+@@ -252,11 +252,13 @@ int entry::typeSize() {
+ }
+
+ inline cpindex* cpool::getFieldIndex(entry* classRef) {
++ if (classRef == NULL) { abort("missing class reference"); return NULL; }
+ assert(classRef->tagMatches(CONSTANT_Class));
+ assert((uint)classRef->inord < tag_count[CONSTANT_Class]);
+ return &member_indexes[classRef->inord*2+0];
+ }
+ inline cpindex* cpool::getMethodIndex(entry* classRef) {
++ if (classRef == NULL) { abort("missing class reference"); return NULL; }
+ assert(classRef->tagMatches(CONSTANT_Class));
+ assert((uint)classRef->inord < tag_count[CONSTANT_Class]);
+ return &member_indexes[classRef->inord*2+1];
+@@ -512,11 +514,10 @@ void unpacker::read_file_header() {
+ AH_CP_NUMBER_LEN = 4, // int/float/long/double
+ AH_SPECIAL_FORMAT_LEN = 2, // layouts/band-headers
+ AH_LENGTH_MIN = AH_LENGTH
+- -(AH_FILE_HEADER_LEN+AH_SPECIAL_FORMAT_LEN+AH_CP_NUMBER_LEN),
+- ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - (AH_LENGTH_0 + AH_ARCHIVE_SIZE_LEN),
++ -(AH_FILE_HEADER_LEN+AH_SPECIAL_FORMAT_LEN+AH_CP_NUMBER_LEN),
++ ARCHIVE_SIZE_MIN = AH_LENGTH_MIN - (AH_LENGTH_0 + AH_ARCHIVE_SIZE_LEN),
+ FIRST_READ = MAGIC_BYTES + AH_LENGTH_MIN
+ };
+-
+
+ assert(AH_LENGTH_MIN == 15); // # of UNSIGNED5 fields required after archive_magic
+ assert(ARCHIVE_SIZE_MIN == 10); // # of UNSIGNED5 fields required after archive_size
+@@ -580,15 +581,15 @@ void unpacker::read_file_header() {
+ for (;;) {
+ jarout->write_data(rp, input_remaining());
+ if (foreign_buf)
+- break; // one-time use of a passed in buffer
++ break; // one-time use of a passed in buffer
+ if (input.size() < CHUNK) {
+- // Get some breathing room.
+- input.set(U_NEW(byte, (size_t) CHUNK + C_SLOP), (size_t) CHUNK);
+- CHECK;
++ // Get some breathing room.
++ input.set(U_NEW(byte, (size_t) CHUNK + C_SLOP), (size_t) CHUNK);
++ CHECK;
+ }
+ rp = rplimit = input.base();
+ if (!ensure_input(1))
+- break;
++ break;
+ }
+ jarout->closeJarFile(false);
+ #endif
+@@ -612,16 +613,16 @@ void unpacker::read_file_header() {
+ hdrVals += 2;
+
+ if (magic != JAVA_PACKAGE_MAGIC ||
+- (majver != JAVA5_PACKAGE_MAJOR_VERSION &&
+- majver != JAVA6_PACKAGE_MAJOR_VERSION) ||
+- (minver != JAVA5_PACKAGE_MINOR_VERSION &&
++ (majver != JAVA5_PACKAGE_MAJOR_VERSION &&
++ majver != JAVA6_PACKAGE_MAJOR_VERSION) ||
++ (minver != JAVA5_PACKAGE_MINOR_VERSION &&
+ minver != JAVA6_PACKAGE_MINOR_VERSION)) {
+ char message[200];
+ sprintf(message, "@" ERROR_FORMAT ": magic/ver = "
+- "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d\n",
+- magic, majver, minver,
+- JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION,
+- JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION);
++ "%08X/%d.%d should be %08X/%d.%d OR %08X/%d.%d\n",
++ magic, majver, minver,
++ JAVA_PACKAGE_MAGIC, JAVA5_PACKAGE_MAJOR_VERSION, JAVA5_PACKAGE_MINOR_VERSION,
++ JAVA_PACKAGE_MAGIC, JAVA6_PACKAGE_MAJOR_VERSION, JAVA6_PACKAGE_MINOR_VERSION);
+ abort(message);
+ }
+ CHECK;
+@@ -635,7 +636,7 @@ void unpacker::read_file_header() {
+ #undef ORBIT
+ if ((archive_options & ~OPTION_LIMIT) != 0) {
+ fprintf(errstrm, "Warning: Illegal archive options 0x%x\n",
+- archive_options);
++ archive_options);
+ abort("illegal archive options");
+ return;
+ }
+@@ -675,7 +676,7 @@ void unpacker::read_file_header() {
+ if (archive_size < header_size_1) {
+ abort("too much read-ahead"); // somehow we pre-fetched too much?
+ return;
+- }
++ }
+ input.set(U_NEW(byte, add_size(header_size_0, archive_size, C_SLOP)),
+ (size_t) header_size_0 + archive_size);
+ CHECK;
+@@ -756,9 +757,9 @@ void unpacker::read_file_header() {
+ case CONSTANT_Float:
+ case CONSTANT_Long:
+ case CONSTANT_Double:
+- cp_counts[k] = 0;
+- hdrValsSkipped += 1;
+- continue;
++ cp_counts[k] = 0;
++ hdrValsSkipped += 1;
++ continue;
+ }
+ }
+ cp_counts[k] = hdr.getInt();
+@@ -813,7 +814,7 @@ void unpacker::read_file_header() {
+ bytes band_headers;
+ // The "1+" allows an initial byte to be pushed on the front.
+ band_headers.set(1+U_NEW(byte, 1+band_headers_size+C_SLOP),
+- band_headers_size);
++ band_headers_size);
+ CHECK;
+ // Start scanning band headers here:
+ band_headers.copyFrom(rp, band_headers.len);
+@@ -874,7 +875,7 @@ void cpool::init(unpacker* u_, int count
+ IMPLICIT_ENTRY_COUNT = 1 // empty Utf8 string
+ };
+ if (len >= (1<<29) || len < 0
+- || next_entry >= CP_SIZE_LIMIT+IMPLICIT_ENTRY_COUNT) {
++ || next_entry >= CP_SIZE_LIMIT+IMPLICIT_ENTRY_COUNT) {
+ abort("archive too large: constant pool limit exceeded");
+ return;
+ }
+@@ -935,9 +936,9 @@ static byte* skip_Utf8_chars(byte* cp, i
+ int ch = *cp & 0xFF;
+ if ((ch & 0xC0) != 0x80) {
+ if (len-- == 0)
+- return cp;
++ return cp;
+ if (ch < 0x80 && len == 0)
+- return cp+1;
++ return cp+1;
+ }
+ }
+ }
+@@ -963,9 +964,9 @@ static int compare_Utf8_chars(bytes& b1,
+ if (c1 == 0xC0 && (p1[i+1] & 0xFF) == 0x80) c1 = 0;
+ if (c2 == 0xC0 && (p2[i+1] & 0xFF) == 0x80) c2 = 0;
+ if (c0 == 0xC0) {
+- assert(((c1|c2) & 0xC0) == 0x80); // c1 & c2 are extension chars
+- if (c1 == 0x80) c1 = 0; // will sort below c2
+- if (c2 == 0x80) c2 = 0; // will sort below c1
++ assert(((c1|c2) & 0xC0) == 0x80); // c1 & c2 are extension chars
++ if (c1 == 0x80) c1 = 0; // will sort below c2
++ if (c2 == 0x80) c2 = 0; // will sort below c1
+ }
+ return c1 - c2;
+ }
+@@ -1024,9 +1025,9 @@ void unpacker::read_Utf8_values(entry* c
+ chars.malloc(size3);
+ } else {
+ if (!charbuf.canAppend(size3+1)) {
+- assert(charbuf.allocated == 0 || tmallocs.contains(charbuf.base()));
+- charbuf.init(CHUNK); // Reset to new buffer.
+- tmallocs.add(charbuf.base());
++ assert(charbuf.allocated == 0 || tmallocs.contains(charbuf.base()));
++ charbuf.init(CHUNK); // Reset to new buffer.
++ tmallocs.add(charbuf.base());
+ }
+ chars.set(charbuf.grow(size3+1), size3);
+ }
+@@ -1191,9 +1192,9 @@ void unpacker::read_single_refs(band& cp
+ // Maintain cross-reference:
+ entry* &htref = cp.hashTabRef(indexTag, e.value.b);
+ if (htref == null) {
+- // Note that if two identical classes are transmitted,
+- // the first is taken to be the canonical one.
+- htref = &e;
++ // Note that if two identical classes are transmitted,
++ // the first is taken to be the canonical one.
++ htref = &e;
+ }
+ }
+ }
+@@ -1202,7 +1203,7 @@ void unpacker::read_single_refs(band& cp
+
+ maybe_inline
+ void unpacker::read_double_refs(band& cp_band, byte ref1Tag, byte ref2Tag,
+- entry* cpMap, int len) {
++ entry* cpMap, int len) {
+ band& cp_band1 = cp_band;
+ band& cp_band2 = cp_band.nextBand();
+ cp_band1.setIndexByTag(ref1Tag);
+@@ -1214,6 +1215,7 @@ void unpacker::read_double_refs(band& cp
+ entry& e = cpMap[i];
+ e.refs = U_NEW(entry*, e.nrefs = 2);
+ e.refs[0] = cp_band1.getRef();
++ CHECK;
+ e.refs[1] = cp_band2.getRef();
+ CHECK;
+ }
+@@ -1302,23 +1304,23 @@ void unpacker::read_cp() {
+ break;
+ case CONSTANT_NameandType:
+ read_double_refs(cp_Descr_name /*& cp_Descr_type*/,
+- CONSTANT_Utf8, CONSTANT_Signature,
+- cpMap, len);
++ CONSTANT_Utf8, CONSTANT_Signature,
++ cpMap, len);
+ break;
+ case CONSTANT_Fieldref:
+ read_double_refs(cp_Field_class /*& cp_Field_desc*/,
+- CONSTANT_Class, CONSTANT_NameandType,
+- cpMap, len);
++ CONSTANT_Class, CONSTANT_NameandType,
++ cpMap, len);
+ break;
+ case CONSTANT_Methodref:
+ read_double_refs(cp_Method_class /*& cp_Method_desc*/,
+- CONSTANT_Class, CONSTANT_NameandType,
+- cpMap, len);
++ CONSTANT_Class, CONSTANT_NameandType,
++ cpMap, len);
+ break;
+ case CONSTANT_InterfaceMethodref:
+ read_double_refs(cp_Imethod_class /*& cp_Imethod_desc*/,
+- CONSTANT_Class, CONSTANT_NameandType,
+- cpMap, len);
++ CONSTANT_Class, CONSTANT_NameandType,
++ cpMap, len);
+ break;
+ default:
+ assert(false);
+@@ -1384,8 +1386,8 @@ inline
+ inline
+ unpacker::layout_definition*
+ unpacker::attr_definitions::defineLayout(int idx,
+- entry* nameEntry,
+- const char* layout) {
++ entry* nameEntry,
++ const char* layout) {
+ const char* name = nameEntry->value.b.strval();
+ layout_definition* lo = defineLayout(idx, name, layout);
+ CHECK_0;
+@@ -1395,8 +1397,8 @@ unpacker::attr_definitions::defineLayout
+
+ unpacker::layout_definition*
+ unpacker::attr_definitions::defineLayout(int idx,
+- const char* name,
+- const char* layout) {
++ const char* name,
++ const char* layout) {
+ assert(flag_limit != 0); // must be set up already
+ if (idx >= 0) {
+ // Fixed attr.
+@@ -1419,12 +1421,12 @@ unpacker::attr_definitions::defineLayout
+ }
+ CHECK_0;
+ layouts.get(idx) = lo;
+- return lo;
++ return lo;
+ }
+
+ band**
+ unpacker::attr_definitions::buildBands(unpacker::layout_definition* lo) {
+- int i;
++ int i;
+ if (lo->elems != null)
+ return lo->bands();
+ if (lo->layout[0] == '\0') {
+@@ -1448,11 +1450,11 @@ unpacker::attr_definitions::buildBands(u
+ int num_callables = 0;
+ if (hasCallables) {
+ while (bands[num_callables] != null) {
+- if (bands[num_callables]->le_kind != EK_CBLE) {
+- abort("garbage mixed with callables");
+- break;
+- }
+- num_callables += 1;
++ if (bands[num_callables]->le_kind != EK_CBLE) {
++ abort("garbage mixed with callables");
++ break;
++ }
++ num_callables += 1;
+ }
+ }
+ for (i = 0; i < calls_to_link.length(); i++) {
+@@ -1461,8 +1463,8 @@ unpacker::attr_definitions::buildBands(u
+ // Determine the callee.
+ int call_num = call.le_len;
+ if (call_num < 0 || call_num >= num_callables) {
+- abort("bad call in layout");
+- break;
++ abort("bad call in layout");
++ break;
+ }
+ band& cble = *bands[call_num];
+ // Link the call to it.
+@@ -1540,7 +1542,7 @@ unpacker::attr_definitions::buildBands(u
+
+ const char*
+ unpacker::attr_definitions::parseIntLayout(const char* lp, band* &res,
+- byte le_kind, bool can_be_signed) {
++ byte le_kind, bool can_be_signed) {
+ const char* lp0 = lp;
+ band* b = U_NEW(band, 1);
+ CHECK_(lp);
+@@ -1619,7 +1621,7 @@ unpacker::attr_definitions::popBody(int
+
+ const char*
+ unpacker::attr_definitions::parseLayout(const char* lp, band** &res,
+- int curCble) {
++ int curCble) {
+ const char* lp0 = lp;
+ int bs_base = band_stack.length();
+ bool top_level = (bs_base == 0);
+@@ -1636,18 +1638,18 @@ unpacker::attr_definitions::parseLayout(
+ break;
+ case 'P':
+ {
+- int le_bci = EK_BCI;
+- if (*lp == 'O') {
+- ++lp;
+- le_bci = EK_BCID;
+- }
+- assert(*lp != 'S'); // no PSH, etc.
+- lp = parseIntLayout(lp, b, EK_INT);
+- b->le_bci = le_bci;
+- if (le_bci == EK_BCI)
+- b->defc = coding::findBySpec(BCI5_spec);
+- else
+- b->defc = coding::findBySpec(BRANCH5_spec);
++ int le_bci = EK_BCI;
++ if (*lp == 'O') {
++ ++lp;
++ le_bci = EK_BCID;
++ }
++ assert(*lp != 'S'); // no PSH, etc.
++ lp = parseIntLayout(lp, b, EK_INT);
++ b->le_bci = le_bci;
++ if (le_bci == EK_BCI)
++ b->defc = coding::findBySpec(BCI5_spec);
++ else
++ b->defc = coding::findBySpec(BRANCH5_spec);
+ }
+ break;
+ case 'O':
+@@ -1665,25 +1667,25 @@ unpacker::attr_definitions::parseLayout(
+ case 'T': // union: 'T' any_int union_case* '(' ')' '[' body ']'
+ lp = parseIntLayout(lp, b, EK_UN, can_be_signed);
+ {
+- int union_base = band_stack.length();
+- for (;;) { // for each case
+- band& k_case = *U_NEW(band, 1);
+- CHECK_(lp);
+- band_stack.add(&k_case);
+- k_case.le_kind = EK_CASE;
+- k_case.bn = bands_made++;
+- if (*lp++ != '(') {
+- abort("bad union case");
+- return "";
+- }
+- if (*lp++ != ')') {
+- --lp; // reparse
+- // Read some case values. (Use band_stack for temp. storage.)
+- int case_base = band_stack.length();
+- for (;;) {
+- int caseval = 0;
+- lp = parseNumeral(lp, caseval);
+- band_stack.add((void*)caseval);
++ int union_base = band_stack.length();
++ for (;;) { // for each case
++ band& k_case = *U_NEW(band, 1);
++ CHECK_(lp);
++ band_stack.add(&k_case);
++ k_case.le_kind = EK_CASE;
++ k_case.bn = bands_made++;
++ if (*lp++ != '(') {
++ abort("bad union case");
++ return "";
++ }
++ if (*lp++ != ')') {
++ --lp; // reparse
++ // Read some case values. (Use band_stack for temp. storage.)
++ int case_base = band_stack.length();
++ for (;;) {
++ int caseval = 0;
++ lp = parseNumeral(lp, caseval);
++ band_stack.add((void*)caseval);
+ if (*lp == '-') {
+ // new in version 160, allow (1-5) for (1,2,3,4,5)
+ if (u->majver < JAVA6_PACKAGE_MAJOR_VERSION) {
+@@ -1706,111 +1708,111 @@ unpacker::attr_definitions::parseLayout(
+ if (caseval == caselimit) break;
+ }
+ }
+- if (*lp != ',') break;
+- lp++;
+- }
+- if (*lp++ != ')') {
+- abort("bad case label");
+- return "";
+- }
+- // save away the case labels
+- int ntags = band_stack.length() - case_base;
+- int* tags = U_NEW(int, add_size(ntags, 1));
+- CHECK_(lp);
+- k_case.le_casetags = tags;
+- *tags++ = ntags;
+- for (int i = 0; i < ntags; i++) {
+- *tags++ = ptrlowbits(band_stack.get(case_base+i));
+- }
+- band_stack.popTo(case_base);
+- CHECK_(lp);
+- }
+- // Got le_casetags. Now grab the body.
+- assert(*lp == '[');
+- ++lp;
+- lp = parseLayout(lp, k_case.le_body, curCble);
+- CHECK_(lp);
+- if (k_case.le_casetags == null) break; // done
+- }
+- b->le_body = popBody(union_base);
++ if (*lp != ',') break;
++ lp++;
++ }
++ if (*lp++ != ')') {
++ abort("bad case label");
++ return "";
++ }
++ // save away the case labels
++ int ntags = band_stack.length() - case_base;
++ int* tags = U_NEW(int, add_size(ntags, 1));
++ CHECK_(lp);
++ k_case.le_casetags = tags;
++ *tags++ = ntags;
++ for (int i = 0; i < ntags; i++) {
++ *tags++ = ptrlowbits(band_stack.get(case_base+i));
++ }
++ band_stack.popTo(case_base);
++ CHECK_(lp);
++ }
++ // Got le_casetags. Now grab the body.
++ assert(*lp == '[');
++ ++lp;
++ lp = parseLayout(lp, k_case.le_body, curCble);
++ CHECK_(lp);
++ if (k_case.le_casetags == null) break; // done
++ }
++ b->le_body = popBody(union_base);
+ }
+ break;
+ case '(': // call: '(' -?NN* ')'
+ {
+- band& call = *U_NEW(band, 1);
+- CHECK_(lp);
+- band_stack.add(&call);
+- call.le_kind = EK_CALL;
+- call.bn = bands_made++;
+- call.le_body = U_NEW(band*, 2); // fill in later
+- int call_num = 0;
+- lp = parseNumeral(lp, call_num);
+- call.le_back = (call_num <= 0);
+- call_num += curCble; // numeral is self-relative offset
+- call.le_len = call_num; //use le_len as scratch
+- calls_to_link.add(&call);
+- CHECK_(lp);
+- if (*lp++ != ')') {
+- abort("bad call label");
+- return "";
++ band& call = *U_NEW(band, 1);
++ CHECK_(lp);
++ band_stack.add(&call);
++ call.le_kind = EK_CALL;
++ call.bn = bands_made++;
++ call.le_body = U_NEW(band*, 2); // fill in later
++ int call_num = 0;
++ lp = parseNumeral(lp, call_num);
++ call.le_back = (call_num <= 0);
++ call_num += curCble; // numeral is self-relative offset
++ call.le_len = call_num; //use le_len as scratch
++ calls_to_link.add(&call);
++ CHECK_(lp);
++ if (*lp++ != ')') {
++ abort("bad call label");
++ return "";
+ }
+ }
+ break;
+ case 'K': // reference_type: constant_ref
+ case 'R': // reference_type: schema_ref
+ {
+- int ixTag = CONSTANT_None;
+- if (lp[-1] == 'K') {
+- switch (*lp++) {
+- case 'I': ixTag = CONSTANT_Integer; break;
+- case 'J': ixTag = CONSTANT_Long; break;
+- case 'F': ixTag = CONSTANT_Float; break;
+- case 'D': ixTag = CONSTANT_Double; break;
+- case 'S': ixTag = CONSTANT_String; break;
+- case 'Q': ixTag = CONSTANT_Literal; break;
+- }
+- } else {
+- switch (*lp++) {
+- case 'C': ixTag = CONSTANT_Class; break;
+- case 'S': ixTag = CONSTANT_Signature; break;
+- case 'D': ixTag = CONSTANT_NameandType; break;
+- case 'F': ixTag = CONSTANT_Fieldref; break;
+- case 'M': ixTag = CONSTANT_Methodref; break;
+- case 'I': ixTag = CONSTANT_InterfaceMethodref; break;
+- case 'U': ixTag = CONSTANT_Utf8; break; //utf8_ref
+- case 'Q': ixTag = CONSTANT_All; break; //untyped_ref
+- }
+- }
+- if (ixTag == CONSTANT_None) {
+- abort("bad reference layout");
+- break;
+- }
+- bool nullOK = false;
+- if (*lp == 'N') {
+- nullOK = true;
+- lp++;
+- }
+- lp = parseIntLayout(lp, b, EK_REF);
+- b->defc = coding::findBySpec(UNSIGNED5_spec);
+- b->initRef(ixTag, nullOK);
++ int ixTag = CONSTANT_None;
++ if (lp[-1] == 'K') {
++ switch (*lp++) {
++ case 'I': ixTag = CONSTANT_Integer; break;
++ case 'J': ixTag = CONSTANT_Long; break;
++ case 'F': ixTag = CONSTANT_Float; break;
++ case 'D': ixTag = CONSTANT_Double; break;
++ case 'S': ixTag = CONSTANT_String; break;
++ case 'Q': ixTag = CONSTANT_Literal; break;
++ }
++ } else {
++ switch (*lp++) {
++ case 'C': ixTag = CONSTANT_Class; break;
++ case 'S': ixTag = CONSTANT_Signature; break;
++ case 'D': ixTag = CONSTANT_NameandType; break;
++ case 'F': ixTag = CONSTANT_Fieldref; break;
++ case 'M': ixTag = CONSTANT_Methodref; break;
++ case 'I': ixTag = CONSTANT_InterfaceMethodref; break;
++ case 'U': ixTag = CONSTANT_Utf8; break; //utf8_ref
++ case 'Q': ixTag = CONSTANT_All; break; //untyped_ref
++ }
++ }
++ if (ixTag == CONSTANT_None) {
++ abort("bad reference layout");
++ break;
++ }
++ bool nullOK = false;
++ if (*lp == 'N') {
++ nullOK = true;
++ lp++;
++ }
++ lp = parseIntLayout(lp, b, EK_REF);
++ b->defc = coding::findBySpec(UNSIGNED5_spec);
++ b->initRef(ixTag, nullOK);
+ }
+ break;
+ case '[':
+ {
+- // [callable1][callable2]...
+- if (!top_level) {
+- abort("bad nested callable");
+- break;
+- }
+- curCble += 1;
+- NOT_PRODUCT(int call_num = band_stack.length() - bs_base);
+- band& cble = *U_NEW(band, 1);
+- CHECK_(lp);
+- band_stack.add(&cble);
+- cble.le_kind = EK_CBLE;
+- NOT_PRODUCT(cble.le_len = call_num);
+- cble.bn = bands_made++;
+- lp = parseLayout(lp, cble.le_body, curCble);
++ // [callable1][callable2]...
++ if (!top_level) {
++ abort("bad nested callable");
++ break;
++ }
++ curCble += 1;
++ NOT_PRODUCT(int call_num = band_stack.length() - bs_base);
++ band& cble = *U_NEW(band, 1);
++ CHECK_(lp);
++ band_stack.add(&cble);
++ cble.le_kind = EK_CBLE;
++ NOT_PRODUCT(cble.le_len = call_num);
++ cble.bn = bands_made++;
++ lp = parseLayout(lp, cble.le_body, curCble);
+ }
+ break;
+ case ']':
+@@ -1880,10 +1882,10 @@ void unpacker::read_attr_defs() {
+ "(115)[RUH]"
+ "(91)[NH[(0)]]"
+ "(64)["
+- // nested annotation:
+- "RSH"
+- "NH[RUH(0)]"
+- "]"
++ // nested annotation:
++ "RSH"
++ "NH[RUH(0)]"
++ "]"
+ "()[]"
+ "]"
+ );
+@@ -1897,16 +1899,16 @@ void unpacker::read_attr_defs() {
+ for (i = 0; i < ATTR_CONTEXT_LIMIT; i++) {
+ attr_definitions& ad = attr_defs[i];
+ ad.defineLayout(X_ATTR_RuntimeVisibleAnnotations,
+- "RuntimeVisibleAnnotations", md_layout_A);
++ "RuntimeVisibleAnnotations", md_layout_A);
+ ad.defineLayout(X_ATTR_RuntimeInvisibleAnnotations,
+- "RuntimeInvisibleAnnotations", md_layout_A);
++ "RuntimeInvisibleAnnotations", md_layout_A);
+ if (i != ATTR_CONTEXT_METHOD) continue;
+ ad.defineLayout(METHOD_ATTR_RuntimeVisibleParameterAnnotations,
+- "RuntimeVisibleParameterAnnotations", md_layout_P);
++ "RuntimeVisibleParameterAnnotations", md_layout_P);
+ ad.defineLayout(METHOD_ATTR_RuntimeInvisibleParameterAnnotations,
+- "RuntimeInvisibleParameterAnnotations", md_layout_P);
++ "RuntimeInvisibleParameterAnnotations", md_layout_P);
+ ad.defineLayout(METHOD_ATTR_AnnotationDefault,
+- "AnnotationDefault", md_layout_V);
++ "AnnotationDefault", md_layout_V);
+ }
+
+ attr_definition_headers.readData(attr_definition_count);
+@@ -1939,6 +1941,7 @@ void unpacker::read_attr_defs() {
+ int attrc = ADH_BYTE_CONTEXT(header);
+ int idx = ADH_BYTE_INDEX(header);
+ entry* name = attr_definition_name.getRef();
++ CHECK;
+ entry* layout = attr_definition_layout.getRef();
+ CHECK;
+ attr_defs[attrc].defineLayout(idx, name, layout->value.b.strval());
+@@ -2043,7 +2046,9 @@ void unpacker::read_ics() {
+ if (ics[i].name == NO_ENTRY_YET) {
+ // Long form.
+ ics[i].outer = ic_outer_class.getRefN();
++ CHECK;
+ ics[i].name = ic_name.getRefN();
++ CHECK;
+ } else {
+ // Fill in outer and name based on inner.
+ bytes& n = ics[i].inner->value.b;
+@@ -2058,48 +2063,48 @@ void unpacker::read_ics() {
+ int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, nlen) + 1;
+ dollar2 = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, nlen);
+ if (dollar2 < 0) {
+- abort();
+- return;
++ abort();
++ return;
+ }
+ assert(dollar2 >= pkglen);
+ if (isDigitString(n, dollar2+1, nlen)) {
+- // n = (<pkg>/)*<outer>$<number>
+- number = n.slice(dollar2+1, nlen);
+- name.set(null,0);
+- dollar1 = dollar2;
++ // n = (<pkg>/)*<outer>$<number>
++ number = n.slice(dollar2+1, nlen);
++ name.set(null,0);
++ dollar1 = dollar2;
+ } else if (pkglen < (dollar1
+- = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, dollar2-1))
+- && isDigitString(n, dollar1+1, dollar2)) {
+- // n = (<pkg>/)*<outer>$<number>$<name>
+- number = n.slice(dollar1+1, dollar2);
+- name = n.slice(dollar2+1, nlen);
++ = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, n, dollar2-1))
++ && isDigitString(n, dollar1+1, dollar2)) {
++ // n = (<pkg>/)*<outer>$<number>$<name>
++ number = n.slice(dollar1+1, dollar2);
++ name = n.slice(dollar2+1, nlen);
+ } else {
+- // n = (<pkg>/)*<outer>$<name>
+- dollar1 = dollar2;
+- number.set(null,0);
+- name = n.slice(dollar2+1, nlen);
++ // n = (<pkg>/)*<outer>$<name>
++ dollar1 = dollar2;
++ number.set(null,0);
++ name = n.slice(dollar2+1, nlen);
+ }
+ if (number.ptr == null)
+- pkgOuter = n.slice(0, dollar1);
++ pkgOuter = n.slice(0, dollar1);
+ else
+- pkgOuter.set(null,0);
++ pkgOuter.set(null,0);
+ printcr(5,"=> %s$ 0%s $%s",
+- pkgOuter.string(), number.string(), name.string());
++ pkgOuter.string(), number.string(), name.string());
+
+ if (pkgOuter.ptr != null)
+- ics[i].outer = cp.ensureClass(pkgOuter);
++ ics[i].outer = cp.ensureClass(pkgOuter);
+
+ if (name.ptr != null)
+- ics[i].name = cp.ensureUtf8(name);
++ ics[i].name = cp.ensureUtf8(name);
+ }
+
+ // update child/sibling list
+ if (ics[i].outer != null) {
+ uint outord = ics[i].outer->inord;
+ if (outord != NO_INORD) {
+- assert(outord < cp.tag_count[CONSTANT_Class]);
+- ics[i].next_sibling = ic_child_index[outord];
+- ic_child_index[outord] = &ics[i];
++ assert(outord < cp.tag_count[CONSTANT_Class]);
++ ics[i].next_sibling = ic_child_index[outord];
++ ic_child_index[outord] = &ics[i];
+ }
+ }
+ }
+@@ -2149,7 +2154,7 @@ void unpacker::read_classes() {
+ read_code_headers();
+
+ printcr(1,"scanned %d classes, %d fields, %d methods, %d code headers",
+- class_count, field_count, method_count, code_count);
++ class_count, field_count, method_count, code_count);
+ }
+
+ maybe_inline
+@@ -2226,11 +2231,11 @@ void unpacker::read_attrs(int attrc, int
+ band** bands = ad.buildBands(lo);
+ CHECK;
+ if (lo->hasCallables()) {
+- for (i = 0; bands[i] != null; i++) {
+- if (bands[i]->le_back) {
+- assert(bands[i]->le_kind == EK_CBLE);
+- backwardCounts += 1;
+- }
++ for (i = 0; bands[i] != null; i++) {
++ if (bands[i]->le_back) {
++ assert(bands[i]->le_kind == EK_CBLE);
++ backwardCounts += 1;
++ }
+ }
+ }
+ }
+@@ -2427,7 +2432,7 @@ void unpacker::attr_definitions::readBan
+ layout_definition* lo = getLayout(idx);
+ if (lo != null) {
+ printcr(1, "counted %d [redefined = %d predefined = %d] attributes of type %s.%s",
+- count, isRedefined(idx), isPredefined(idx),
++ count, isRedefined(idx), isPredefined(idx),
+ ATTR_CONTEXT_NAME[attrc], lo->name);
+ }
+ bool hasCallables = lo->hasCallables();
+@@ -2444,10 +2449,10 @@ void unpacker::attr_definitions::readBan
+ band& j_cble = *bands[j];
+ assert(j_cble.le_kind == EK_CBLE);
+ if (j_cble.le_back) {
+- // Add in the predicted effects of backward calls, too.
+- int back_calls = xxx_attr_calls().getInt();
+- j_cble.expectMoreLength(back_calls);
+- // In a moment, more forward calls may increment j_cble.length.
++ // Add in the predicted effects of backward calls, too.
++ int back_calls = xxx_attr_calls().getInt();
++ j_cble.expectMoreLength(back_calls);
++ // In a moment, more forward calls may increment j_cble.length.
+ }
+ }
+ // Now consult whichever callables have non-zero entry counts.
+@@ -2467,38 +2472,38 @@ void unpacker::attr_definitions::readBan
+ switch (b.le_kind) {
+ case EK_REPL:
+ {
+- int reps = b.getIntTotal();
+- readBandData(b.le_body, reps);
++ int reps = b.getIntTotal();
++ readBandData(b.le_body, reps);
+ }
+ break;
+ case EK_UN:
+ {
+- int remaining = count;
+- for (k = 0; b.le_body[k] != null; k++) {
+- band& k_case = *b.le_body[k];
+- int k_count = 0;
+- if (k_case.le_casetags == null) {
+- k_count = remaining; // last (empty) case
+- } else {
+- int* tags = k_case.le_casetags;
+- int ntags = *tags++; // 1st element is length (why not?)
+- while (ntags-- > 0) {
+- int tag = *tags++;
+- k_count += b.getIntCount(tag);
+- }
+- }
+- readBandData(k_case.le_body, k_count);
+- remaining -= k_count;
+- }
+- assert(remaining == 0);
++ int remaining = count;
++ for (k = 0; b.le_body[k] != null; k++) {
++ band& k_case = *b.le_body[k];
++ int k_count = 0;
++ if (k_case.le_casetags == null) {
++ k_count = remaining; // last (empty) case
++ } else {
++ int* tags = k_case.le_casetags;
++ int ntags = *tags++; // 1st element is length (why not?)
++ while (ntags-- > 0) {
++ int tag = *tags++;
++ k_count += b.getIntCount(tag);
++ }
++ }
++ readBandData(k_case.le_body, k_count);
++ remaining -= k_count;
++ }
++ assert(remaining == 0);
+ }
+ break;
+ case EK_CALL:
+ // Push the count forward, if it is not a backward call.
+ if (!b.le_back) {
+- band& cble = *b.le_body[0];
+- assert(cble.le_kind == EK_CBLE);
+- cble.expectMoreLength(count);
++ band& cble = *b.le_body[0];
++ assert(cble.le_kind == EK_CBLE);
++ cble.expectMoreLength(count);
+ }
+ break;
+ case EK_CBLE:
+@@ -2522,12 +2527,12 @@ band** findMatchingCase(int matchTag, ba
+ int* tags = k_case.le_casetags;
+ int ntags = *tags++; // 1st element is length
+ for (; ntags > 0; ntags--) {
+- int tag = *tags++;
+- if (tag == matchTag)
+- break;
++ int tag = *tags++;
++ if (tag == matchTag)
++ break;
+ }
+ if (ntags == 0)
+- continue; // does not match
++ continue; // does not match
+ }
+ return k_case.le_body;
+ }
+@@ -2549,46 +2554,47 @@ void unpacker::putlayout(band** body) {
+ if (b.defc != null) {
+ // It has data, so unparse an element.
+ if (b.ixTag != CONSTANT_None) {
+- assert(le_kind == EK_REF);
+- if (b.ixTag == CONSTANT_Literal)
+- e = b.getRefUsing(cp.getKQIndex());
+- else
+- e = b.getRefN();
+- switch (b.le_len) {
+- case 0: break;
+- case 1: putu1ref(e); break;
+- case 2: putref(e); break;
+- case 4: putu2(0); putref(e); break;
+- default: assert(false);
+- }
++ assert(le_kind == EK_REF);
++ if (b.ixTag == CONSTANT_Literal)
++ e = b.getRefUsing(cp.getKQIndex());
++ else
++ e = b.getRefN();
++ CHECK;
++ switch (b.le_len) {
++ case 0: break;
++ case 1: putu1ref(e); break;
++ case 2: putref(e); break;
++ case 4: putu2(0); putref(e); break;
++ default: assert(false);
++ }
+ } else {
+- assert(le_kind == EK_INT || le_kind == EK_REPL || le_kind == EK_UN);
+- x = b.getInt();
+-
+- assert(!b.le_bci || prevBCI == to_bci(prevBII));
+- switch (b.le_bci) {
+- case EK_BCI: // PH: transmit R(bci), store bci
+- x = to_bci(prevBII = x);
+- prevBCI = x;
+- break;
+- case EK_BCID: // POH: transmit D(R(bci)), store bci
+- x = to_bci(prevBII += x);
+- prevBCI = x;
+- break;
+- case EK_BCO: // OH: transmit D(R(bci)), store D(bci)
+- x = to_bci(prevBII += x) - prevBCI;
+- prevBCI += x;
+- break;
+- }
+- assert(!b.le_bci || prevBCI == to_bci(prevBII));
+-
+- switch (b.le_len) {
+- case 0: break;
+- case 1: putu1(x); break;
+- case 2: putu2(x); break;
+- case 4: putu4(x); break;
+- default: assert(false);
+- }
++ assert(le_kind == EK_INT || le_kind == EK_REPL || le_kind == EK_UN);
++ x = b.getInt();
++
++ assert(!b.le_bci || prevBCI == to_bci(prevBII));
++ switch (b.le_bci) {
++ case EK_BCI: // PH: transmit R(bci), store bci
++ x = to_bci(prevBII = x);
++ prevBCI = x;
++ break;
++ case EK_BCID: // POH: transmit D(R(bci)), store bci
++ x = to_bci(prevBII += x);
++ prevBCI = x;
++ break;
++ case EK_BCO: // OH: transmit D(R(bci)), store D(bci)
++ x = to_bci(prevBII += x) - prevBCI;
++ prevBCI += x;
++ break;
++ }
++ assert(!b.le_bci || prevBCI == to_bci(prevBII));
++
++ switch (b.le_len) {
++ case 0: break;
++ case 1: putu1(x); break;
++ case 2: putu2(x); break;
++ case 4: putu4(x); break;
++ default: assert(false);
++ }
+ }
+ }
+
+@@ -2597,7 +2603,7 @@ void unpacker::putlayout(band** body) {
+ case EK_REPL:
+ // x is the repeat count
+ while (x-- > 0) {
+- putlayout(b.le_body);
++ putlayout(b.le_body);
+ }
+ break;
+ case EK_UN:
+@@ -2606,10 +2612,10 @@ void unpacker::putlayout(band** body) {
+ break;
+ case EK_CALL:
+ {
+- band& cble = *b.le_body[0];
+- assert(cble.le_kind == EK_CBLE);
+- assert(cble.le_len == b.le_len);
+- putlayout(cble.le_body);
++ band& cble = *b.le_body[0];
++ assert(cble.le_kind == EK_CBLE);
++ assert(cble.le_len == b.le_len);
++ putlayout(cble.le_body);
+ }
+ break;
+
+@@ -2635,7 +2641,7 @@ void unpacker::read_files() {
+ // FO_IS_CLASS_STUB might be set, causing overlap between classes and files
+ for (int i = 0; i < file_count; i++) {
+ if ((file_options.getInt() & FO_IS_CLASS_STUB) != 0) {
+- allFiles -= 1; // this one counts as both class and file
++ allFiles -= 1; // this one counts as both class and file
+ }
+ }
+ file_options.rewind();
+@@ -2646,9 +2652,9 @@ void unpacker::read_files() {
+
+ maybe_inline
+ void unpacker::get_code_header(int& max_stack,
+- int& max_na_locals,
+- int& handler_count,
+- int& cflags) {
++ int& max_na_locals,
++ int& handler_count,
++ int& cflags) {
+ int sc = code_headers.getByte();
+ if (sc == 0) {
+ max_stack = max_na_locals = handler_count = cflags = -1;
+@@ -2801,7 +2807,7 @@ inline // called exactly once => inline
+ inline // called exactly once => inline
+ void unpacker::read_bcs() {
+ printcr(3, "reading compressed bytecodes and operands for %d codes...",
+- code_count);
++ code_count);
+
+ // read from bc_codes and bc_case_count
+ fillbytes all_switch_ops;
+@@ -2822,80 +2828,80 @@ void unpacker::read_bcs() {
+ // Scan one method:
+ for (;;) {
+ if (opptr+2 > oplimit) {
+- rp = opptr;
+- ensure_input(2);
+- oplimit = rplimit;
+- rp = rp0; // back up
++ rp = opptr;
++ ensure_input(2);
++ oplimit = rplimit;
++ rp = rp0; // back up
+ }
+ if (opptr == oplimit) { abort(); break; }
+ int bc = *opptr++ & 0xFF;
+ bool isWide = false;
+ if (bc == bc_wide) {
+- if (opptr == oplimit) { abort(); break; }
+- bc = *opptr++ & 0xFF;
+- isWide = true;
++ if (opptr == oplimit) { abort(); break; }
++ bc = *opptr++ & 0xFF;
++ isWide = true;
+ }
+ // Adjust expectations of various band sizes.
+ switch (bc) {
+ case bc_tableswitch:
+ case bc_lookupswitch:
+- all_switch_ops.addByte(bc);
+- break;
++ all_switch_ops.addByte(bc);
++ break;
+ case bc_iinc:
+- bc_local.expectMoreLength(1);
+- bc_which = isWide ? &bc_short : &bc_byte;
+- bc_which->expectMoreLength(1);
+- break;
++ bc_local.expectMoreLength(1);
++ bc_which = isWide ? &bc_short : &bc_byte;
++ bc_which->expectMoreLength(1);
++ break;
+ case bc_sipush:
+- bc_short.expectMoreLength(1);
+- break;
++ bc_short.expectMoreLength(1);
++ break;
+ case bc_bipush:
+- bc_byte.expectMoreLength(1);
+- break;
++ bc_byte.expectMoreLength(1);
++ break;
+ case bc_newarray:
+- bc_byte.expectMoreLength(1);
+- break;
++ bc_byte.expectMoreLength(1);
++ break;
+ case bc_multianewarray:
+- assert(ref_band_for_op(bc) == &bc_classref);
+- bc_classref.expectMoreLength(1);
+- bc_byte.expectMoreLength(1);
+- break;
++ assert(ref_band_for_op(bc) == &bc_classref);
++ bc_classref.expectMoreLength(1);
++ bc_byte.expectMoreLength(1);
++ break;
+ case bc_ref_escape:
+- bc_escrefsize.expectMoreLength(1);
+- bc_escref.expectMoreLength(1);
+- break;
++ bc_escrefsize.expectMoreLength(1);
++ bc_escref.expectMoreLength(1);
++ break;
+ case bc_byte_escape:
+- bc_escsize.expectMoreLength(1);
+- // bc_escbyte will have to be counted too
+- break;
++ bc_escsize.expectMoreLength(1);
++ // bc_escbyte will have to be counted too
++ break;
+ default:
+- if (is_invoke_init_op(bc)) {
+- bc_initref.expectMoreLength(1);
+- break;
+- }
+- bc_which = ref_band_for_self_op(bc, isAload, junkBC);
+- if (bc_which != null) {
+- bc_which->expectMoreLength(1);
+- break;
+- }
+- if (is_branch_op(bc)) {
+- bc_label.expectMoreLength(1);
+- break;
+- }
+- bc_which = ref_band_for_op(bc);
+- if (bc_which != null) {
+- bc_which->expectMoreLength(1);
+- assert(bc != bc_multianewarray); // handled elsewhere
+- break;
+- }
+- if (is_local_slot_op(bc)) {
+- bc_local.expectMoreLength(1);
+- break;
+- }
+- break;
++ if (is_invoke_init_op(bc)) {
++ bc_initref.expectMoreLength(1);
++ break;
++ }
++ bc_which = ref_band_for_self_op(bc, isAload, junkBC);
++ if (bc_which != null) {
++ bc_which->expectMoreLength(1);
++ break;
++ }
++ if (is_branch_op(bc)) {
++ bc_label.expectMoreLength(1);
++ break;
++ }
++ bc_which = ref_band_for_op(bc);
++ if (bc_which != null) {
++ bc_which->expectMoreLength(1);
++ assert(bc != bc_multianewarray); // handled elsewhere
++ break;
++ }
++ if (is_local_slot_op(bc)) {
++ bc_local.expectMoreLength(1);
++ break;
++ }
++ break;
+ case bc_end_marker:
+- // Increment k and test against code_count.
+- goto doneScanningMethod;
++ // Increment k and test against code_count.
++ goto doneScanningMethod;
+ }
+ }
+ doneScanningMethod:{}
+@@ -2929,15 +2935,15 @@ void unpacker::read_bcs() {
+ bc_escbyte.readData(bc_escsize.getIntTotal());
+
+ printcr(3, "scanned %d opcode and %d operand bytes for %d codes...",
+- (int)(bc_codes.size()),
+- (int)(bc_escsize.maxRP() - bc_case_value.minRP()),
+- code_count);
++ (int)(bc_codes.size()),
++ (int)(bc_escsize.maxRP() - bc_case_value.minRP()),
++ code_count);
+ }
+
+ void unpacker::read_bands() {
+ byte* rp0 = rp;
+ int i;
+-
++ CHECK;
+ read_file_header();
+ CHECK;
+
+@@ -3063,8 +3069,8 @@ void cpool::expandSignatures() {
+ int c = form.ptr[j];
+ buf.addByte(c);
+ if (c == 'L') {
+- entry* cls = e.refs[refnum++];
+- buf.append(cls->className()->asUtf8());
++ entry* cls = e.refs[refnum++];
++ buf.append(cls->className()->asUtf8());
+ }
+ }
+ assert(refnum == e.nrefs);
+@@ -3099,7 +3105,7 @@ void cpool::expandSignatures() {
+ for (int j = 0; j < e.nrefs; j++) {
+ entry*& e2 = e.refs[j];
+ if (e2 != null && e2->tag == CONSTANT_Signature)
+- e2 = e2->refs[0];
++ e2 = e2->refs[0];
+ }
+ }
+ }
+@@ -3141,14 +3147,14 @@ void cpool::initMemberIndexes() {
+ int fc = field_counts[i];
+ int mc = method_counts[i];
+ all_indexes[i*2+0].init(fc, field_ix+fbase,
+- CONSTANT_Fieldref + SUBINDEX_BIT);
++ CONSTANT_Fieldref + SUBINDEX_BIT);
+ all_indexes[i*2+1].init(mc, method_ix+mbase,
+- CONSTANT_Methodref + SUBINDEX_BIT);
++ CONSTANT_Methodref + SUBINDEX_BIT);
+ // reuse field_counts and member_counts as fill pointers:
+ field_counts[i] = fbase;
+ method_counts[i] = mbase;
+ printcr(3, "class %d fields @%d[%d] methods @%d[%d]",
+- i, fbase, fc, mbase, mc);
++ i, fbase, fc, mbase, mc);
+ fbase += fc+1;
+ mbase += mc+1;
+ // (the +1 leaves a space between every subarray)
+@@ -3178,7 +3184,7 @@ void cpool::initMemberIndexes() {
+ cpindex* fix = getFieldIndex(cls);
+ cpindex* mix = getMethodIndex(cls);
+ printcr(2, "field and method index for %s [%d] [%d]",
+- cls->string(), mix->len, fix->len);
++ cls->string(), mix->len, fix->len);
+ prevord = -1;
+ for (j = 0, len = fix->len; j < len; j++) {
+ entry* f = fix->get(j);
+@@ -3204,7 +3210,7 @@ void cpool::initMemberIndexes() {
+ }
+ assert(fvisited == nfields);
+ assert(mvisited == nmethods);
+-#endif
++#endif
+
+ // Free intermediate buffers.
+ u->free_temps();
+@@ -3438,8 +3444,8 @@ bool unpacker::set_option(const char* pr
+ bool unpacker::set_option(const char* prop, const char* value) {
+ if (prop == NULL) return false;
+ if (strcmp(prop, UNPACK_DEFLATE_HINT) == 0) {
+- deflate_hint_or_zero = ( (value == null || strcmp(value, "keep") == 0)
+- ? 0: BOOL_TF(value) ? +1: -1);
++ deflate_hint_or_zero = ( (value == null || strcmp(value, "keep") == 0)
++ ? 0: BOOL_TF(value) ? +1: -1);
+ #ifdef HAVE_STRIP
+ } else if (strcmp(prop, UNPACK_STRIP_COMPILE) == 0) {
+ strip_compile = STR_TF(value);
+@@ -3466,7 +3472,7 @@ bool unpacker::set_option(const char* pr
+ } else {
+ modification_time_or_zero = atoi(value);
+ if (modification_time_or_zero == 0)
+- modification_time_or_zero = 1; // make non-zero
++ modification_time_or_zero = 1; // make non-zero
+ }
+ } else if (strcmp(prop, UNPACK_LOG_FILE) == 0) {
+ log_file = (value == null)? value: saveStr(value);
+@@ -3597,14 +3603,16 @@ void unpacker::dump_options() {
+
+
+ // Usage: unpack a byte buffer
+-// packptr is a reference to byte buffer containing a
++// packptr is a reference to byte buffer containing a
+ // packed file and len is the length of the buffer.
+ // If null, the callback is used to fill an internal buffer.
+ void unpacker::start(void* packptr, size_t len) {
++ CHECK;
+ NOT_PRODUCT(debug_u = this);
+ if (packptr != null && len != 0) {
+ inbytes.set((byte*) packptr, len);
+ }
++ CHECK;
+ read_bands();
+ }
+
+@@ -3735,6 +3743,7 @@ void unpacker::write_bc_ops() {
+ NOT_PRODUCT(bc_superfield.setIndex(null));
+ NOT_PRODUCT(bc_supermethod.setIndex(null));
+ }
++ CHECK;
+
+ for (int curIP = 0; ; curIP++) {
+ int curPC = wpoffset() - codeBase;
+@@ -3760,196 +3769,197 @@ void unpacker::write_bc_ops() {
+ case bc_tableswitch: // apc: (df, lo, hi, (hi-lo+1)*(label))
+ case bc_lookupswitch: // apc: (df, nc, nc*(case, label))
+ {
+- int caseCount = bc_case_count.getInt();
+- while (((wpoffset() - codeBase) % 4) != 0) putu1_fast(0);
+- ensure_put_space(30 + caseCount*8);
+- put_label(curIP, 4); //int df = bc_label.getInt();
+- if (bc == bc_tableswitch) {
+- int lo = bc_case_value.getInt();
+- int hi = lo + caseCount-1;
+- putu4(lo);
+- putu4(hi);
+- for (int j = 0; j < caseCount; j++) {
+- put_label(curIP, 4); //int lVal = bc_label.getInt();
+- //int cVal = lo + j;
+- }
+- } else {
+- putu4(caseCount);
+- for (int j = 0; j < caseCount; j++) {
+- int cVal = bc_case_value.getInt();
+- putu4(cVal);
+- put_label(curIP, 4); //int lVal = bc_label.getInt();
+- }
+- }
+- assert(to_bci(curIP) == curPC);
+- continue;
++ int caseCount = bc_case_count.getInt();
++ while (((wpoffset() - codeBase) % 4) != 0) putu1_fast(0);
++ ensure_put_space(30 + caseCount*8);
++ put_label(curIP, 4); //int df = bc_label.getInt();
++ if (bc == bc_tableswitch) {
++ int lo = bc_case_value.getInt();
++ int hi = lo + caseCount-1;
++ putu4(lo);
++ putu4(hi);
++ for (int j = 0; j < caseCount; j++) {
++ put_label(curIP, 4); //int lVal = bc_label.getInt();
++ //int cVal = lo + j;
++ }
++ } else {
++ putu4(caseCount);
++ for (int j = 0; j < caseCount; j++) {
++ int cVal = bc_case_value.getInt();
++ putu4(cVal);
++ put_label(curIP, 4); //int lVal = bc_label.getInt();
++ }
++ }
++ assert(to_bci(curIP) == curPC);
++ continue;
+ }
+ case bc_iinc:
+ {
+- int local = bc_local.getInt();
+- int delta = (isWide ? bc_short : bc_byte).getInt();
+- if (isWide) {
+- putu2(local);
+- putu2(delta);
+- } else {
+- putu1_fast(local);
+- putu1_fast(delta);
+- }
+- continue;
++ int local = bc_local.getInt();
++ int delta = (isWide ? bc_short : bc_byte).getInt();
++ if (isWide) {
++ putu2(local);
++ putu2(delta);
++ } else {
++ putu1_fast(local);
++ putu1_fast(delta);
++ }
++ continue;
+ }
+ case bc_sipush:
+ {
+- int val = bc_short.getInt();
+- putu2(val);
+- continue;
++ int val = bc_short.getInt();
++ putu2(val);
++ continue;
+ }
+ case bc_bipush:
+ case bc_newarray:
+ {
+- int val = bc_byte.getByte();
+- putu1_fast(val);
+- continue;
++ int val = bc_byte.getByte();
++ putu1_fast(val);
++ continue;
+ }
+ case bc_ref_escape:
+ {
+- // Note that insnMap has one entry for this.
++ // Note that insnMap has one entry for this.
+ --wp; // not really part of the code
+- int size = bc_escrefsize.getInt();
+- entry* ref = bc_escref.getRefN();
+- CHECK;
+- switch (size) {
+- case 1: putu1ref(ref); break;
+- case 2: putref(ref); break;
+- default: assert(false);
+- }
+- continue;
++ int size = bc_escrefsize.getInt();
++ entry* ref = bc_escref.getRefN();
++ CHECK;
++ switch (size) {
++ case 1: putu1ref(ref); break;
++ case 2: putref(ref); break;
++ default: assert(false);
++ }
++ continue;
+ }
+ case bc_byte_escape:
+ {
+- // Note that insnMap has one entry for all these bytes.
++ // Note that insnMap has one entry for all these bytes.
+ --wp; // not really part of the code
+- int size = bc_escsize.getInt();
+- ensure_put_space(size);
+- for (int j = 0; j < size; j++)
+- putu1_fast(bc_escbyte.getByte());
+- continue;
++ int size = bc_escsize.getInt();
++ ensure_put_space(size);
++ for (int j = 0; j < size; j++)
++ putu1_fast(bc_escbyte.getByte());
++ continue;
+ }
+ default:
+ if (is_invoke_init_op(bc)) {
+- origBC = bc_invokespecial;
+- entry* classRef;
+- switch (bc - _invokeinit_op) {
+- case _invokeinit_self_option: classRef = thisClass; break;
+- case _invokeinit_super_option: classRef = superClass; break;
+- default: assert(bc == _invokeinit_op+_invokeinit_new_option);
+- case _invokeinit_new_option: classRef = newClass; break;
+- }
+- wp[-1] = origBC; // overwrite with origBC
+- int coding = bc_initref.getInt();
+- // Find the nth overloading of <init> in classRef.
+- entry* ref = null;
+- cpindex* ix = (classRef == null)? null: cp.getMethodIndex(classRef);
+- for (int j = 0, which_init = 0; ; j++) {
+- ref = (ix == null)? null: ix->get(j);
+- if (ref == null) break; // oops, bad input
+- assert(ref->tag == CONSTANT_Methodref);
+- if (ref->memberDescr()->descrName() == cp.sym[cpool::s_lt_init_gt]) {
+- if (which_init++ == coding) break;
+- }
+- }
+- putref(ref);
+- continue;
++ origBC = bc_invokespecial;
++ entry* classRef;
++ switch (bc - _invokeinit_op) {
++ case _invokeinit_self_option: classRef = thisClass; break;
++ case _invokeinit_super_option: classRef = superClass; break;
++ default: assert(bc == _invokeinit_op+_invokeinit_new_option);
++ case _invokeinit_new_option: classRef = newClass; break;
++ }
++ wp[-1] = origBC; // overwrite with origBC
++ int coding = bc_initref.getInt();
++ // Find the nth overloading of <init> in classRef.
++ entry* ref = null;
++ cpindex* ix = cp.getMethodIndex(classRef);
++ CHECK;
++ for (int j = 0, which_init = 0; ; j++) {
++ ref = (ix == null)? null: ix->get(j);
++ if (ref == null) break; // oops, bad input
++ assert(ref->tag == CONSTANT_Methodref);
++ if (ref->memberDescr()->descrName() == cp.sym[cpool::s_lt_init_gt]) {
++ if (which_init++ == coding) break;
++ }
++ }
++ putref(ref);
++ continue;
+ }
+ bc_which = ref_band_for_self_op(bc, isAload, origBC);
+ if (bc_which != null) {
+- if (!isAload) {
+- wp[-1] = origBC; // overwrite with origBC
+- } else {
+- wp[-1] = bc_aload_0; // overwrite with _aload_0
+- // Note: insnMap keeps the _aload_0 separate.
+- bcimap.add(++curPC);
+- ++curIP;
+- putu1_fast(origBC);
+- }
+- entry* ref = bc_which->getRef();
+- CHECK;
+- putref(ref);
+- continue;
++ if (!isAload) {
++ wp[-1] = origBC; // overwrite with origBC
++ } else {
++ wp[-1] = bc_aload_0; // overwrite with _aload_0
++ // Note: insnMap keeps the _aload_0 separate.
++ bcimap.add(++curPC);
++ ++curIP;
++ putu1_fast(origBC);
++ }
++ entry* ref = bc_which->getRef();
++ CHECK;
++ putref(ref);
++ continue;
+ }
+ if (is_branch_op(bc)) {
+- //int lVal = bc_label.getInt();
+- if (bc < bc_goto_w) {
+- put_label(curIP, 2); //putu2(lVal & 0xFFFF);
+- } else {
+- assert(bc <= bc_jsr_w);
+- put_label(curIP, 4); //putu4(lVal);
+- }
+- assert(to_bci(curIP) == curPC);
+- continue;
++ //int lVal = bc_label.getInt();
++ if (bc < bc_goto_w) {
++ put_label(curIP, 2); //putu2(lVal & 0xFFFF);
++ } else {
++ assert(bc <= bc_jsr_w);
++ put_label(curIP, 4); //putu4(lVal);
++ }
++ assert(to_bci(curIP) == curPC);
++ continue;
+ }
+ bc_which = ref_band_for_op(bc);
+ if (bc_which != null) {
+- entry* ref = bc_which->getRefCommon(bc_which->ix, bc_which->nullOK);
+- CHECK;
+- if (ref == null && bc_which == &bc_classref) {
+- // Shorthand for class self-references.
+- ref = thisClass;
+- }
+- origBC = bc;
+- switch (bc) {
+- case bc_ildc:
+- case bc_cldc:
+- case bc_fldc:
+- case bc_aldc:
+- origBC = bc_ldc;
+- break;
+- case bc_ildc_w:
+- case bc_cldc_w:
+- case bc_fldc_w:
+- case bc_aldc_w:
+- origBC = bc_ldc_w;
+- break;
+- case bc_lldc2_w:
+- case bc_dldc2_w:
+- origBC = bc_ldc2_w;
+- break;
+- case bc_new:
+- newClass = ref;
+- break;
+- }
+- wp[-1] = origBC; // overwrite with origBC
+- if (origBC == bc_ldc) {
+- putu1ref(ref);
+- } else {
+- putref(ref);
+- }
+- if (origBC == bc_multianewarray) {
+- // Copy the trailing byte also.
+- int val = bc_byte.getByte();
+- putu1_fast(val);
+- } else if (origBC == bc_invokeinterface) {
+- int argSize = ref->memberDescr()->descrType()->typeSize();
+- putu1_fast(1 + argSize);
+- putu1_fast(0);
+- }
+- continue;
++ entry* ref = bc_which->getRefCommon(bc_which->ix, bc_which->nullOK);
++ CHECK;
++ if (ref == null && bc_which == &bc_classref) {
++ // Shorthand for class self-references.
++ ref = thisClass;
++ }
++ origBC = bc;
++ switch (bc) {
++ case bc_ildc:
++ case bc_cldc:
++ case bc_fldc:
++ case bc_aldc:
++ origBC = bc_ldc;
++ break;
++ case bc_ildc_w:
++ case bc_cldc_w:
++ case bc_fldc_w:
++ case bc_aldc_w:
++ origBC = bc_ldc_w;
++ break;
++ case bc_lldc2_w:
++ case bc_dldc2_w:
++ origBC = bc_ldc2_w;
++ break;
++ case bc_new:
++ newClass = ref;
++ break;
++ }
++ wp[-1] = origBC; // overwrite with origBC
++ if (origBC == bc_ldc) {
++ putu1ref(ref);
++ } else {
++ putref(ref);
++ }
++ if (origBC == bc_multianewarray) {
++ // Copy the trailing byte also.
++ int val = bc_byte.getByte();
++ putu1_fast(val);
++ } else if (origBC == bc_invokeinterface) {
++ int argSize = ref->memberDescr()->descrType()->typeSize();
++ putu1_fast(1 + argSize);
++ putu1_fast(0);
++ }
++ continue;
+ }
+ if (is_local_slot_op(bc)) {
+- int local = bc_local.getInt();
+- if (isWide) {
+- putu2(local);
+- if (bc == bc_iinc) {
+- int iVal = bc_short.getInt();
+- putu2(iVal);
+- }
+- } else {
+- putu1_fast(local);
+- if (bc == bc_iinc) {
+- int iVal = bc_byte.getByte();
+- putu1_fast(iVal);
+- }
+- }
+- continue;
++ int local = bc_local.getInt();
++ if (isWide) {
++ putu2(local);
++ if (bc == bc_iinc) {
++ int iVal = bc_short.getInt();
++ putu2(iVal);
++ }
++ } else {
++ putu1_fast(local);
++ if (bc == bc_iinc) {
++ int iVal = bc_byte.getByte();
++ putu1_fast(iVal);
++ }
++ }
++ continue;
+ }
+ // Random bytecode. Just copy it.
+ assert(bc < bc_bytecode_limit);
+@@ -4073,78 +4083,80 @@ int unpacker::write_attrs(int attrc, jul
+ case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_OVERFLOW):
+ case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_OVERFLOW):
+ case ADH_BYTE(ATTR_CONTEXT_CODE, X_ATTR_OVERFLOW):
+- // no attribute at all, so back up on this one
+- wp = wp_at(abase);
+- continue;
++ // no attribute at all, so back up on this one
++ wp = wp_at(abase);
++ continue;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_ClassFile_version):
+- cur_class_minver = class_ClassFile_version_minor_H.getInt();
+- cur_class_majver = class_ClassFile_version_major_H.getInt();
+- // back up; not a real attribute
+- wp = wp_at(abase);
+- continue;
++ cur_class_minver = class_ClassFile_version_minor_H.getInt();
++ cur_class_majver = class_ClassFile_version_major_H.getInt();
++ // back up; not a real attribute
++ wp = wp_at(abase);
++ continue;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_InnerClasses):
+- // note the existence of this attr, but save for later
+- if (cur_class_has_local_ics)
+- abort("too many InnerClasses attrs");
+- cur_class_has_local_ics = true;
+- wp = wp_at(abase);
+- continue;
++ // note the existence of this attr, but save for later
++ if (cur_class_has_local_ics)
++ abort("too many InnerClasses attrs");
++ cur_class_has_local_ics = true;
++ wp = wp_at(abase);
++ continue;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_SourceFile):
+- aname = cp.sym[cpool::s_SourceFile];
+- ref = class_SourceFile_RUN.getRefN();
+- CHECK_0;
+- if (ref == null) {
+- bytes& n = cur_class->ref(0)->value.b;
+- // parse n = (<pkg>/)*<outer>?($<id>)*
+- int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, n.len)+1;
+- bytes prefix = n.slice(pkglen, n.len);
+- for (;;) {
+- // Work backwards, finding all '$', '#', etc.
+- int dollar = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, prefix, prefix.len);
+- if (dollar < 0) break;
+- prefix = prefix.slice(0, dollar);
+- }
+- const char* suffix = ".java";
+- int len = prefix.len + strlen(suffix);
+- bytes name; name.set(T_NEW(byte, add_size(len, 1)), len);
+- name.strcat(prefix).strcat(suffix);
+- ref = cp.ensureUtf8(name);
+- }
+- putref(ref);
+- break;
++ aname = cp.sym[cpool::s_SourceFile];
++ ref = class_SourceFile_RUN.getRefN();
++ CHECK_0;
++ if (ref == null) {
++ bytes& n = cur_class->ref(0)->value.b;
++ // parse n = (<pkg>/)*<outer>?($<id>)*
++ int pkglen = lastIndexOf(SLASH_MIN, SLASH_MAX, n, n.len)+1;
++ bytes prefix = n.slice(pkglen, n.len);
++ for (;;) {
++ // Work backwards, finding all '$', '#', etc.
++ int dollar = lastIndexOf(DOLLAR_MIN, DOLLAR_MAX, prefix, prefix.len);
++ if (dollar < 0) break;
++ prefix = prefix.slice(0, dollar);
++ }
++ const char* suffix = ".java";
++ int len = prefix.len + strlen(suffix);
++ bytes name; name.set(T_NEW(byte, add_size(len, 1)), len);
++ name.strcat(prefix).strcat(suffix);
++ ref = cp.ensureUtf8(name);
++ }
++ putref(ref);
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, CLASS_ATTR_EnclosingMethod):
+- aname = cp.sym[cpool::s_EnclosingMethod];
+- putref(class_EnclosingMethod_RC.getRefN());
+- putref(class_EnclosingMethod_RDN.getRefN());
+- break;
++ aname = cp.sym[cpool::s_EnclosingMethod];
++ putref(class_EnclosingMethod_RC.getRefN());
++ CHECK_0;
++ putref(class_EnclosingMethod_RDN.getRefN());
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_FIELD, FIELD_ATTR_ConstantValue):
+- aname = cp.sym[cpool::s_ConstantValue];
+- putref(field_ConstantValue_KQ.getRefUsing(cp.getKQIndex()));
+- break;
++ aname = cp.sym[cpool::s_ConstantValue];
++ putref(field_ConstantValue_KQ.getRefUsing(cp.getKQIndex()));
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Code):
+- aname = cp.sym[cpool::s_Code];
+- write_code();
+- break;
++ aname = cp.sym[cpool::s_Code];
++ write_code();
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_METHOD, METHOD_ATTR_Exceptions):
+- aname = cp.sym[cpool::s_Exceptions];
+- putu2(count = method_Exceptions_N.getInt());
+- for (j = 0; j < count; j++) {
+- putref(method_Exceptions_RC.getRefN());
+- }
+- break;
++ aname = cp.sym[cpool::s_Exceptions];
++ putu2(count = method_Exceptions_N.getInt());
++ for (j = 0; j < count; j++) {
++ putref(method_Exceptions_RC.getRefN());
++ CHECK_0;
++ }
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_StackMapTable):
+- aname = cp.sym[cpool::s_StackMapTable];
++ aname = cp.sym[cpool::s_StackMapTable];
+ // (keep this code aligned with its brother in unpacker::read_attrs)
+- putu2(count = code_StackMapTable_N.getInt());
+- for (j = 0; j < count; j++) {
++ putu2(count = code_StackMapTable_N.getInt());
++ for (j = 0; j < count; j++) {
+ int tag = code_StackMapTable_frame_T.getByte();
+ putu1(tag);
+ if (tag <= 127) {
+@@ -4160,109 +4172,115 @@ int unpacker::write_attrs(int attrc, jul
+ // (253) [(1)(2)(2)]
+ // (254) [(1)(2)(2)(2)]
+ putu2(code_StackMapTable_offset.getInt());
++ CHECK_0;
+ for (int j2 = (tag - 251); j2 > 0; j2--) {
+ put_stackmap_type();
++ CHECK_0;
+ }
+ } else {
+ // (255) [(1)NH[(2)]NH[(2)]]
+ putu2(code_StackMapTable_offset.getInt());
+ putu2(j2 = code_StackMapTable_local_N.getInt());
+- while (j2-- > 0) put_stackmap_type();
++ while (j2-- > 0) {put_stackmap_type(); CHECK_0;}
+ putu2(j2 = code_StackMapTable_stack_N.getInt());
+- while (j2-- > 0) put_stackmap_type();
++ while (j2-- > 0) {put_stackmap_type(); CHECK_0;}
+ }
+- }
+- break;
++ }
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LineNumberTable):
+- aname = cp.sym[cpool::s_LineNumberTable];
+- putu2(count = code_LineNumberTable_N.getInt());
+- for (j = 0; j < count; j++) {
+- putu2(to_bci(code_LineNumberTable_bci_P.getInt()));
+- putu2(code_LineNumberTable_line.getInt());
+- }
+- break;
++ aname = cp.sym[cpool::s_LineNumberTable];
++ putu2(count = code_LineNumberTable_N.getInt());
++ for (j = 0; j < count; j++) {
++ putu2(to_bci(code_LineNumberTable_bci_P.getInt()));
++ putu2(code_LineNumberTable_line.getInt());
++ }
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTable):
+- aname = cp.sym[cpool::s_LocalVariableTable];
+- putu2(count = code_LocalVariableTable_N.getInt());
+- for (j = 0; j < count; j++) {
+- int bii = code_LocalVariableTable_bci_P.getInt();
+- int bci = to_bci(bii);
+- putu2(bci);
+- bii += code_LocalVariableTable_span_O.getInt();
+- putu2(to_bci(bii) - bci);
+- putref(code_LocalVariableTable_name_RU.getRefN());
+- putref(code_LocalVariableTable_type_RS.getRefN());
+- putu2(code_LocalVariableTable_slot.getInt());
+- }
+- break;
++ aname = cp.sym[cpool::s_LocalVariableTable];
++ putu2(count = code_LocalVariableTable_N.getInt());
++ for (j = 0; j < count; j++) {
++ int bii = code_LocalVariableTable_bci_P.getInt();
++ int bci = to_bci(bii);
++ putu2(bci);
++ bii += code_LocalVariableTable_span_O.getInt();
++ putu2(to_bci(bii) - bci);
++ putref(code_LocalVariableTable_name_RU.getRefN());
++ CHECK_0;
++ putref(code_LocalVariableTable_type_RS.getRefN());
++ CHECK_0;
++ putu2(code_LocalVariableTable_slot.getInt());
++ }
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CODE, CODE_ATTR_LocalVariableTypeTable):
+- aname = cp.sym[cpool::s_LocalVariableTypeTable];
+- putu2(count = code_LocalVariableTypeTable_N.getInt());
+- for (j = 0; j < count; j++) {
+- int bii = code_LocalVariableTypeTable_bci_P.getInt();
+- int bci = to_bci(bii);
+- putu2(bci);
+- bii += code_LocalVariableTypeTable_span_O.getInt();
+- putu2(to_bci(bii) - bci);
+- putref(code_LocalVariableTypeTable_name_RU.getRefN());
+- putref(code_LocalVariableTypeTable_type_RS.getRefN());
+- putu2(code_LocalVariableTypeTable_slot.getInt());
+- }
+- break;
++ aname = cp.sym[cpool::s_LocalVariableTypeTable];
++ putu2(count = code_LocalVariableTypeTable_N.getInt());
++ for (j = 0; j < count; j++) {
++ int bii = code_LocalVariableTypeTable_bci_P.getInt();
++ int bci = to_bci(bii);
++ putu2(bci);
++ bii += code_LocalVariableTypeTable_span_O.getInt();
++ putu2(to_bci(bii) - bci);
++ putref(code_LocalVariableTypeTable_name_RU.getRefN());
++ CHECK_0;
++ putref(code_LocalVariableTypeTable_type_RS.getRefN());
++ CHECK_0;
++ putu2(code_LocalVariableTypeTable_slot.getInt());
++ }
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_Signature):
+- aname = cp.sym[cpool::s_Signature];
+- putref(class_Signature_RS.getRefN());
+- break;
++ aname = cp.sym[cpool::s_Signature];
++ putref(class_Signature_RS.getRefN());
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_Signature):
+- aname = cp.sym[cpool::s_Signature];
+- putref(field_Signature_RS.getRefN());
+- break;
++ aname = cp.sym[cpool::s_Signature];
++ putref(field_Signature_RS.getRefN());
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Signature):
+- aname = cp.sym[cpool::s_Signature];
+- putref(method_Signature_RS.getRefN());
+- break;
++ aname = cp.sym[cpool::s_Signature];
++ putref(method_Signature_RS.getRefN());
++ break;
+
+ case ADH_BYTE(ATTR_CONTEXT_CLASS, X_ATTR_Deprecated):
+ case ADH_BYTE(ATTR_CONTEXT_FIELD, X_ATTR_Deprecated):
+ case ADH_BYTE(ATTR_CONTEXT_METHOD, X_ATTR_Deprecated):
+- aname = cp.sym[cpool::s_Deprecated];
+- // no data
+- break;
+- }
+- }
+-
++ aname = cp.sym[cpool::s_Deprecated];
++ // no data
++ break;
++ }
++ }
++ CHECK_0;
+ if (aname == null) {
+ // Unparse a compressor-defined attribute.
+ layout_definition* lo = ad.getLayout(idx);
+ if (lo == null) {
+- abort("bad layout index");
+- break;
++ abort("bad layout index");
++ break;
+ }
+ assert(lo->idx == idx);
+ aname = lo->nameEntry;
+ if (aname == null) {
+- bytes nameb; nameb.set(lo->name);
+- aname = cp.ensureUtf8(nameb);
+- // Cache the name entry for next time.
+- lo->nameEntry = aname;
++ bytes nameb; nameb.set(lo->name);
++ aname = cp.ensureUtf8(nameb);
++ // Cache the name entry for next time.
++ lo->nameEntry = aname;
+ }
+ // Execute all the layout elements.
+ band** bands = lo->bands();
+ if (lo->hasCallables()) {
+- band& cble = *bands[0];
+- assert(cble.le_kind == EK_CBLE);
+- bands = cble.le_body;
++ band& cble = *bands[0];
++ assert(cble.le_kind == EK_CBLE);
++ bands = cble.le_body;
+ }
+ putlayout(bands);
+ }
+
+- if (aname == null)
++ if (aname == null)
+ abort("bad attribute index");
+ CHECK_0;
+
+@@ -4335,8 +4353,8 @@ void unpacker::write_classfile_tail() {
+ julong indexMask = ad.flagIndexMask();
+
+ cur_class = class_this.getRef();
++ CHECK;
+ cur_super = class_super.getRef();
+-
+ CHECK;
+
+ if (cur_super == cur_class) cur_super = null;
+@@ -4349,6 +4367,7 @@ void unpacker::write_classfile_tail() {
+ putu2(num = class_interface_count.getInt());
+ for (i = 0; i < num; i++) {
+ putref(class_interface.getRef());
++ CHECK;
+ }
+
+ write_members(class_field_count.getInt(), ATTR_CONTEXT_FIELD);
+@@ -4389,8 +4408,8 @@ void unpacker::write_classfile_tail() {
+ entry& e = *oes[i];
+ if (e.tag != CONSTANT_Class) continue; // wrong sort
+ for (inner_class* ic = cp.getIC(&e);
+- ic != null;
+- ic = cp.getIC(ic->outer)) {
++ ic != null;
++ ic = cp.getIC(ic->outer)) {
+ if (ic->requested) break; // already processed
+ ic->requested = true;
+ requested_ics.add(ic);
+@@ -4421,22 +4440,24 @@ void unpacker::write_classfile_tail() {
+ if (flags == 0) {
+ // The extra IC is simply a copy of a global IC.
+ if (global_ic == null) {
+- abort("bad reference to inner class");
+- break;
++ abort("bad reference to inner class");
++ break;
+ }
+ extra_ic = (*global_ic); // fill in rest of fields
+ } else {
+ flags &= ~ACC_IC_LONG_FORM; // clear high bit if set to get clean zero
+ extra_ic.flags = flags;
+ extra_ic.outer = class_InnerClasses_outer_RCN.getRefN();
++ CHECK;
+ extra_ic.name = class_InnerClasses_name_RUN.getRefN();
++ CHECK;
+ // Detect if this is an exact copy of the global tuple.
+ if (global_ic != null) {
+- if (global_ic->flags != extra_ic.flags ||
+- global_ic->outer != extra_ic.outer ||
+- global_ic->name != extra_ic.name) {
+- global_ic = null; // not really the same, so break the link
+- }
++ if (global_ic->flags != extra_ic.flags ||
++ global_ic->outer != extra_ic.outer ||
++ global_ic->name != extra_ic.name) {
++ global_ic = null; // not really the same, so break the link
++ }
+ }
+ }
+ if (global_ic != null && global_ic->requested) {
+@@ -4465,15 +4486,15 @@ void unpacker::write_classfile_tail() {
+ for (i = -num_global_ics; i < num_extra_ics; i++) {
+ inner_class* ic;
+ if (i < 0)
+- ic = (inner_class*) requested_ics.get(num_global_ics+i);
++ ic = (inner_class*) requested_ics.get(num_global_ics+i);
+ else
+- ic = &extra_ics[i];
++ ic = &extra_ics[i];
+ if (ic->requested) {
+- putref(ic->inner);
+- putref(ic->outer);
+- putref(ic->name);
+- putu2(ic->flags);
+- NOT_PRODUCT(local_ics--);
++ putref(ic->inner);
++ putref(ic->outer);
++ putref(ic->name);
++ putu2(ic->flags);
++ NOT_PRODUCT(local_ics--);
+ }
+ }
+ assert(local_ics == 0); // must balance
+@@ -4573,7 +4594,7 @@ unpacker::file* unpacker::get_next_file(
+ if (archive_size != 0) {
+ julong predicted_size = unsized_bytes_read + archive_size;
+ if (predicted_size != bytes_read)
+- abort("archive header had incorrect size");
++ abort("archive header had incorrect size");
+ }
+ return null;
+ }
+@@ -4637,7 +4658,7 @@ unpacker::file* unpacker::get_next_file(
+ size_t rpleft = input_remaining();
+ if (rpleft > 0) {
+ if (rpleft > cur_file.size)
+- rpleft = (size_t) cur_file.size;
++ rpleft = (size_t) cur_file.size;
+ cur_file.data[0].set(rp, rpleft);
+ rp += rpleft;
+ }
+@@ -4655,7 +4676,7 @@ unpacker::file* unpacker::get_next_file(
+
+ // Write a file to jarout.
+ void unpacker::write_file_to_jar(unpacker::file* f) {
+- size_t htsize = f->data[0].len + f->data[1].len;
++ size_t htsize = f->data[0].len + f->data[1].len;
+ julong fsize = f->size;
+ #ifndef PRODUCT
+ if (nowrite NOT_PRODUCT(|| skipfiles-- > 0)) {
+@@ -4665,7 +4686,7 @@ void unpacker::write_file_to_jar(unpacke
+ #endif
+ if (htsize == fsize) {
+ jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime,
+- f->data[0], f->data[1]);
++ f->data[0], f->data[1]);
+ } else {
+ assert(input_remaining() == 0);
+ bytes part1, part2;
+@@ -4680,27 +4701,27 @@ void unpacker::write_file_to_jar(unpacke
+ if (fleft > 0) {
+ // Must read some more.
+ if (live_input) {
+- // Stop using the input buffer. Make a new one:
+- if (free_input) input.free();
+- input.init(fleft > (1<<12) ? fleft : (1<<12));
+- free_input = true;
+- live_input = false;
++ // Stop using the input buffer. Make a new one:
++ if (free_input) input.free();
++ input.init(fleft > (1<<12) ? fleft : (1<<12));
++ free_input = true;
++ live_input = false;
+ } else {
+- // Make it large enough.
+- assert(free_input); // must be reallocable
+- input.ensureSize(fleft);
++ // Make it large enough.
++ assert(free_input); // must be reallocable
++ input.ensureSize(fleft);
+ }
+ rplimit = rp = input.base();
+ CHECK;
+ input.setLimit(rp + fleft);
+ if (!ensure_input(fleft))
+- abort("EOF reading resource file");
++ abort("EOF reading resource file");
+ part2.ptr = input_scan();
+ part2.len = input_remaining();
+ rplimit = rp = input.base();
+ }
+ jarout->addJarEntry(f->name, f->deflate_hint(), f->modtime,
+- part1, part2);
++ part1, part2);
+ }
+ if (verbose >= 3) {
+ fprintf(errstrm, "Wrote %lld bytes to: %s\n", fsize, f->name);
+@@ -4722,7 +4743,7 @@ void unpacker::redirect_stdio() {
+ } else if (strcmp(log_file, LOGFILE_STDOUT) == 0) {
+ errstrm = stdout;
+ return;
+- } else if (log_file[0] != '\0' && (errstrm = fopen(log_file,"a+")) != NULL) {
++ } else if (log_file[0] != '\0' && (errstrm = fopen(log_file,"a+")) != NULL) {
+ return;
+ } else {
+ char log_file_name[PATH_MAX+100];
+@@ -4732,7 +4753,7 @@ void unpacker::redirect_stdio() {
+ if (n < 1 || n > PATH_MAX) {
+ sprintf(tmpdir,"C:\\");
+ }
+- sprintf(log_file_name, "%sunpack.log", tmpdir);
++ sprintf(log_file_name, "%sunpack.log", tmpdir);
+ #else
+ sprintf(tmpdir,"/tmp");
+ sprintf(log_file_name, "/tmp/unpack.log");
+@@ -4742,7 +4763,7 @@ void unpacker::redirect_stdio() {
+ return ;
+ }
+
+- char *tname = tempnam(tmpdir,"#upkg");
++ char *tname = tempnam(tmpdir,"#upkg");
+ sprintf(log_file_name, "%s", tname);
+ if ((errstrm = fopen(log_file_name, "a+")) != NULL) {
+ log_file = errstrm_name = saveStr(log_file_name);
+@@ -4758,7 +4779,7 @@ void unpacker::redirect_stdio() {
+ #endif
+ // Last resort
+ // (Do not use stdout, since it might be jarout->jarfp.)
+- errstrm = stderr;
++ errstrm = stderr;
+ log_file = errstrm_name = LOGFILE_STDERR;
+ }
+ }
+@@ -4799,3 +4820,5 @@ void unpacker::abort(const char* message
+ #endif
+ #endif // JNI
+ }
++
++
diff --git a/java/openjdk6/files/icedtea/security/20130201/7186948.patch b/java/openjdk6/files/icedtea/security/20130201/7186948.patch
new file mode 100644
index 000000000000..1313561fda6a
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7186948.patch
@@ -0,0 +1,20 @@
+# HG changeset patch
+# User rupashka
+# Date 1350390610 -14400
+# Node ID 6deb10c2d5d0c8925fd2012d9fc3b9325c997f21
+# Parent ce11c5c59cb8672eeddf9d5ce49563ccbc387854
+7186948: Improve Swing data validation
+Reviewed-by: art, ahgross
+
+diff --git a/src/share/classes/javax/swing/UIDefaults.java b/src/share/classes/javax/swing/UIDefaults.java
+--- jdk/src/share/classes/javax/swing/UIDefaults.java
++++ jdk/src/share/classes/javax/swing/UIDefaults.java
+@@ -677,6 +677,8 @@ public class UIDefaults extends Hashtabl
+ try {
+ String className = (String)get(uiClassID);
+ if (className != null) {
++ ReflectUtil.checkPackageAccess(className);
++
+ Class cls = (Class)get(className);
+ if (cls == null) {
+ if (uiClassLoader == null) {
diff --git a/java/openjdk6/files/icedtea/security/20130201/7186952.patch b/java/openjdk6/files/icedtea/security/20130201/7186952.patch
new file mode 100644
index 000000000000..0c6c8ee2e67e
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7186952.patch
@@ -0,0 +1,127 @@
+# HG changeset patch
+# User denis
+# Date 1353947054 -14400
+# Node ID 9bbc6817b00c3e9d4eba05d53a8a20b45947ea03
+# Parent c684d497e159d3eebded29e997d953019305ec45
+7186952: Improve clipboard access
+Reviewed-by: serb, ahgross
+
+diff --git a/src/share/classes/java/awt/TextComponent.java b/src/share/classes/java/awt/TextComponent.java
+--- jdk/src/share/classes/java/awt/TextComponent.java
++++ jdk/src/share/classes/java/awt/TextComponent.java
+@@ -107,12 +107,6 @@ public class TextComponent extends Compo
+ // the background color of non-editable TextComponents.
+ boolean backgroundSetByClientCode = false;
+
+- /**
+- * True if this <code>TextComponent</code> has access
+- * to the System clipboard.
+- */
+- transient private boolean canAccessClipboard;
+-
+ transient protected TextListener textListener;
+
+ /*
+@@ -137,7 +131,6 @@ public class TextComponent extends Compo
+ GraphicsEnvironment.checkHeadless();
+ this.text = (text != null) ? text : "";
+ setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
+- checkSystemClipboardAccess();
+ }
+
+ private void enableInputMethodsIfNecessary() {
+@@ -727,17 +720,14 @@ public class TextComponent extends Compo
+ /**
+ * Assigns a valid value to the canAccessClipboard instance variable.
+ */
+- private void checkSystemClipboardAccess() {
+- canAccessClipboard = true;
++ private boolean canAccessClipboard() {
+ SecurityManager sm = System.getSecurityManager();
+- if (sm != null) {
+- try {
+- sm.checkSystemClipboardAccess();
+- }
+- catch (SecurityException e) {
+- canAccessClipboard = false;
+- }
+- }
++ if (sm == null) return true;
++ try {
++ sm.checkSystemClipboardAccess();
++ return true;
++ } catch (SecurityException e) {}
++ return false;
+ }
+
+ /*
+@@ -820,7 +810,6 @@ public class TextComponent extends Compo
+ }
+ }
+ enableInputMethodsIfNecessary();
+- checkSystemClipboardAccess();
+ }
+
+
+diff --git a/src/windows/native/sun/windows/awt_TextComponent.cpp b/src/windows/native/sun/windows/awt_TextComponent.cpp
+--- jdk/src/windows/native/sun/windows/awt_TextComponent.cpp
++++ jdk/src/windows/native/sun/windows/awt_TextComponent.cpp
+@@ -52,13 +52,11 @@ struct EnableEditingStruct {
+ * AwtTextComponent fields
+ */
+
+-/* java.awt.TextComponent fields */
+-jfieldID AwtTextComponent::canAccessClipboardID;
+-
+-
+ /************************************************************************
+ * AwtTextComponent methods
+ */
++
++jmethodID AwtTextComponent::canAccessClipboardMID;
+
+ AwtTextComponent::AwtTextComponent() {
+ m_synthetic = FALSE;
+@@ -188,8 +186,7 @@ AwtTextComponent::WmPaste()
+ }
+ jobject target = GetTarget(env);
+ jboolean canAccessClipboard =
+- env->GetBooleanField(target,
+- AwtTextComponent::canAccessClipboardID);
++ env->CallBooleanMethod (target, AwtTextComponent::canAccessClipboardMID);
+ env->DeleteLocalRef(target);
+ return (canAccessClipboard) ? mrDoDefault : mrConsume;
+ }
+@@ -622,12 +619,13 @@ Java_sun_awt_windows_WTextComponentPeer_
+ {
+ TRY;
+
+- cls = env->FindClass("java/awt/TextComponent");
+- if (cls != NULL) {
+- AwtTextComponent::canAccessClipboardID =
+- env->GetFieldID(cls, "canAccessClipboard", "Z");
+- DASSERT(AwtTextComponent::canAccessClipboardID != NULL);
+- }
++ jclass textComponentClassID = env->FindClass("java/awt/TextComponent");
++ AwtTextComponent::canAccessClipboardMID =
++ env->GetMethodID(textComponentClassID,
++ "canAccessClipboard", "()Z");
++ env->DeleteLocalRef(textComponentClassID);
++
++ DASSERT(AwtTextComponent::canAccessClipboardMID != NULL)
+
+ CATCH_BAD_ALLOC;
+ }
+diff --git a/src/windows/native/sun/windows/awt_TextComponent.h b/src/windows/native/sun/windows/awt_TextComponent.h
+--- jdk/src/windows/native/sun/windows/awt_TextComponent.h
++++ jdk/src/windows/native/sun/windows/awt_TextComponent.h
+@@ -42,8 +42,7 @@
+
+ class AwtTextComponent : public AwtComponent {
+ public:
+- /* java.awt.TextComponent canAccessClipboard field ID */
+- static jfieldID canAccessClipboardID;
++ static jmethodID canAccessClipboardMID;
+
+ AwtTextComponent();
+
diff --git a/java/openjdk6/files/icedtea/security/20130201/7186954.patch b/java/openjdk6/files/icedtea/security/20130201/7186954.patch
new file mode 100644
index 000000000000..b3fbfcaafb0b
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7186954.patch
@@ -0,0 +1,81 @@
+# HG changeset patch
+# User dmeetry
+# Date 1352295947 -14400
+# Node ID ee4632a30696050ebd5c014fb3da64112ab48dd3
+# Parent 6e2d4ed84b41667df189abb7bd0915cda01a85a0
+7186954: Improve connection performance
+Reviewed-by: khazra
+
+diff --git a/src/share/classes/sun/net/httpserver/ChunkedInputStream.java b/src/share/classes/sun/net/httpserver/ChunkedInputStream.java
+--- jdk/src/share/classes/sun/net/httpserver/ChunkedInputStream.java
++++ jdk/src/share/classes/sun/net/httpserver/ChunkedInputStream.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -41,8 +41,12 @@ class ChunkedInputStream extends LeftOve
+
+ private boolean needToReadHeader = true;
+
+- static char CR = '\r';
+- static char LF = '\n';
++ final static char CR = '\r';
++ final static char LF = '\n';
++ /*
++ * Maximum chunk header size of 2KB + 2 bytes for CRLF
++ */
++ private final static int MAX_CHUNK_HEADER_SIZE = 2050;
+
+ private int numeric (char[] arr, int nchars) throws IOException {
+ assert arr.length >= nchars;
+@@ -73,9 +77,13 @@ class ChunkedInputStream extends LeftOve
+ char[] len_arr = new char [16];
+ int len_size = 0;
+ boolean end_of_len = false;
++ int read = 0;
+
+ while ((c=(char)in.read())!= -1) {
+- if (len_size == len_arr.length -1) {
++ read++;
++ if ((len_size == len_arr.length -1) ||
++ (read > MAX_CHUNK_HEADER_SIZE))
++ {
+ throw new IOException ("invalid chunk header");
+ }
+ if (gotCR) {
+diff --git a/src/share/classes/sun/net/www/http/ChunkedInputStream.java b/src/share/classes/sun/net/www/http/ChunkedInputStream.java
+--- jdk/src/share/classes/sun/net/www/http/ChunkedInputStream.java
++++ jdk/src/share/classes/sun/net/www/http/ChunkedInputStream.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -125,6 +125,11 @@ class ChunkedInputStream extends InputSt
+ */
+ private boolean closed;
+
++ /*
++ * Maximum chunk header size of 2KB + 2 bytes for CRLF
++ */
++ private final static int MAX_CHUNK_HEADER_SIZE = 2050;
++
+ /**
+ * State to indicate that next field should be :-
+ * chunk-size [ chunk-extension ] CRLF
+@@ -290,6 +295,10 @@ class ChunkedInputStream extends InputSt
+ break;
+ }
+ pos++;
++ if ((pos - rawPos) >= MAX_CHUNK_HEADER_SIZE) {
++ error = true;
++ throw new IOException("Chunk header too long");
++ }
+ }
+ if (pos >= rawCount) {
+ return;
diff --git a/java/openjdk6/files/icedtea/security/20130201/7192392.patch b/java/openjdk6/files/icedtea/security/20130201/7192392.patch
new file mode 100644
index 000000000000..5e51b99c7e64
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7192392.patch
@@ -0,0 +1,695 @@
+# HG changeset patch
+# User mbankal
+# Date 1355226562 28800
+# Node ID 726b9456757648efb7c68e41c6bcc08a401eef83
+# Parent aade089d4505d382f49306a90873c4217367e709
+7192392: Better validation of client keys
+Reviewed-by: xuelei
+
+diff --git a/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java b/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java
+--- jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java
++++ jdk/src/share/classes/com/sun/crypto/provider/DHKeyAgreement.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -39,6 +39,7 @@ import javax.crypto.ShortBufferException
+ import javax.crypto.ShortBufferException;
+ import javax.crypto.SecretKey;
+ import javax.crypto.spec.*;
++import sun.security.util.KeyUtil;
+
+ /**
+ * This class implements the Diffie-Hellman key agreement protocol between
+@@ -205,6 +206,9 @@ extends KeyAgreementSpi {
+ if (pub_g != null && !(init_g.equals(pub_g))) {
+ throw new InvalidKeyException("Incompatible parameters");
+ }
++
++ // validate the Diffie-Hellman public key
++ KeyUtil.validate(dhPubKey);
+
+ // store the y value
+ this.y = dhPubKey.getY();
+diff --git a/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java b/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java
+--- jdk/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java
++++ jdk/src/share/classes/sun/security/pkcs11/P11KeyAgreement.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -37,6 +37,7 @@ import static sun.security.pkcs11.Templa
+ import static sun.security.pkcs11.TemplateManager.*;
+ import sun.security.pkcs11.wrapper.*;
+ import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
++import sun.security.util.KeyUtil;
+
+ /**
+ * KeyAgreement implementation class. This class currently supports
+@@ -134,6 +135,8 @@ final class P11KeyAgreement extends KeyA
+ BigInteger p, g, y;
+ if (key instanceof DHPublicKey) {
+ DHPublicKey dhKey = (DHPublicKey)key;
++ // validate the Diffie-Hellman public key
++ KeyUtil.validate(dhKey);
+ y = dhKey.getY();
+ DHParameterSpec params = dhKey.getParams();
+ p = params.getP();
+@@ -145,6 +148,8 @@ final class P11KeyAgreement extends KeyA
+ try {
+ DHPublicKeySpec spec = (DHPublicKeySpec)kf.engineGetKeySpec
+ (key, DHPublicKeySpec.class);
++ // validate the Diffie-Hellman public key
++ KeyUtil.validate(spec);
+ y = spec.getY();
+ p = spec.getP();
+ g = spec.getG();
+diff --git a/src/share/classes/sun/security/ssl/ClientHandshaker.java b/src/share/classes/sun/security/ssl/ClientHandshaker.java
+--- jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java
++++ jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -168,7 +168,11 @@ final class ClientHandshaker extends Han
+ }
+ break;
+ case K_DH_ANON:
+- this.serverKeyExchange(new DH_ServerKeyExchange(input));
++ try {
++ this.serverKeyExchange(new DH_ServerKeyExchange(input));
++ } catch (GeneralSecurityException e) {
++ throwSSLException("Server key", e);
++ }
+ break;
+ case K_DHE_DSS:
+ case K_DHE_RSA:
+@@ -811,7 +815,7 @@ final class ClientHandshaker extends Han
+ case K_DHE_RSA:
+ case K_DHE_DSS:
+ case K_DH_ANON:
+- preMasterSecret = dh.getAgreedSecret(serverDH);
++ preMasterSecret = dh.getAgreedSecret(serverDH, true);
+ break;
+ case K_ECDHE_RSA:
+ case K_ECDHE_ECDSA:
+diff --git a/src/share/classes/sun/security/ssl/DHClientKeyExchange.java b/src/share/classes/sun/security/ssl/DHClientKeyExchange.java
+--- jdk/src/share/classes/sun/security/ssl/DHClientKeyExchange.java
++++ jdk/src/share/classes/sun/security/ssl/DHClientKeyExchange.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -29,7 +29,7 @@ import java.io.IOException;
+ import java.io.IOException;
+ import java.io.PrintStream;
+ import java.math.BigInteger;
+-
++import javax.net.ssl.SSLHandshakeException;
+
+ /*
+ * Message used by clients to send their Diffie-Hellman public
+@@ -50,7 +50,7 @@ final class DHClientKeyExchange extends
+ private byte dh_Yc[]; // 1 to 2^16 -1 bytes
+
+ BigInteger getClientPublicKey() {
+- return new BigInteger(1, dh_Yc);
++ return dh_Yc == null ? null : new BigInteger(1, dh_Yc);
+ }
+
+ /*
+@@ -72,7 +72,14 @@ final class DHClientKeyExchange extends
+ * but that's what the protocol spec requires.)
+ */
+ DHClientKeyExchange(HandshakeInStream input) throws IOException {
+- dh_Yc = input.getBytes16();
++ if (input.available() >= 2) {
++ dh_Yc = input.getBytes16();
++ } else {
++ // currently, we don't support cipher suites that requires
++ // implicit public key of client.
++ throw new SSLHandshakeException(
++ "Unsupported implicit client DiffieHellman public key");
++ }
+ }
+
+ int messageLength() {
+@@ -84,7 +91,9 @@ final class DHClientKeyExchange extends
+ }
+
+ void send(HandshakeOutStream s) throws IOException {
+- s.putBytes16(dh_Yc);
++ if (dh_Yc != null && dh_Yc.length != 0) {
++ s.putBytes16(dh_Yc);
++ }
+ }
+
+ void print(PrintStream s) throws IOException {
+diff --git a/src/share/classes/sun/security/ssl/DHCrypt.java b/src/share/classes/sun/security/ssl/DHCrypt.java
+--- jdk/src/share/classes/sun/security/ssl/DHCrypt.java
++++ jdk/src/share/classes/sun/security/ssl/DHCrypt.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -28,11 +28,14 @@ package sun.security.ssl;
+
+ import java.math.BigInteger;
+ import java.security.*;
++import java.io.IOException;
++import javax.net.ssl.SSLHandshakeException;
+
+ import javax.crypto.SecretKey;
+ import javax.crypto.KeyAgreement;
+ import javax.crypto.interfaces.DHPublicKey;
+ import javax.crypto.spec.*;
++import sun.security.util.KeyUtil;
+
+ /**
+ * This class implements the Diffie-Hellman key exchange algorithm.
+@@ -54,7 +57,8 @@ import javax.crypto.spec.*;
+ * . if we are server, call DHCrypt(keyLength,random). This generates
+ * an ephemeral keypair of the request length.
+ * . if we are client, call DHCrypt(modulus, base, random). This
+- * generates an ephemeral keypair using the parameters specified by the server.
++ * generates an ephemeral keypair using the parameters specified by
++ * the server.
+ * . send parameters and public value to remote peer
+ * . receive peers ephemeral public key
+ * . call getAgreedSecret() to calculate the shared secret
+@@ -83,6 +87,9 @@ final class DHCrypt {
+ // public component of our key, X = (g ^ x) mod p
+ private BigInteger publicValue; // X (aka y)
+
++ // the times to recover from failure if public key validation
++ private static int MAX_FAILOVER_TIMES = 2;
++
+ /**
+ * Generate a Diffie-Hellman keypair of the specified size.
+ */
+@@ -90,9 +97,10 @@ final class DHCrypt {
+ try {
+ KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
+ kpg.initialize(keyLength, random);
+- KeyPair kp = kpg.generateKeyPair();
+- privateKey = kp.getPrivate();
+- DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
++ DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
++ if (spec == null) {
++ throw new RuntimeException("Could not generate DH keypair");
++ }
+ publicValue = spec.getY();
+ modulus = spec.getP();
+ base = spec.getG();
+@@ -115,9 +123,10 @@ final class DHCrypt {
+ KeyPairGenerator kpg = JsseJce.getKeyPairGenerator("DiffieHellman");
+ DHParameterSpec params = new DHParameterSpec(modulus, base);
+ kpg.initialize(params, random);
+- KeyPair kp = kpg.generateKeyPair();
+- privateKey = kp.getPrivate();
+- DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
++ DHPublicKeySpec spec = generateDHPublicKeySpec(kpg);
++ if (spec == null) {
++ throw new RuntimeException("Could not generate DH keypair");
++ }
+ publicValue = spec.getY();
+ } catch (GeneralSecurityException e) {
+ throw new RuntimeException("Could not generate DH keypair", e);
+@@ -128,7 +137,8 @@ final class DHCrypt {
+ if (key instanceof DHPublicKey) {
+ DHPublicKey dhKey = (DHPublicKey)key;
+ DHParameterSpec params = dhKey.getParams();
+- return new DHPublicKeySpec(dhKey.getY(), params.getP(), params.getG());
++ return new DHPublicKeySpec(dhKey.getY(),
++ params.getP(), params.getG());
+ }
+ try {
+ KeyFactory factory = JsseJce.getKeyFactory("DH");
+@@ -168,16 +178,29 @@ final class DHCrypt {
+ * has not been set (or generated).
+ *
+ * @param peerPublicKey the peer's public key.
+- * @returns the secret, which is an unsigned big-endian integer
++ * @param keyIsValidated whether the {@code peerPublicKey} has beed
++ * validated
++ * @return the secret, which is an unsigned big-endian integer
+ * the same size as the Diffie-Hellman modulus.
+ */
+- SecretKey getAgreedSecret(BigInteger peerPublicValue) {
++ SecretKey getAgreedSecret(BigInteger peerPublicValue,
++ boolean keyIsValidated) throws IOException {
+ try {
+ KeyFactory kf = JsseJce.getKeyFactory("DiffieHellman");
+ DHPublicKeySpec spec =
+ new DHPublicKeySpec(peerPublicValue, modulus, base);
+ PublicKey publicKey = kf.generatePublic(spec);
+ KeyAgreement ka = JsseJce.getKeyAgreement("DiffieHellman");
++ // validate the Diffie-Hellman public key
++ if (!keyIsValidated &&
++ !KeyUtil.isOracleJCEProvider(ka.getProvider().getName())) {
++ try {
++ KeyUtil.validate(spec);
++ } catch (InvalidKeyException ike) {
++ // prefer handshake_failure alert to internal_error alert
++ throw new SSLHandshakeException(ike.getMessage());
++ }
++ }
+ ka.init(privateKey);
+ ka.doPhase(publicKey, true);
+ return ka.generateSecret("TlsPremasterSecret");
+@@ -186,4 +209,33 @@ final class DHCrypt {
+ }
+ }
+
++ // Generate and validate DHPublicKeySpec
++ private DHPublicKeySpec generateDHPublicKeySpec(KeyPairGenerator kpg)
++ throws GeneralSecurityException {
++
++ boolean doExtraValiadtion =
++ (!KeyUtil.isOracleJCEProvider(kpg.getProvider().getName()));
++ for (int i = 0; i <= MAX_FAILOVER_TIMES; i++) {
++ KeyPair kp = kpg.generateKeyPair();
++ privateKey = kp.getPrivate();
++ DHPublicKeySpec spec = getDHPublicKeySpec(kp.getPublic());
++
++ // validate the Diffie-Hellman public key
++ if (doExtraValiadtion) {
++ try {
++ KeyUtil.validate(spec);
++ } catch (InvalidKeyException ivke) {
++ if (i == MAX_FAILOVER_TIMES) {
++ throw ivke;
++ }
++ // otherwise, ignore the exception and try the next one
++ continue;
++ }
++ }
++
++ return spec;
++ }
++
++ return null;
++ }
+ }
+diff --git a/src/share/classes/sun/security/ssl/HandshakeMessage.java b/src/share/classes/sun/security/ssl/HandshakeMessage.java
+--- jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java
++++ jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -42,6 +42,7 @@ import javax.security.auth.x500.X500Prin
+
+ import javax.crypto.KeyGenerator;
+ import javax.crypto.SecretKey;
++import javax.crypto.spec.DHPublicKeySpec;
+ import javax.crypto.spec.SecretKeySpec;
+
+ import javax.net.ssl.*;
+@@ -51,6 +52,7 @@ import sun.security.internal.spec.TlsPrf
+ import sun.security.internal.spec.TlsPrfParameterSpec;
+
+ import sun.security.ssl.CipherSuite.*;
++import sun.security.util.KeyUtil;
+
+ /**
+ * Many data structures are involved in the handshake messages. These
+@@ -715,6 +717,7 @@ class DH_ServerKeyExchange extends Serve
+ * key exchange.
+ */
+ DH_ServerKeyExchange(DHCrypt obj) {
++ // The DH key has been validated in the constructor of DHCrypt.
+ getValues(obj);
+ signature = null;
+ }
+@@ -727,6 +730,7 @@ class DH_ServerKeyExchange extends Serve
+ DH_ServerKeyExchange(DHCrypt obj, PrivateKey key, byte clntNonce[],
+ byte svrNonce[], SecureRandom sr) throws GeneralSecurityException {
+
++ // The DH key has been validated in the constructor of DHCrypt.
+ getValues(obj);
+
+ Signature sig;
+@@ -751,10 +755,14 @@ class DH_ServerKeyExchange extends Serve
+ * stream, as if sent from server to client for use with
+ * DH_anon key exchange
+ */
+- DH_ServerKeyExchange(HandshakeInStream input) throws IOException {
++ DH_ServerKeyExchange(HandshakeInStream input)
++ throws IOException, GeneralSecurityException {
+ dh_p = input.getBytes16();
+ dh_g = input.getBytes16();
+ dh_Ys = input.getBytes16();
++ KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
++ new BigInteger(1, dh_p),
++ new BigInteger(1, dh_g)));
+ signature = null;
+ }
+
+@@ -770,7 +778,9 @@ class DH_ServerKeyExchange extends Serve
+ dh_p = input.getBytes16();
+ dh_g = input.getBytes16();
+ dh_Ys = input.getBytes16();
+-
++ KeyUtil.validate(new DHPublicKeySpec(new BigInteger(1, dh_Ys),
++ new BigInteger(1, dh_p),
++ new BigInteger(1, dh_g)));
+ byte signature[];
+ if (dhKeyExchangeFix) {
+ signature = input.getBytes16();
+diff --git a/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java b/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java
+--- jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java
++++ jdk/src/share/classes/sun/security/ssl/RSAClientKeyExchange.java
+@@ -36,7 +36,7 @@ import javax.net.ssl.*;
+ import javax.net.ssl.*;
+
+ import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec;
+-import sun.security.util.KeyLength;
++import sun.security.util.KeyUtil;
+
+ /**
+ * This is the client key exchange message (CLIENT --> SERVER) used with
+@@ -194,7 +194,7 @@ final class RSAClientKeyExchange extends
+ "unable to get the plaintext of the premaster secret");
+ }
+
+- int keySize = KeyLength.getKeySize(secretKey);
++ int keySize = KeyUtil.getKeySize(secretKey);
+ if (keySize > 0 && keySize != 384) { // 384 = 48 * 8
+ if (debug != null && Debug.isOn("handshake")) {
+ System.out.println(
+diff --git a/src/share/classes/sun/security/ssl/ServerHandshaker.java b/src/share/classes/sun/security/ssl/ServerHandshaker.java
+--- jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java
++++ jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java
+@@ -1147,7 +1147,7 @@ final class ServerHandshaker extends Han
+ if (debug != null && Debug.isOn("handshake")) {
+ mesg.print(System.out);
+ }
+- return dh.getAgreedSecret(mesg.getClientPublicKey());
++ return dh.getAgreedSecret(mesg.getClientPublicKey(), false);
+ }
+
+ private SecretKey clientKeyExchange(ECDHClientKeyExchange mesg)
+diff --git a/src/share/classes/sun/security/util/KeyLength.java b/src/share/classes/sun/security/util/KeyLength.java
+deleted file mode 100644
+--- jdk/src/share/classes/sun/security/util/KeyLength.java
++++ /dev/null
+@@ -1,91 +0,0 @@
+-/*
+- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-package sun.security.util;
+-
+-import java.security.Key;
+-import java.security.PrivilegedAction;
+-import java.security.AccessController;
+-import java.security.interfaces.ECKey;
+-import java.security.interfaces.RSAKey;
+-import java.security.interfaces.DSAKey;
+-import javax.crypto.SecretKey;
+-import javax.crypto.interfaces.DHKey;
+-
+-/**
+- * A utility class to get key length
+- */
+-public final class KeyLength {
+-
+- /**
+- * Returns the key size of the given key object in bits.
+- *
+- * @param key the key object, cannot be null
+- * @return the key size of the given key object in bits, or -1 if the
+- * key size is not accessible
+- */
+- final public static int getKeySize(Key key) {
+- int size = -1;
+-
+- if (key instanceof Length) {
+- try {
+- Length ruler = (Length)key;
+- size = ruler.length();
+- } catch (UnsupportedOperationException usoe) {
+- // ignore the exception
+- }
+-
+- if (size >= 0) {
+- return size;
+- }
+- }
+-
+- // try to parse the length from key specification
+- if (key instanceof SecretKey) {
+- SecretKey sk = (SecretKey)key;
+- String format = sk.getFormat();
+- if ("RAW".equals(format) && sk.getEncoded() != null) {
+- size = (sk.getEncoded().length * 8);
+- } // Otherwise, it may be a unextractable key of PKCS#11, or
+- // a key we are not able to handle.
+- } else if (key instanceof RSAKey) {
+- RSAKey pubk = (RSAKey)key;
+- size = pubk.getModulus().bitLength();
+- } else if (key instanceof ECKey) {
+- ECKey pubk = (ECKey)key;
+- size = pubk.getParams().getOrder().bitLength();
+- } else if (key instanceof DSAKey) {
+- DSAKey pubk = (DSAKey)key;
+- size = pubk.getParams().getP().bitLength();
+- } else if (key instanceof DHKey) {
+- DHKey pubk = (DHKey)key;
+- size = pubk.getParams().getP().bitLength();
+- } // Otherwise, it may be a unextractable key of PKCS#11, or
+- // a key we are not able to handle.
+-
+- return size;
+- }
+-}
+-
+diff --git a/src/share/classes/sun/security/util/KeyUtil.java b/src/share/classes/sun/security/util/KeyUtil.java
+new file mode 100644
+--- /dev/null
++++ jdk/src/share/classes/sun/security/util/KeyUtil.java
+@@ -0,0 +1,184 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ */
++
++package sun.security.util;
++
++import java.security.Key;
++import java.security.PrivilegedAction;
++import java.security.AccessController;
++import java.security.InvalidKeyException;
++import java.security.interfaces.ECKey;
++import java.security.interfaces.RSAKey;
++import java.security.interfaces.DSAKey;
++import java.security.spec.KeySpec;
++import javax.crypto.SecretKey;
++import javax.crypto.interfaces.DHKey;
++import javax.crypto.interfaces.DHPublicKey;
++import javax.crypto.spec.DHParameterSpec;
++import javax.crypto.spec.DHPublicKeySpec;
++import java.math.BigInteger;
++
++/**
++ * A utility class to get key length, valiate keys, etc.
++ */
++public final class KeyUtil {
++
++ /**
++ * Returns the key size of the given key object in bits.
++ *
++ * @param key the key object, cannot be null
++ * @return the key size of the given key object in bits, or -1 if the
++ * key size is not accessible
++ */
++ public static final int getKeySize(Key key) {
++ int size = -1;
++
++ if (key instanceof Length) {
++ try {
++ Length ruler = (Length)key;
++ size = ruler.length();
++ } catch (UnsupportedOperationException usoe) {
++ // ignore the exception
++ }
++
++ if (size >= 0) {
++ return size;
++ }
++ }
++
++ // try to parse the length from key specification
++ if (key instanceof SecretKey) {
++ SecretKey sk = (SecretKey)key;
++ String format = sk.getFormat();
++ if ("RAW".equals(format) && sk.getEncoded() != null) {
++ size = (sk.getEncoded().length * 8);
++ } // Otherwise, it may be a unextractable key of PKCS#11, or
++ // a key we are not able to handle.
++ } else if (key instanceof RSAKey) {
++ RSAKey pubk = (RSAKey)key;
++ size = pubk.getModulus().bitLength();
++ } else if (key instanceof ECKey) {
++ ECKey pubk = (ECKey)key;
++ size = pubk.getParams().getOrder().bitLength();
++ } else if (key instanceof DSAKey) {
++ DSAKey pubk = (DSAKey)key;
++ size = pubk.getParams().getP().bitLength();
++ } else if (key instanceof DHKey) {
++ DHKey pubk = (DHKey)key;
++ size = pubk.getParams().getP().bitLength();
++ } // Otherwise, it may be a unextractable key of PKCS#11, or
++ // a key we are not able to handle.
++
++ return size;
++ }
++
++ /**
++ * Returns whether the key is valid or not.
++ * <P>
++ * Note that this method is only apply to DHPublicKey at present.
++ *
++ * @param publicKey
++ * the key object, cannot be null
++ *
++ * @throws NullPointerException if {@code publicKey} is null
++ * @throws InvalidKeyException if {@code publicKey} is invalid
++ */
++ public static final void validate(Key key)
++ throws InvalidKeyException {
++ if (key == null) {
++ throw new NullPointerException(
++ "The key to be validated cannot be null");
++ }
++
++ if (key instanceof DHPublicKey) {
++ validateDHPublicKey((DHPublicKey)key);
++ }
++ }
++
++
++ /**
++ * Returns whether the key spec is valid or not.
++ * <P>
++ * Note that this method is only apply to DHPublicKeySpec at present.
++ *
++ * @param keySpec
++ * the key spec object, cannot be null
++ *
++ * @throws NullPointerException if {@code keySpec} is null
++ * @throws InvalidKeyException if {@code keySpec} is invalid
++ */
++ public static final void validate(KeySpec keySpec)
++ throws InvalidKeyException {
++ if (keySpec == null) {
++ throw new NullPointerException(
++ "The key spec to be validated cannot be null");
++ }
++
++ if (keySpec instanceof DHPublicKeySpec) {
++ validateDHPublicKey((DHPublicKeySpec)keySpec);
++ }
++ }
++
++ /**
++ * Returns whether the specified provider is Oracle provider or not.
++ * <P>
++ * Note that this method is only apply to SunJCE and SunPKCS11 at present.
++ *
++ * @param providerName
++ * the provider name
++ * @return true if, and only if, the provider of the specified
++ * {@code providerName} is Oracle provider
++ */
++ public static final boolean isOracleJCEProvider(String providerName) {
++ return providerName != null && (providerName.equals("SunJCE") ||
++ providerName.startsWith("SunPKCS11"));
++ }
++
++ /**
++ * Returns whether the Diffie-Hellman public key is valid or not.
++ *
++ * Per RFC 2631 and NIST SP800-56A, the following algorithm is used to
++ * validate Diffie-Hellman public keys:
++ * 1. Verify that y lies within the interval [2,p-1]. If it does not,
++ * the key is invalid.
++ * 2. Compute y^q mod p. If the result == 1, the key is valid.
++ * Otherwise the key is invalid.
++ */
++ private static void validateDHPublicKey(DHPublicKey publicKey)
++ throws InvalidKeyException {
++ DHParameterSpec paramSpec = publicKey.getParams();
++
++ BigInteger p = paramSpec.getP();
++ BigInteger g = paramSpec.getG();
++ BigInteger y = publicKey.getY();
++
++ validateDHPublicKey(p, g, y);
++ }
++
++ private static void validateDHPublicKey(DHPublicKeySpec publicKeySpec)
++ throws InvalidKeyException {
++ validateDHPublicKey(publicKeySpec.getP(),
++ publicKeySpec.getG(), publicKeySpec.getY());
++ }
++
++ private static void validateDHPublicKey(BigInteger p,
++ BigInteger g, BigInteger y) throws InvalidKeyException {
++
++ // For better interoperability, the interval is limited to [2, p-2].
++ BigInteger leftOpen = BigInteger.ONE;
++ BigInteger rightOpen = p.subtract(BigInteger.ONE);
++ if (y.compareTo(leftOpen) <= 0) {
++ throw new InvalidKeyException(
++ "Diffie-Hellman public key is too small");
++ }
++ if (y.compareTo(rightOpen) >= 0) {
++ throw new InvalidKeyException(
++ "Diffie-Hellman public key is too large");
++ }
++
++ // Don't bother to check against the y^q mod p if safe primes are used.
++ }
++}
diff --git a/java/openjdk6/files/icedtea/security/20130201/7192393.patch b/java/openjdk6/files/icedtea/security/20130201/7192393.patch
new file mode 100644
index 000000000000..f9c312d5f019
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7192393.patch
@@ -0,0 +1,60 @@
+# HG changeset patch
+# User mbankal
+# Date 1355294606 28800
+# Node ID 708c134c36312faf8721c0c981be6553e4ebf49f
+# Parent 175c95df5b8609142188946b59040de2e4cbe0af
+7192393: Better Checking of order of TLS Messages
+Reviewed-by: xuelei
+
+diff --git a/src/share/classes/sun/security/ssl/ClientHandshaker.java b/src/share/classes/sun/security/ssl/ClientHandshaker.java
+--- jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java
++++ jdk/src/share/classes/sun/security/ssl/ClientHandshaker.java
+@@ -128,9 +128,8 @@ final class ClientHandshaker extends Han
+ * in the constructor.
+ */
+ void processMessage(byte type, int messageLen) throws IOException {
+- if (state > type
+- && (type != HandshakeMessage.ht_hello_request
+- && state != HandshakeMessage.ht_client_hello)) {
++ if (state >= type
++ && (type != HandshakeMessage.ht_hello_request)) {
+ throw new SSLProtocolException(
+ "Handshake message sequence violation, " + type);
+ }
+diff --git a/src/share/classes/sun/security/ssl/ServerHandshaker.java b/src/share/classes/sun/security/ssl/ServerHandshaker.java
+--- jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java
++++ jdk/src/share/classes/sun/security/ssl/ServerHandshaker.java
+@@ -153,7 +153,7 @@ final class ServerHandshaker extends Han
+ // In SSLv3 and TLS, messages follow strictly increasing
+ // numerical order _except_ for one annoying special case.
+ //
+- if ((state > type)
++ if ((state >= type)
+ && (state != HandshakeMessage.ht_client_key_exchange
+ && type != HandshakeMessage.ht_certificate_verify)) {
+ throw new SSLProtocolException(
+@@ -250,16 +250,17 @@ final class ServerHandshaker extends Han
+ }
+
+ //
+- // Move the state machine forward except for that annoying
+- // special case. This means that clients could send extra
+- // cert verify messages; not a problem so long as all of
+- // them actually check out.
++ // Move state machine forward if the message handling
++ // code didn't already do so
+ //
+- if (state < type && type != HandshakeMessage.ht_certificate_verify) {
+- state = type;
++ if (state < type) {
++ if(type == HandshakeMessage.ht_certificate_verify) {
++ state = type + 2; // an annoying special case
++ } else {
++ state = type;
++ }
+ }
+ }
+-
+
+ /*
+ * ClientHello presents the server with a bunch of options, to which the
diff --git a/java/openjdk6/files/icedtea/security/20130201/7192977.patch b/java/openjdk6/files/icedtea/security/20130201/7192977.patch
new file mode 100644
index 000000000000..19e366b08377
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7192977.patch
@@ -0,0 +1,436 @@
+diff --git a/src/share/classes/java/awt/EventQueue.java b/src/share/classes/java/awt/EventQueue.java
+--- jdk/src/share/classes/java/awt/EventQueue.java
++++ jdk/src/share/classes/java/awt/EventQueue.java
+@@ -173,8 +173,14 @@ public class EventQueue {
+ }
+ public void removeSourceEvents(EventQueue eventQueue,
+ Object source,
+- boolean removeAllEvents) {
++ boolean removeAllEvents)
++ {
+ eventQueue.removeSourceEvents(source, removeAllEvents);
++ }
++ public void invokeAndWait(Object source, Runnable r)
++ throws InterruptedException, InvocationTargetException
++ {
++ EventQueue.invokeAndWait(source, r);
+ }
+ });
+ }
+@@ -1042,8 +1048,14 @@ public class EventQueue {
+ * @since 1.2
+ */
+ public static void invokeAndWait(Runnable runnable)
+- throws InterruptedException, InvocationTargetException {
++ throws InterruptedException, InvocationTargetException
++ {
++ invokeAndWait(Toolkit.getDefaultToolkit(), runnable);
++ }
+
++ static void invokeAndWait(Object source, Runnable runnable)
++ throws InterruptedException, InvocationTargetException
++ {
+ if (EventQueue.isDispatchThread()) {
+ throw new Error("Cannot call invokeAndWait from the event dispatcher thread");
+ }
+@@ -1052,8 +1064,7 @@ public class EventQueue {
+ Object lock = new AWTInvocationLock();
+
+ InvocationEvent event =
+- new InvocationEvent(Toolkit.getDefaultToolkit(), runnable, lock,
+- true);
++ new InvocationEvent(source, runnable, lock, true);
+
+ synchronized (lock) {
+ Toolkit.getEventQueue().postEvent(event);
+diff --git a/src/share/classes/java/awt/Window.java b/src/share/classes/java/awt/Window.java
+--- jdk/src/share/classes/java/awt/Window.java
++++ jdk/src/share/classes/java/awt/Window.java
+@@ -1036,7 +1036,7 @@ public class Window extends Container im
+ }
+ else {
+ try {
+- EventQueue.invokeAndWait(action);
++ EventQueue.invokeAndWait(this, action);
+ }
+ catch (InterruptedException e) {
+ System.err.println("Disposal was interrupted:");
+diff --git a/src/share/classes/javax/swing/RepaintManager.java b/src/share/classes/javax/swing/RepaintManager.java
+--- jdk/src/share/classes/javax/swing/RepaintManager.java
++++ jdk/src/share/classes/javax/swing/RepaintManager.java
+@@ -27,17 +27,21 @@ package javax.swing;
+
+ import java.awt.*;
+ import java.awt.event.*;
+-import java.awt.peer.ComponentPeer;
+-import java.awt.peer.ContainerPeer;
+ import java.awt.image.VolatileImage;
++import java.security.AccessControlContext;
+ import java.security.AccessController;
++import java.security.PrivilegedAction;
+ import java.util.*;
++import java.util.concurrent.atomic.AtomicInteger;
+ import java.applet.*;
+
+ import sun.awt.AppContext;
++import sun.awt.AWTAccessor;
+ import sun.awt.DisplayChangedListener;
+ import sun.awt.SunToolkit;
+ import sun.java2d.SunGraphicsEnvironment;
++import sun.misc.JavaSecurityAccess;
++import sun.misc.SharedSecrets;
+ import sun.security.action.GetPropertyAction;
+
+
+@@ -168,6 +172,9 @@ public class RepaintManager
+ * Runnable used to process all repaint/revalidate requests.
+ */
+ private final ProcessingRunnable processingRunnable;
++
++ private final static JavaSecurityAccess javaSecurityAccess =
++ SharedSecrets.getJavaSecurityAccess();
+
+
+ static {
+@@ -553,13 +560,26 @@ public class RepaintManager
+ // This is called from the toolkit thread when awt needs to run a
+ // Runnable before we paint.
+ //
+- void nativeQueueSurfaceDataRunnable(AppContext appContext, Component c,
+- Runnable r) {
++ void nativeQueueSurfaceDataRunnable(AppContext appContext,
++ final Component c, final Runnable r)
++ {
+ synchronized(this) {
+ if (runnableList == null) {
+ runnableList = new LinkedList<Runnable>();
+ }
+- runnableList.add(r);
++ runnableList.add(new Runnable() {
++ public void run() {
++ AccessControlContext stack = AccessController.getContext();
++ AccessControlContext acc =
++ AWTAccessor.getComponentAccessor().getAccessControlContext(c);
++ javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
++ public Void run() {
++ r.run();
++ return null;
++ }
++ }, stack, acc);
++ }
++ });
+ }
+ scheduleProcessingRunnable(appContext);
+ }
+@@ -639,9 +659,9 @@ public class RepaintManager
+ * @see #addInvalidComponent
+ */
+ public void validateInvalidComponents() {
+- java.util.List<Component> ic;
++ final java.util.List<Component> ic;
+ synchronized(this) {
+- if(invalidComponents == null) {
++ if (invalidComponents == null) {
+ return;
+ }
+ ic = invalidComponents;
+@@ -649,7 +669,17 @@ public class RepaintManager
+ }
+ int n = ic.size();
+ for(int i = 0; i < n; i++) {
+- ic.get(i).validate();
++ final Component c = ic.get(i);
++ AccessControlContext stack = AccessController.getContext();
++ AccessControlContext acc =
++ AWTAccessor.getComponentAccessor().getAccessControlContext(c);
++ javaSecurityAccess.doIntersectionPrivilege(
++ new PrivilegedAction<Void>() {
++ public Void run() {
++ c.validate();
++ return null;
++ }
++ }, stack, acc);
+ }
+ }
+
+@@ -696,76 +726,75 @@ public class RepaintManager
+ paintDirtyRegions(tmpDirtyComponents);
+ }
+
+- private void paintDirtyRegions(Map<Component,Rectangle>
+- tmpDirtyComponents){
+- int i, count;
+- java.util.List<Component> roots;
+- Component dirtyComponent;
+-
+- count = tmpDirtyComponents.size();
+- if (count == 0) {
++ private void paintDirtyRegions(
++ final Map<Component,Rectangle> tmpDirtyComponents)
++ {
++ if (tmpDirtyComponents.isEmpty()) {
+ return;
+ }
+
+- Rectangle rect;
+- int localBoundsX = 0;
+- int localBoundsY = 0;
+- int localBoundsH = 0;
+- int localBoundsW = 0;
+- Enumeration keys;
+-
+- roots = new ArrayList<Component>(count);
++ final java.util.List<Component> roots =
++ new ArrayList<Component>(tmpDirtyComponents.size());
+
+ for (Component dirty : tmpDirtyComponents.keySet()) {
+ collectDirtyComponents(tmpDirtyComponents, dirty, roots);
+ }
+
+- count = roots.size();
+- // System.out.println("roots size is " + count);
++ final AtomicInteger count = new AtomicInteger(roots.size());
+ painting = true;
+ try {
+- for(i=0 ; i < count ; i++) {
+- dirtyComponent = roots.get(i);
+- rect = tmpDirtyComponents.get(dirtyComponent);
+- // System.out.println("Should refresh :" + rect);
+- localBoundsH = dirtyComponent.getHeight();
+- localBoundsW = dirtyComponent.getWidth();
++ for(int j = 0; j < count.get(); j++) {
++ final int i = j;
++ final Component dirtyComponent = roots.get(j);
+
+- SwingUtilities.computeIntersection(localBoundsX,
+- localBoundsY,
+- localBoundsW,
+- localBoundsH,
+- rect);
+- if (dirtyComponent instanceof JComponent) {
+- ((JComponent)dirtyComponent).paintImmediately(
+- rect.x,rect.y,rect.width, rect.height);
+- }
+- else if (dirtyComponent.isShowing()) {
+- Graphics g = JComponent.safelyGetGraphics(
+- dirtyComponent, dirtyComponent);
+- // If the Graphics goes away, it means someone disposed of
+- // the window, don't do anything.
+- if (g != null) {
+- g.setClip(rect.x, rect.y, rect.width, rect.height);
+- try {
+- dirtyComponent.paint(g);
+- } finally {
+- g.dispose();
++ AccessControlContext stack = AccessController.getContext();
++ AccessControlContext acc =
++ AWTAccessor.getComponentAccessor().getAccessControlContext(dirtyComponent);
++ javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
++ public Void run() {
++ Rectangle rect = tmpDirtyComponents.get(dirtyComponent);
++
++ int localBoundsH = dirtyComponent.getHeight();
++ int localBoundsW = dirtyComponent.getWidth();
++ SwingUtilities.computeIntersection(0,
++ 0,
++ localBoundsW,
++ localBoundsH,
++ rect);
++ if (dirtyComponent instanceof JComponent) {
++ ((JComponent)dirtyComponent).paintImmediately(
++ rect.x,rect.y,rect.width, rect.height);
+ }
++ else if (dirtyComponent.isShowing()) {
++ Graphics g = JComponent.safelyGetGraphics(
++ dirtyComponent, dirtyComponent);
++ // If the Graphics goes away, it means someone disposed of
++ // the window, don't do anything.
++ if (g != null) {
++ g.setClip(rect.x, rect.y, rect.width, rect.height);
++ try {
++ dirtyComponent.paint(g);
++ } finally {
++ g.dispose();
++ }
++ }
++ }
++ // If the repaintRoot has been set, service it now and
++ // remove any components that are children of repaintRoot.
++ if (repaintRoot != null) {
++ adjustRoots(repaintRoot, roots, i + 1);
++ count.set(roots.size());
++ paintManager.isRepaintingRoot = true;
++ repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
++ repaintRoot.getHeight());
++ paintManager.isRepaintingRoot = false;
++ // Only service repaintRoot once.
++ repaintRoot = null;
++ }
++
++ return null;
+ }
+- }
+- // If the repaintRoot has been set, service it now and
+- // remove any components that are children of repaintRoot.
+- if (repaintRoot != null) {
+- adjustRoots(repaintRoot, roots, i + 1);
+- count = roots.size();
+- paintManager.isRepaintingRoot = true;
+- repaintRoot.paintImmediately(0, 0, repaintRoot.getWidth(),
+- repaintRoot.getHeight());
+- paintManager.isRepaintingRoot = false;
+- // Only service repaintRoot once.
+- repaintRoot = null;
+- }
++ }, stack, acc);
+ }
+ } finally {
+ painting = false;
+diff --git a/src/share/classes/sun/applet/AppletPanel.java b/src/share/classes/sun/applet/AppletPanel.java
+--- jdk/src/share/classes/sun/applet/AppletPanel.java
++++ jdk/src/share/classes/sun/applet/AppletPanel.java
+@@ -47,6 +47,7 @@ import java.util.WeakHashMap;
+ import java.util.WeakHashMap;
+ import javax.swing.SwingUtilities;
+ import sun.awt.AppContext;
++import sun.awt.AWTAccessor;
+ import sun.awt.EmbeddedFrame;
+ import sun.awt.SunToolkit;
+ import sun.misc.MessageUtils;
+@@ -449,12 +450,12 @@ abstract class AppletPanel extends Panel
+ // to avoid deadlock.
+ try {
+ final AppletPanel p = this;
+-
+- SwingUtilities.invokeAndWait(new Runnable() {
+- public void run() {
+- p.validate();
+- }
+- });
++ Runnable r = new Runnable() {
++ public void run() {
++ p.validate();
++ }
++ };
++ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
+ }
+ catch(InterruptedException ie) {
+ }
+@@ -479,18 +480,19 @@ abstract class AppletPanel extends Panel
+ try {
+ final AppletPanel p = this;
+ final Applet a = applet;
++ Runnable r = new Runnable() {
++ public void run() {
++ p.validate();
++ a.setVisible(true);
+
+- SwingUtilities.invokeAndWait(new Runnable() {
+- public void run() {
+- p.validate();
+- a.setVisible(true);
+-
+- // Fix for BugTraq ID 4041703.
+- // Set the default focus for an applet.
+- if (hasInitialFocus())
+- setDefaultFocus();
++ // Fix for BugTraq ID 4041703.
++ // Set the default focus for an applet.
++ if (hasInitialFocus()) {
++ setDefaultFocus();
+ }
+- });
++ }
++ };
++ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
+ }
+ catch(InterruptedException ie) {
+ }
+@@ -513,13 +515,12 @@ abstract class AppletPanel extends Panel
+ // to avoid deadlock.
+ try {
+ final Applet a = applet;
+-
+- SwingUtilities.invokeAndWait(new Runnable() {
+- public void run()
+- {
+- a.setVisible(false);
+- }
+- });
++ Runnable r = new Runnable() {
++ public void run() {
++ a.setVisible(false);
++ }
++ };
++ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
+ }
+ catch(InterruptedException ie) {
+ }
+@@ -571,17 +572,14 @@ abstract class AppletPanel extends Panel
+ }
+ status = APPLET_DISPOSE;
+
+- try
+- {
++ try {
+ final Applet a = applet;
+-
+- EventQueue.invokeAndWait(new Runnable()
+- {
+- public void run()
+- {
++ Runnable r = new Runnable() {
++ public void run() {
+ remove(a);
+ }
+- });
++ };
++ AWTAccessor.getEventQueueAccessor().invokeAndWait(applet, r);
+ }
+ catch(InterruptedException ie)
+ {
+diff --git a/src/share/classes/sun/awt/AWTAccessor.java b/src/share/classes/sun/awt/AWTAccessor.java
+--- jdk/src/share/classes/sun/awt/AWTAccessor.java
++++ jdk/src/share/classes/sun/awt/AWTAccessor.java
+@@ -29,6 +29,7 @@ import java.awt.*;
+
+ import sun.misc.Unsafe;
+
++import java.lang.reflect.InvocationTargetException;
+ import java.security.AccessControlContext;
+
+ import java.util.Vector;
+@@ -198,6 +199,11 @@ public final class AWTAccessor {
+ */
+ void removeSourceEvents(EventQueue eventQueue, Object source,
+ boolean removeAllEvents);
++ /**
++ * Static in EventQueue
++ */
++ void invokeAndWait(Object source, Runnable r)
++ throws InterruptedException, InvocationTargetException;
+ }
+
+ /**
+diff --git a/src/windows/classes/sun/awt/windows/WComponentPeer.java b/src/windows/classes/sun/awt/windows/WComponentPeer.java
+--- jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java
++++ jdk/src/windows/classes/sun/awt/windows/WComponentPeer.java
+@@ -427,14 +427,15 @@ public abstract class WComponentPeer ext
+ try {
+ replaceSurfaceData();
+ } catch (InvalidPipeException e) {
+- // REMIND : what do we do if our surface creation failed?
++ // REMIND : what do we do if our surface creation failed?
+ }
+ }
+ }
+ };
++ Component c = (Component)target;
+ // Fix 6255371.
+- if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing((Component)target, r)) {
+- postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(), r));
++ if (!PaintEventDispatcher.getPaintEventDispatcher().queueSurfaceDataReplacing(c, r)) {
++ postEvent(new InvocationEvent(c, r));
+ }
+ }
+
diff --git a/java/openjdk6/files/icedtea/security/20130201/7197546.patch b/java/openjdk6/files/icedtea/security/20130201/7197546.patch
new file mode 100644
index 000000000000..890ae091d9f0
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7197546.patch
@@ -0,0 +1,479 @@
+# HG changeset patch
+# User mbankal
+# Date 1355327990 28800
+# Node ID 41f8dd88c5e9aec4975c36414a865aed5643c880
+# Parent 708c134c36312faf8721c0c981be6553e4ebf49f
+7197546: (proxy) Reflect about creating reflective proxies
+Reviewed-by: mchung
+
+diff --git a/src/share/classes/java/lang/Class.java b/src/share/classes/java/lang/Class.java
+--- jdk/src/share/classes/java/lang/Class.java
++++ jdk/src/share/classes/java/lang/Class.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1994, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -65,7 +65,9 @@ import sun.reflect.generics.scope.ClassS
+ import sun.reflect.generics.scope.ClassScope;
+ import sun.security.util.SecurityConstants;
+ import java.lang.annotation.Annotation;
++import java.lang.reflect.Proxy;
+ import sun.reflect.annotation.*;
++import sun.reflect.misc.ReflectUtil;
+
+ /**
+ * Instances of the class {@code Class} represent classes and
+@@ -320,7 +322,7 @@ public final
+ throws InstantiationException, IllegalAccessException
+ {
+ if (System.getSecurityManager() != null) {
+- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
+ }
+ return newInstance0();
+ }
+@@ -1294,7 +1296,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false);
+
+ // Privileged so this implementation can look at DECLARED classes,
+ // something the caller might not have privilege to do. The code here
+@@ -1372,7 +1374,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ return copyFields(privateGetPublicFields(null));
+ }
+
+@@ -1423,7 +1425,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ return copyMethods(privateGetPublicMethods());
+ }
+
+@@ -1472,7 +1474,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ return copyConstructors(privateGetDeclaredConstructors(true));
+ }
+
+@@ -1531,7 +1533,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ Field field = getField0(name);
+ if (field == null) {
+ throw new NoSuchFieldException(name);
+@@ -1616,7 +1618,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ Method method = getMethod0(name, parameterTypes);
+ if (method == null) {
+ throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
+@@ -1670,7 +1672,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), true);
+ return getConstructor0(parameterTypes, Member.PUBLIC);
+ }
+
+@@ -1712,7 +1714,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), false);
+ return getDeclaredClasses0();
+ }
+
+@@ -1756,7 +1758,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ return copyFields(privateGetDeclaredFields(false));
+ }
+
+@@ -1804,7 +1806,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ return copyMethods(privateGetDeclaredMethods(false));
+ }
+
+@@ -1849,7 +1851,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ return copyConstructors(privateGetDeclaredConstructors(false));
+ }
+
+@@ -1893,7 +1895,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ Field field = searchFields(privateGetDeclaredFields(false), name);
+ if (field == null) {
+ throw new NoSuchFieldException(name);
+@@ -1948,7 +1950,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
+ if (method == null) {
+ throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
+@@ -1998,7 +2000,7 @@ public final
+ // be very careful not to change the stack depth of this
+ // checkMemberAccess call for security reasons
+ // see java.lang.SecurityManager.checkMemberAccess
+- checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
++ checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader(), true);
+ return getConstructor0(parameterTypes, Member.DECLARED);
+ }
+
+@@ -2168,18 +2170,26 @@ public final
+ * <p> Default policy: allow all clients access with normal Java access
+ * control.
+ */
+- private void checkMemberAccess(int which, ClassLoader ccl) {
++ private void checkMemberAccess(int which, ClassLoader ccl, boolean checkProxyInterfaces) {
+ SecurityManager s = System.getSecurityManager();
+ if (s != null) {
+ s.checkMemberAccess(this, which);
+ ClassLoader cl = getClassLoader0();
+- if ((ccl != null) && (ccl != cl) &&
+- ((cl == null) || !cl.isAncestor(ccl))) {
++ if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
++
+ String name = this.getName();
+ int i = name.lastIndexOf('.');
+ if (i != -1) {
+- s.checkPackageAccess(name.substring(0, i));
++ // skip the package access check on a proxy class in default proxy package
++ String pkg = name.substring(0, i);
++ if (!Proxy.isProxyClass(this) || !pkg.equals(ReflectUtil.PROXY_PACKAGE)) {
++ s.checkPackageAccess(pkg);
++ }
+ }
++ }
++ // check package access on the proxy interfaces
++ if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
++ ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces());
+ }
+ }
+ }
+diff --git a/src/share/classes/java/lang/reflect/Proxy.java b/src/share/classes/java/lang/reflect/Proxy.java
+--- jdk/src/share/classes/java/lang/reflect/Proxy.java
++++ jdk/src/share/classes/java/lang/reflect/Proxy.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -27,6 +27,9 @@ package java.lang.reflect;
+
+ import java.lang.ref.Reference;
+ import java.lang.ref.WeakReference;
++import java.security.AccessController;
++import java.security.Permission;
++import java.security.PrivilegedAction;
+ import java.util.Arrays;
+ import java.util.Collections;
+ import java.util.HashMap;
+@@ -35,6 +38,9 @@ import java.util.Set;
+ import java.util.Set;
+ import java.util.WeakHashMap;
+ import sun.misc.ProxyGenerator;
++import sun.reflect.Reflection;
++import sun.reflect.misc.ReflectUtil;
++import sun.security.util.SecurityConstants;
+
+ /**
+ * {@code Proxy} provides static methods for creating dynamic proxy
+@@ -263,7 +269,67 @@ public class Proxy implements java.io.Se
+ * @param h the invocation handler for this proxy instance
+ */
+ protected Proxy(InvocationHandler h) {
++ doNewInstanceCheck();
+ this.h = h;
++ }
++
++ private static class ProxyAccessHelper {
++ // The permission is implementation specific.
++ static final Permission PROXY_PERMISSION =
++ new ReflectPermission("proxyConstructorNewInstance");
++ // These system properties are defined to provide a short-term
++ // workaround if customers need to disable the new security checks.
++ static final boolean allowNewInstance;
++ static final boolean allowNullLoader;
++ static {
++ allowNewInstance = getBooleanProperty("sun.reflect.proxy.allowsNewInstance");
++ allowNullLoader = getBooleanProperty("sun.reflect.proxy.allowsNullLoader");
++ }
++
++ private static boolean getBooleanProperty(final String key) {
++ String s = AccessController.doPrivileged(new PrivilegedAction<String>() {
++ public String run() {
++ return System.getProperty(key);
++ }
++ });
++ return Boolean.valueOf(s);
++ }
++
++ static boolean needsNewInstanceCheck(Class<?> proxyClass) {
++ if (!Proxy.isProxyClass(proxyClass) || allowNewInstance) {
++ return false;
++ }
++
++ if (proxyClass.getName().startsWith(ReflectUtil.PROXY_PACKAGE + ".")) {
++ // all proxy interfaces are public
++ return false;
++ }
++ for (Class<?> intf : proxyClass.getInterfaces()) {
++ if (!Modifier.isPublic(intf.getModifiers())) {
++ return true;
++ }
++ }
++ return false;
++ }
++ }
++
++ /*
++ * Access check on a proxy class that implements any non-public interface.
++ *
++ * @throws SecurityException if a security manager exists, and
++ * the caller does not have the permission.
++ */
++ private void doNewInstanceCheck() {
++ SecurityManager sm = System.getSecurityManager();
++ Class<?> proxyClass = this.getClass();
++ if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(proxyClass)) {
++ try {
++ sm.checkPermission(ProxyAccessHelper.PROXY_PERMISSION);
++ } catch (SecurityException e) {
++ throw new SecurityException("Not allowed to construct a Proxy "
++ + "instance that implements a non-public interface", e);
++ }
++ }
+ }
+
+ /**
+@@ -344,6 +410,50 @@ public class Proxy implements java.io.Se
+ Class<?>... interfaces)
+ throws IllegalArgumentException
+ {
++ return getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
++ }
++
++ private static void checkProxyLoader(ClassLoader ccl,
++ ClassLoader loader)
++ {
++ SecurityManager sm = System.getSecurityManager();
++ if (sm != null) {
++ if (loader == null && ccl != null) {
++ if (!ProxyAccessHelper.allowNullLoader) {
++ sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
++ }
++ }
++ }
++ }
++
++ /*
++ * Generate a proxy class (caller-sensitive).
++ *
++ * To define a proxy class, it performs the access checks as in
++ * Class.forName (VM will invoke ClassLoader.checkPackageAccess):
++ * 1. "getClassLoader" permission check if loader == null
++ * 2. checkPackageAccess on the interfaces it implements
++ *
++ * To get a constructor and new instance of a proxy class, it performs
++ * the package access check on the interfaces it implements
++ * as in Class.getConstructor.
++ *
++ * If an interface is non-public, the proxy class must be defined by
++ * the defining loader of the interface. If the caller's class loader
++ * is not the same as the defining loader of the interface, the VM
++ * will throw IllegalAccessError when the generated proxy class is
++ * being defined via the defineClass0 method.
++ */
++ private static Class<?> getProxyClass0(ClassLoader loader,
++ Class<?>... interfaces) {
++ SecurityManager sm = System.getSecurityManager();
++ if (sm != null) {
++ final int CALLER_FRAME = 3; // 0: Reflection, 1: getProxyClass0 2: Proxy 3: caller
++ final Class<?> caller = Reflection.getCallerClass(CALLER_FRAME);
++ final ClassLoader ccl = caller.getClassLoader();
++ checkProxyLoader(ccl, loader);
++ ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
++ }
+ if (interfaces.length > 65535) {
+ throw new IllegalArgumentException("interface limit exceeded");
+ }
+@@ -494,8 +604,9 @@ public class Proxy implements java.io.Se
+ }
+ }
+
+- if (proxyPkg == null) { // if no non-public proxy interfaces,
+- proxyPkg = ""; // use the unnamed package
++ if (proxyPkg == null) {
++ // if no non-public proxy interfaces, use sun.proxy package
++ proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
+ }
+
+ {
+@@ -595,22 +706,45 @@ public class Proxy implements java.io.Se
+ /*
+ * Look up or generate the designated proxy class.
+ */
+- Class cl = getProxyClass(loader, interfaces);
++ Class<?> cl = getProxyClass0(loader, interfaces); // stack walk magic: do not refactor
+
+ /*
+ * Invoke its constructor with the designated invocation handler.
+ */
+ try {
+- Constructor cons = cl.getConstructor(constructorParams);
+- return (Object) cons.newInstance(new Object[] { h });
++ final Constructor<?> cons = cl.getConstructor(constructorParams);
++ final InvocationHandler ih = h;
++ SecurityManager sm = System.getSecurityManager();
++ if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
++ // create proxy instance with doPrivilege as the proxy class may
++ // implement non-public interfaces that requires a special permission
++ return AccessController.doPrivileged(new PrivilegedAction<Object>() {
++ public Object run() {
++ return newInstance(cons, ih);
++ }
++ });
++ } else {
++ return newInstance(cons, ih);
++ }
+ } catch (NoSuchMethodException e) {
+ throw new InternalError(e.toString());
++ }
++ }
++
++ private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
++ try {
++ return cons.newInstance(new Object[] {h} );
+ } catch (IllegalAccessException e) {
+ throw new InternalError(e.toString());
+ } catch (InstantiationException e) {
+ throw new InternalError(e.toString());
+ } catch (InvocationTargetException e) {
+- throw new InternalError(e.toString());
++ Throwable t = e.getCause();
++ if (t instanceof RuntimeException) {
++ throw (RuntimeException) t;
++ } else {
++ throw new InternalError(t.toString());
++ }
+ }
+ }
+
+diff --git a/src/share/classes/sun/reflect/misc/ReflectUtil.java b/src/share/classes/sun/reflect/misc/ReflectUtil.java
+--- jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java
++++ jdk/src/share/classes/sun/reflect/misc/ReflectUtil.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -144,4 +144,63 @@ public final class ReflectUtil {
+ }
+ return true;
+ }
++
++ // Returns true if p is an ancestor of cl i.e. class loader 'p' can
++ // be found in the cl's delegation chain
++ private static boolean isAncestor(ClassLoader p, ClassLoader cl) {
++ ClassLoader acl = cl;
++ do {
++ acl = acl.getParent();
++ if (p == acl) {
++ return true;
++ }
++ } while (acl != null);
++ return false;
++ }
++
++ /**
++ * Returns true if package access check is needed for reflective
++ * access from a class loader 'from' to classes or members in
++ * a class defined by class loader 'to'. This method returns true
++ * if 'from' is not the same as or an ancestor of 'to'. All code
++ * in a system domain are granted with all permission and so this
++ * method returns false if 'from' class loader is a class loader
++ * loading system classes. On the other hand, if a class loader
++ * attempts to access system domain classes, it requires package
++ * access check and this method will return true.
++ */
++ public static boolean needsPackageAccessCheck(ClassLoader from, ClassLoader to) {
++ if (from == null || from == to)
++ return false;
++
++ if (to == null)
++ return true;
++
++ return !isAncestor(from, to);
++ }
++
++ /**
++ * Access check on the interfaces that a proxy class implements and throw
++ * {@code SecurityException} if it accesses a restricted package.
++ *
++ * @param ccl the caller's class loader
++ * @param interfaces the list of interfaces that a proxy class implements
++ *
++ * @see Proxy#checkProxyAccess
++ */
++ public static void checkProxyPackageAccess(ClassLoader ccl,
++ Class<?>... interfaces)
++ {
++ SecurityManager sm = System.getSecurityManager();
++ if (sm != null) {
++ for (Class<?> intf : interfaces) {
++ ClassLoader cl = intf.getClassLoader();
++ if (needsPackageAccessCheck(ccl, cl)) {
++ checkPackageAccess(intf);
++ }
++ }
++ }
++ }
++
++ public static final String PROXY_PACKAGE = "sun.proxy";
+ }
diff --git a/java/openjdk6/files/icedtea/security/20130201/7200491.patch b/java/openjdk6/files/icedtea/security/20130201/7200491.patch
new file mode 100644
index 000000000000..c8bfbf50eb27
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7200491.patch
@@ -0,0 +1,49 @@
+# HG changeset patch
+# User rupashka
+# Date 1352203457 -14400
+# Node ID ac55f56db9ab0280853c4a6bfbdc2c578027f9f2
+# Parent 6deb10c2d5d0c8925fd2012d9fc3b9325c997f21
+7200491: Tighten up JTable layout code
+Reviewed-by: art, skoivu
+
+diff --git a/src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java b/src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java
+--- jdk/src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java
++++ jdk/src/share/classes/com/sun/java/swing/plaf/nimbus/NimbusLookAndFeel.java
+@@ -159,7 +159,12 @@ public class NimbusLookAndFeel extends S
+
+ // Store Table ScrollPane Corner Component
+ uiDefaults.put("Table.scrollPaneCornerComponent",
+- TableScrollPaneCorner.class);
++ new UIDefaults.ActiveValue() {
++ @Override
++ public Object createValue(UIDefaults table) {
++ return new TableScrollPaneCorner();
++ }
++ });
+
+ // Setup the settings for ToolBarSeparator which is custom
+ // installed for Nimbus
+diff --git a/src/share/classes/javax/swing/JTable.java b/src/share/classes/javax/swing/JTable.java
+--- jdk/src/share/classes/javax/swing/JTable.java
++++ jdk/src/share/classes/javax/swing/JTable.java
+@@ -777,15 +777,11 @@ public class JTable extends JComponent i
+ scrollPane.getCorner(JScrollPane.UPPER_TRAILING_CORNER);
+ if (corner == null || corner instanceof UIResource){
+ corner = null;
+- Object componentClass = UIManager.get(
+- "Table.scrollPaneCornerComponent");
+- if (componentClass instanceof Class){
+- try {
+- corner = (Component)
+- ((Class)componentClass).newInstance();
+- } catch (Exception e) {
+- // just ignore and don't set corner
+- }
++ try {
++ corner = (Component) UIManager.get(
++ "Table.scrollPaneCornerComponent");
++ } catch (Exception e) {
++ // just ignore and don't set corner
+ }
+ scrollPane.setCorner(JScrollPane.UPPER_TRAILING_CORNER,
+ corner);
diff --git a/java/openjdk6/files/icedtea/security/20130201/7200500.patch b/java/openjdk6/files/icedtea/security/20130201/7200500.patch
new file mode 100644
index 000000000000..20106060ee3b
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7200500.patch
@@ -0,0 +1,60 @@
+# HG changeset patch
+# User coffeys
+# Date 1353019348 0
+# Node ID 27bb245457d801fab2a5a835e42a4adefdf7ce85
+# Parent 46582c3c96b3fdd43b58761c3869ce55fad1c755
+7200500: Launcher better input validation
+Reviewed-by: ksrini
+
+diff --git a/src/share/bin/parse_manifest.c b/src/share/bin/parse_manifest.c
+--- jdk/src/share/bin/parse_manifest.c
++++ jdk/src/share/bin/parse_manifest.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -487,9 +487,9 @@ JLI_ParseManifest(char *jarfile, manifes
+ #ifdef O_BINARY
+ | O_BINARY /* use binary mode on windows */
+ #endif
+- )) == -1)
++ )) == -1) {
+ return (-1);
+-
++ }
+ info->manifest_version = NULL;
+ info->main_class = NULL;
+ info->jre_version = NULL;
+@@ -536,12 +536,14 @@ JLI_JarUnpackFile(const char *jarfile, c
+ zentry entry;
+ void *data = NULL;
+
+- fd = open(jarfile, O_RDONLY
++ if ((fd = open(jarfile, O_RDONLY
+ #ifdef O_BINARY
+ | O_BINARY /* use binary mode on windows */
+ #endif
+- );
+- if (fd != -1 && find_file(fd, &entry, filename) == 0) {
++ )) == -1) {
++ return NULL;
++ }
++ if (find_file(fd, &entry, filename) == 0) {
+ data = inflate_file(fd, &entry, size);
+ }
+ close(fd);
+@@ -583,9 +585,9 @@ JLI_ManifestIterate(const char *jarfile,
+ #ifdef O_BINARY
+ | O_BINARY /* use binary mode on windows */
+ #endif
+- )) == -1)
++ )) == -1) {
+ return (-1);
+-
++ }
+ if (rc = find_file(fd, &entry, manifest_name) != 0) {
+ close(fd);
+ return (-2);
diff --git a/java/openjdk6/files/icedtea/security/20130201/7201064.patch b/java/openjdk6/files/icedtea/security/20130201/7201064.patch
new file mode 100644
index 000000000000..3ab97af24fc9
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7201064.patch
@@ -0,0 +1,117 @@
+diff --git a/src/share/classes/java/awt/Dialog.java b/src/share/classes/java/awt/Dialog.java
+--- jdk/src/share/classes/java/awt/Dialog.java
++++ jdk/src/share/classes/java/awt/Dialog.java
+@@ -34,6 +34,7 @@ import java.security.PrivilegedAction;
+ import java.security.PrivilegedAction;
+ import javax.accessibility.*;
+ import sun.awt.AppContext;
++import java.security.AccessControlException;
+ import sun.awt.SunToolkit;
+ import sun.awt.PeerEvent;
+ import sun.awt.util.IdentityArrayList;
+@@ -127,6 +128,8 @@ public class Dialog extends Window {
+ * @since 1.4
+ */
+ boolean undecorated = false;
++
++ private transient boolean initialized = false;
+
+ /**
+ * Modal dialogs block all input to some top-level windows.
+@@ -679,6 +682,7 @@ public class Dialog extends Window {
+ this.title = title;
+ setModalityType(modalityType);
+ SunToolkit.checkAndSetPolicy(this, false);
++ initialized = true;
+ }
+
+ /**
+@@ -730,6 +734,7 @@ public class Dialog extends Window {
+ this.title = title;
+ setModalityType(modalityType);
+ SunToolkit.checkAndSetPolicy(this, false);
++ initialized = true;
+ }
+
+ /**
+@@ -859,12 +864,9 @@ public class Dialog extends Window {
+ if (modalityType == type) {
+ return;
+ }
+- if (type == ModalityType.TOOLKIT_MODAL) {
+- SecurityManager sm = System.getSecurityManager();
+- if (sm != null) {
+- sm.checkPermission(SecurityConstants.TOOLKIT_MODALITY_PERMISSION);
+- }
+- }
++
++ checkModalityPermission(type);
++
+ modalityType = type;
+ modal = (modalityType != ModalityType.MODELESS);
+ }
+@@ -1039,6 +1041,11 @@ public class Dialog extends Window {
+ */
+ @Deprecated
+ public void show() {
++ if (!initialized) {
++ throw new IllegalStateException("The dialog component " +
++ "has not been initialized properly");
++ }
++
+ beforeFirstShow = false;
+ if (!isModal()) {
+ conditionalShow(null, null);
+@@ -1614,18 +1621,50 @@ public class Dialog extends Window {
+ }
+ }
+
++ private void checkModalityPermission(ModalityType mt) {
++ if (mt == ModalityType.TOOLKIT_MODAL) {
++ SecurityManager sm = System.getSecurityManager();
++ if (sm != null) {
++ sm.checkPermission(
++ SecurityConstants.TOOLKIT_MODALITY_PERMISSION
++ );
++ }
++ }
++ }
++
+ private void readObject(ObjectInputStream s)
+ throws ClassNotFoundException, IOException, HeadlessException
+ {
+ GraphicsEnvironment.checkHeadless();
+- s.defaultReadObject();
++
++ java.io.ObjectInputStream.GetField fields =
++ s.readFields();
++
++ ModalityType localModalityType = (ModalityType)fields.get("modalityType", null);
++
++ try {
++ checkModalityPermission(localModalityType);
++ } catch (AccessControlException ace) {
++ localModalityType = DEFAULT_MODALITY_TYPE;
++ }
+
+ // in 1.5 or earlier modalityType was absent, so use "modal" instead
+- if (modalityType == null) {
++ if (localModalityType == null) {
++ this.modal = fields.get("modal", false);
+ setModal(modal);
+ }
+
++ this.resizable = fields.get("resizable", true);
++ this.undecorated = fields.get("undecorated", false);
++ this.title = (String)fields.get("title", "");
++ this.modalityType = localModalityType;
++
+ blockedWindows = new IdentityArrayList();
++
++ SunToolkit.checkAndSetPolicy(this, false);
++
++ initialized = true;
++
+ }
+
+ /*
diff --git a/java/openjdk6/files/icedtea/security/20130201/7201066.patch b/java/openjdk6/files/icedtea/security/20130201/7201066.patch
new file mode 100644
index 000000000000..2a38f116a6f0
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7201066.patch
@@ -0,0 +1,66 @@
+# HG changeset patch
+# User coffeys
+# Date 1352217014 0
+# Node ID 58fdb67fcacc67693fc43b5601e88bd7c216f850
+# Parent 42b1142b39b5a511e1e07b5877cc55e93767064e
+7201066: Change modifiers on unused fields
+Reviewed-by: alanb, skoivu
+
+diff --git a/src/share/classes/com/sun/corba/se/impl/activation/ServerMain.java b/src/share/classes/com/sun/corba/se/impl/activation/ServerMain.java
+--- corba/src/share/classes/com/sun/corba/se/impl/activation/ServerMain.java
++++ corba/src/share/classes/com/sun/corba/se/impl/activation/ServerMain.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -322,9 +322,9 @@ class ServerCallback extends
+ com.sun.corba.se.spi.activation._ServerImplBase
+ {
+ private ORB orb;
+- private Method installMethod ;
+- private Method uninstallMethod ;
+- private Method shutdownMethod ;
++ private transient Method installMethod ;
++ private transient Method uninstallMethod ;
++ private transient Method shutdownMethod ;
+ private Object methodArgs[] ;
+
+ ServerCallback(ORB orb, Method installMethod, Method uninstallMethod,
+diff --git a/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java b/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
+--- corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
++++ corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
+@@ -1536,8 +1536,8 @@ public class ObjectStreamClass implement
+ private boolean hasExternalizableBlockData;
+ Method writeObjectMethod;
+ Method readObjectMethod;
+- private Method writeReplaceObjectMethod;
+- private Method readResolveObjectMethod;
++ private transient Method writeReplaceObjectMethod;
++ private transient Method readResolveObjectMethod;
+ private Constructor cons ;
+
+ /**
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java
++++ corba/src/share/classes/com/sun/corba/se/impl/orbutil/ObjectStreamClass_1_3_1.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2001, 2003, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -1119,8 +1119,8 @@ public class ObjectStreamClass_1_3_1 imp
+ private boolean hasExternalizableBlockData;
+ Method writeObjectMethod;
+ Method readObjectMethod;
+- private Method writeReplaceObjectMethod;
+- private Method readResolveObjectMethod;
++ private transient Method writeReplaceObjectMethod;
++ private transient Method readResolveObjectMethod;
+
+ /*
+ * ObjectStreamClass_1_3_1 that this one was built from.
diff --git a/java/openjdk6/files/icedtea/security/20130201/7201068.patch b/java/openjdk6/files/icedtea/security/20130201/7201068.patch
new file mode 100644
index 000000000000..a9e9e7f859ad
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7201068.patch
@@ -0,0 +1,83 @@
+# HG changeset patch
+# User coffeys
+# Date 1352286387 0
+# Node ID 6e2d4ed84b41667df189abb7bd0915cda01a85a0
+# Parent ac55f56db9ab0280853c4a6bfbdc2c578027f9f2
+7201068: Better handling of UI elements
+Reviewed-by: mullan, skoivu
+
+diff --git a/src/share/lib/security/java.security b/src/share/lib/security/java.security
+--- jdk/src/share/lib/security/java.security
++++ jdk/src/share/lib/security/java.security
+@@ -127,7 +127,9 @@ system.scope=sun.security.provider.Ident
+ # passed to checkPackageAccess unless the
+ # corresponding RuntimePermission ("accessClassInPackage."+package) has
+ # been granted.
+-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.
++package.access=sun.,\
++ com.sun.xml.internal.,\
++ com.sun.imageio.
+
+ #
+ # List of comma-separated packages that start with or equal this string
+@@ -139,7 +141,9 @@ package.access=sun.,com.sun.xml.internal
+ # by default, none of the class loaders supplied with the JDK call
+ # checkPackageDefinition.
+ #
+-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.
++package.definition=sun.,\
++ com.sun.xml.internal.,\
++ com.sun.imageio.
+
+ #
+ # Determines whether this properties file can be appended to
+diff --git a/src/share/lib/security/java.security-solaris b/src/share/lib/security/java.security-solaris
+--- jdk/src/share/lib/security/java.security-solaris
++++ jdk/src/share/lib/security/java.security-solaris
+@@ -128,7 +128,9 @@ system.scope=sun.security.provider.Ident
+ # passed to checkPackageAccess unless the
+ # corresponding RuntimePermission ("accessClassInPackage."+package) has
+ # been granted.
+-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.
++package.access=sun.,\
++ com.sun.xml.internal.,\
++ com.sun.imageio.
+
+ #
+ # List of comma-separated packages that start with or equal this string
+@@ -140,7 +142,9 @@ package.access=sun.,com.sun.xml.internal
+ # by default, none of the class loaders supplied with the JDK call
+ # checkPackageDefinition.
+ #
+-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.
++package.definition=sun.,\
++ com.sun.xml.internal.,\
++ com.sun.imageio.
+
+ #
+ # Determines whether this properties file can be appended to
+diff --git a/src/share/lib/security/java.security-windows b/src/share/lib/security/java.security-windows
+--- jdk/src/share/lib/security/java.security-windows
++++ jdk/src/share/lib/security/java.security-windows
+@@ -128,7 +128,9 @@ system.scope=sun.security.provider.Ident
+ # passed to checkPackageAccess unless the
+ # corresponding RuntimePermission ("accessClassInPackage."+package) has
+ # been granted.
+-package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.
++package.access=sun.,\
++ com.sun.xml.internal.,\
++ com.sun.imageio.
+
+ #
+ # List of comma-separated packages that start with or equal this string
+@@ -140,7 +142,9 @@ package.access=sun.,com.sun.xml.internal
+ # by default, none of the class loaders supplied with the JDK call
+ # checkPackageDefinition.
+ #
+-package.definition=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.
++package.definition=sun.,\
++ com.sun.xml.internal.,\
++ com.sun.imageio.
+
+ #
+ # Determines whether this properties file can be appended to
diff --git a/java/openjdk6/files/icedtea/security/20130201/7201070.patch b/java/openjdk6/files/icedtea/security/20130201/7201070.patch
new file mode 100644
index 000000000000..77df21d28374
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7201070.patch
@@ -0,0 +1,31 @@
+# HG changeset patch
+# User coffeys
+# Date 1355322673 0
+# Node ID 042882b32f75d0e736c19f93688d37fb98d7d26d
+# Parent 708c134c36312faf8721c0c981be6553e4ebf49f
+7201070: Serialization to conform to protocol
+Reviewed-by: smarks, skoivu
+
+diff --git a/src/share/classes/java/io/ObjectInputStream.java b/src/share/classes/java/io/ObjectInputStream.java
+--- jdk/src/share/classes/java/io/ObjectInputStream.java
++++ jdk/src/share/classes/java/io/ObjectInputStream.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -1749,6 +1749,12 @@ public class ObjectInputStream
+ ObjectStreamClass desc = readClassDesc(false);
+ desc.checkDeserialize();
+
++ Class<?> cl = desc.forClass();
++ if (cl == String.class || cl == Class.class
++ || cl == ObjectStreamClass.class) {
++ throw new InvalidClassException("invalid class descriptor");
++ }
++
+ Object obj;
+ try {
+ obj = desc.isInstantiable() ? desc.newInstance() : null;
diff --git a/java/openjdk6/files/icedtea/security/20130201/7201071.patch b/java/openjdk6/files/icedtea/security/20130201/7201071.patch
new file mode 100644
index 000000000000..58329d174c3a
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/7201071.patch
@@ -0,0 +1,553 @@
+# HG changeset patch
+# User robm
+# Date 1352819613 0
+# Node ID 46582c3c96b3fdd43b58761c3869ce55fad1c755
+# Parent ee4632a30696050ebd5c014fb3da64112ab48dd3
+7201071: InetSocketAddress serialization issue
+Reviewed-by: chegar
+
+diff --git a/src/share/classes/java/net/InetSocketAddress.java b/src/share/classes/java/net/InetSocketAddress.java
+--- jdk/src/share/classes/java/net/InetSocketAddress.java
++++ jdk/src/share/classes/java/net/InetSocketAddress.java
+@@ -24,9 +24,12 @@
+ */
+ package java.net;
+
+-import java.io.ObjectInputStream;
+ import java.io.IOException;
+ import java.io.InvalidObjectException;
++import java.io.ObjectInputStream;
++import java.io.ObjectOutputStream;
++import java.io.ObjectStreamException;
++import java.io.ObjectStreamField;
+
+ /**
+ *
+@@ -46,24 +49,106 @@ import java.io.InvalidObjectException;
+ * @see java.net.ServerSocket
+ * @since 1.4
+ */
+-public class InetSocketAddress extends SocketAddress {
+- /* The hostname of the Socket Address
+- * @serial
+- */
+- private String hostname = null;
+- /* The IP address of the Socket Address
+- * @serial
+- */
+- private InetAddress addr = null;
+- /* The port number of the Socket Address
+- * @serial
+- */
+- private int port;
++public class InetSocketAddress
++ extends SocketAddress
++{
++ // Private implementation class pointed to by all public methods.
++ private static class InetSocketAddressHolder {
++ // The hostname of the Socket Address
++ private String hostname;
++ // The IP address of the Socket Address
++ private InetAddress addr;
++ // The port number of the Socket Address
++ private int port;
++
++ private InetSocketAddressHolder(String hostname, InetAddress addr, int port) {
++ this.hostname = hostname;
++ this.addr = addr;
++ this.port = port;
++ }
++
++ private int getPort() {
++ return port;
++ }
++
++ private InetAddress getAddress() {
++ return addr;
++ }
++
++ private String getHostName() {
++ if (hostname != null)
++ return hostname;
++ if (addr != null)
++ return addr.getHostName();
++ return null;
++ }
++
++ private String getHostString() {
++ if (hostname != null)
++ return hostname;
++ if (addr != null) {
++ if (addr.hostName != null)
++ return addr.hostName;
++ else
++ return addr.getHostAddress();
++ }
++ return null;
++ }
++
++ private boolean isUnresolved() {
++ return addr == null;
++ }
++
++ @Override
++ public String toString() {
++ if (isUnresolved()) {
++ return hostname + ":" + port;
++ } else {
++ return addr.toString() + ":" + port;
++ }
++ }
++
++ @Override
++ public final boolean equals(Object obj) {
++ if (obj == null || !(obj instanceof InetSocketAddressHolder))
++ return false;
++ InetSocketAddressHolder that = (InetSocketAddressHolder)obj;
++ boolean sameIP;
++ if (addr != null)
++ sameIP = addr.equals(that.addr);
++ else if (hostname != null)
++ sameIP = (that.addr == null) &&
++ hostname.equalsIgnoreCase(that.hostname);
++ else
++ sameIP = (that.addr == null) && (that.hostname == null);
++ return sameIP && (port == that.port);
++ }
++
++ @Override
++ public final int hashCode() {
++ if (addr != null)
++ return addr.hashCode() + port;
++ if (hostname != null)
++ return hostname.toLowerCase().hashCode() + port;
++ return port;
++ }
++ }
++
++ private final transient InetSocketAddressHolder holder;
+
+ private static final long serialVersionUID = 5076001401234631237L;
+
+- private InetSocketAddress() {
++ private static int checkPort(int port) {
++ if (port < 0 || port > 0xFFFF)
++ throw new IllegalArgumentException("port out of range:" + port);
++ return port;
+ }
++
++ private static String checkHost(String hostname) {
++ if (hostname == null)
++ throw new IllegalArgumentException("hostname can't be null");
++ return hostname;
++ }
+
+ /**
+ * Creates a socket address where the IP address is the wildcard address
+@@ -97,14 +182,10 @@ public class InetSocketAddress extends S
+ * range of valid port values.
+ */
+ public InetSocketAddress(InetAddress addr, int port) {
+- if (port < 0 || port > 0xFFFF) {
+- throw new IllegalArgumentException("port out of range:" + port);
+- }
+- this.port = port;
+- if (addr == null)
+- this.addr = InetAddress.anyLocalAddress();
+- else
+- this.addr = addr;
++ holder = new InetSocketAddressHolder(
++ null,
++ addr == null ? InetAddress.anyLocalAddress() : addr,
++ checkPort(port));
+ }
+
+ /**
+@@ -132,19 +213,20 @@ public class InetSocketAddress extends S
+ * @see #isUnresolved()
+ */
+ public InetSocketAddress(String hostname, int port) {
+- if (port < 0 || port > 0xFFFF) {
+- throw new IllegalArgumentException("port out of range:" + port);
+- }
+- if (hostname == null) {
+- throw new IllegalArgumentException("hostname can't be null");
+- }
++ checkHost(hostname);
++ InetAddress addr = null;
++ String host = null;
+ try {
+ addr = InetAddress.getByName(hostname);
+ } catch(UnknownHostException e) {
+- this.hostname = hostname;
+- addr = null;
++ host = hostname;
+ }
+- this.port = port;
++ holder = new InetSocketAddressHolder(host, addr, checkPort(port));
++ }
++
++ // private constructor for creating unresolved instances
++ private InetSocketAddress(int port, String hostname) {
++ holder = new InetSocketAddressHolder(hostname, null, port);
+ }
+
+ /**
+@@ -169,31 +251,67 @@ public class InetSocketAddress extends S
+ * @since 1.5
+ */
+ public static InetSocketAddress createUnresolved(String host, int port) {
+- if (port < 0 || port > 0xFFFF) {
+- throw new IllegalArgumentException("port out of range:" + port);
+- }
+- if (host == null) {
+- throw new IllegalArgumentException("hostname can't be null");
+- }
+- InetSocketAddress s = new InetSocketAddress();
+- s.port = port;
+- s.hostname = host;
+- s.addr = null;
+- return s;
++ return new InetSocketAddress(checkPort(port), checkHost(host));
++ }
++
++ /**
++ * @serialField hostname String
++ * @serialField addr InetAddress
++ * @serialField port int
++ */
++ private static final ObjectStreamField[] serialPersistentFields = {
++ new ObjectStreamField("hostname", String.class),
++ new ObjectStreamField("addr", InetAddress.class),
++ new ObjectStreamField("port", int.class)};
++
++ private void writeObject(ObjectOutputStream out)
++ throws IOException
++ {
++ // Don't call defaultWriteObject()
++ ObjectOutputStream.PutField pfields = out.putFields();
++ pfields.put("hostname", holder.hostname);
++ pfields.put("addr", holder.addr);
++ pfields.put("port", holder.port);
++ out.writeFields();
+ }
+
+- private void readObject(ObjectInputStream s)
+- throws IOException, ClassNotFoundException {
+- s.defaultReadObject();
++ private void readObject(ObjectInputStream in)
++ throws IOException, ClassNotFoundException
++ {
++ // Don't call defaultReadObject()
++ ObjectInputStream.GetField oisFields = in.readFields();
++ final String oisHostname = (String)oisFields.get("hostname", null);
++ final InetAddress oisAddr = (InetAddress)oisFields.get("addr", null);
++ final int oisPort = oisFields.get("port", -1);
+
+ // Check that our invariants are satisfied
+- if (port < 0 || port > 0xFFFF) {
+- throw new InvalidObjectException("port out of range:" + port);
+- }
+-
+- if (hostname == null && addr == null) {
++ checkPort(oisPort);
++ if (oisHostname == null && oisAddr == null)
+ throw new InvalidObjectException("hostname and addr " +
+ "can't both be null");
++
++ InetSocketAddressHolder h = new InetSocketAddressHolder(oisHostname,
++ oisAddr,
++ oisPort);
++ UNSAFE.putObject(this, FIELDS_OFFSET, h);
++ }
++
++ private void readObjectNoData()
++ throws ObjectStreamException
++ {
++ throw new InvalidObjectException("Stream data required");
++ }
++
++ private static final long FIELDS_OFFSET;
++ private static final sun.misc.Unsafe UNSAFE;
++ static {
++ try {
++ sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
++ FIELDS_OFFSET = unsafe.objectFieldOffset(
++ InetSocketAddress.class.getDeclaredField("holder"));
++ UNSAFE = unsafe;
++ } catch (NoSuchFieldException e) {
++ throw new Error(e);
+ }
+ }
+
+@@ -203,7 +321,7 @@ public class InetSocketAddress extends S
+ * @return the port number.
+ */
+ public final int getPort() {
+- return port;
++ return holder.getPort();
+ }
+
+ /**
+@@ -213,7 +331,7 @@ public class InetSocketAddress extends S
+ * @return the InetAdress or <code>null</code> if it is unresolved.
+ */
+ public final InetAddress getAddress() {
+- return addr;
++ return holder.getAddress();
+ }
+
+ /**
+@@ -222,11 +340,7 @@ public class InetSocketAddress extends S
+ * @return the hostname part of the address.
+ */
+ public final String getHostName() {
+- if (hostname != null)
+- return hostname;
+- if (addr != null)
+- return addr.getHostName();
+- return null;
++ return holder.getHostName();
+ }
+
+ /**
+@@ -238,15 +352,7 @@ public class InetSocketAddress extends S
+ * @since 1.6
+ */
+ final String getHostString() {
+- if (hostname != null)
+- return hostname;
+- if (addr != null) {
+- if (addr.hostName != null)
+- return addr.hostName;
+- else
+- return addr.getHostAddress();
+- }
+- return null;
++ return holder.getHostString();
+ }
+
+ /**
+@@ -256,7 +362,7 @@ public class InetSocketAddress extends S
+ * an <code>InetAddress</code>.
+ */
+ public final boolean isUnresolved() {
+- return addr == null;
++ return holder.isUnresolved();
+ }
+
+ /**
+@@ -267,12 +373,9 @@ public class InetSocketAddress extends S
+ *
+ * @return a string representation of this object.
+ */
++ @Override
+ public String toString() {
+- if (isUnresolved()) {
+- return hostname + ":" + port;
+- } else {
+- return addr.toString() + ":" + port;
+- }
++ return holder.toString();
+ }
+
+ /**
+@@ -295,16 +398,7 @@ public class InetSocketAddress extends S
+ public final boolean equals(Object obj) {
+ if (obj == null || !(obj instanceof InetSocketAddress))
+ return false;
+- InetSocketAddress sockAddr = (InetSocketAddress) obj;
+- boolean sameIP = false;
+- if (this.addr != null)
+- sameIP = this.addr.equals(sockAddr.addr);
+- else if (this.hostname != null)
+- sameIP = (sockAddr.addr == null) &&
+- this.hostname.equals(sockAddr.hostname);
+- else
+- sameIP = (sockAddr.addr == null) && (sockAddr.hostname == null);
+- return sameIP && (this.port == sockAddr.port);
++ return holder.equals(((InetSocketAddress) obj).holder);
+ }
+
+ /**
+@@ -312,11 +406,8 @@ public class InetSocketAddress extends S
+ *
+ * @return a hash code value for this socket address.
+ */
++ @Override
+ public final int hashCode() {
+- if (addr != null)
+- return addr.hashCode() + port;
+- if (hostname != null)
+- return hostname.hashCode() + port;
+- return port;
++ return holder.hashCode();
+ }
+ }
+diff --git a/src/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
+--- jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
++++ jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
+@@ -239,7 +239,7 @@ class DatagramChannelImpl
+
+ synchronized (writeLock) {
+ ensureOpen();
+- InetSocketAddress isa = (InetSocketAddress)target;
++ InetSocketAddress isa = Net.checkAddress(target);
+ InetAddress ia = isa.getAddress();
+ if (ia == null)
+ throw new IOException("Target address not resolved");
+@@ -250,9 +250,9 @@ class DatagramChannelImpl
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ if (ia.isMulticastAddress()) {
+- sm.checkMulticast(isa.getAddress());
++ sm.checkMulticast(ia);
+ } else {
+- sm.checkConnect(isa.getAddress().getHostAddress(),
++ sm.checkConnect(ia.getHostAddress(),
+ isa.getPort());
+ }
+ }
+@@ -272,7 +272,7 @@ class DatagramChannelImpl
+ return 0;
+ writerThread = NativeThread.current();
+ do {
+- n = send(fd, src, target);
++ n = send(fd, src, isa);
+ } while ((n == IOStatus.INTERRUPTED) && isOpen());
+ return IOStatus.normalize(n);
+ } finally {
+@@ -283,7 +283,7 @@ class DatagramChannelImpl
+ }
+ }
+
+- private int send(FileDescriptor fd, ByteBuffer src, SocketAddress target)
++ private int send(FileDescriptor fd, ByteBuffer src, InetSocketAddress target)
+ throws IOException
+ {
+ if (src instanceof DirectBuffer)
+@@ -315,7 +315,7 @@ class DatagramChannelImpl
+ }
+
+ private int sendFromNativeBuffer(FileDescriptor fd, ByteBuffer bb,
+- SocketAddress target)
++ InetSocketAddress target)
+ throws IOException
+ {
+ int pos = bb.position();
+@@ -324,7 +324,7 @@ class DatagramChannelImpl
+ int rem = (pos <= lim ? lim - pos : 0);
+
+ int written = send0(fd, ((DirectBuffer)bb).address() + pos,
+- rem, target);
++ rem, target.getAddress(), target.getPort());
+ if (written > 0)
+ bb.position(pos + written);
+ return written;
+@@ -703,8 +703,8 @@ class DatagramChannelImpl
+ boolean connected)
+ throws IOException;
+
+- private native int send0(FileDescriptor fd, long address, int len,
+- SocketAddress sa)
++ private native int send0(FileDescriptor fd, long address,
++ int len, InetAddress addr, int port)
+ throws IOException;
+
+ static {
+diff --git a/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c b/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
+--- jdk/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
++++ jdk/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
+@@ -46,8 +46,6 @@
+
+ #include "sun_nio_ch_DatagramChannelImpl.h"
+
+-static jfieldID isa_addrID; /* address in java.net.InetSocketAddress */
+-static jfieldID isa_portID; /* port in java.net.InetSocketAddress */
+ static jfieldID dci_senderID; /* sender in sun.nio.ch.DatagramChannelImpl */
+ static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
+ static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */
+@@ -61,9 +59,6 @@ Java_sun_nio_ch_DatagramChannelImpl_init
+ isa_class = (*env)->NewGlobalRef(env, clazz);
+ isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
+ "(Ljava/net/InetAddress;I)V");
+- isa_addrID = (*env)->GetFieldID(env, clazz, "addr",
+- "Ljava/net/InetAddress;");
+- isa_portID = (*env)->GetFieldID(env, clazz, "port", "I");
+
+ clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
+ dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
+@@ -198,16 +193,15 @@ Java_sun_nio_ch_DatagramChannelImpl_rece
+
+ JNIEXPORT jint JNICALL
+ Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
+- jobject fdo, jlong address,
+- jint len, jobject dest)
++ jobject fdo, jlong address,
++ jint len, jobject destAddress,
++ jint destPort)
+ {
+ jint fd = fdval(env, fdo);
+ void *buf = (void *)jlong_to_ptr(address);
+ SOCKADDR sa;
+ int sa_len = SOCKADDR_LEN;
+ jint n = 0;
+- jobject destAddress = (*env)->GetObjectField(env, dest, isa_addrID);
+- jint destPort = (*env)->GetIntField(env, dest, isa_portID);
+
+ if (len > MAX_PACKET_LEN) {
+ len = MAX_PACKET_LEN;
+diff --git a/src/windows/native/sun/nio/ch/DatagramChannelImpl.c b/src/windows/native/sun/nio/ch/DatagramChannelImpl.c
+--- jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c
++++ jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c
+@@ -34,8 +34,6 @@
+ #include "net_util.h"
+ #include <winsock2.h>
+
+-static jfieldID isa_addrID; /* address in java.net.InetSocketAddress */
+-static jfieldID isa_portID; /* port in java.net.InetSocketAddress */
+ static jfieldID dci_senderID; /* sender in sun.nio.ch.DatagramChannelImpl */
+ static jfieldID dci_senderAddrID; /* sender InetAddress in sun.nio.ch.DatagramChannelImpl */
+ static jfieldID dci_senderPortID; /* sender port in sun.nio.ch.DatagramChannelImpl */
+@@ -87,9 +85,6 @@ Java_sun_nio_ch_DatagramChannelImpl_init
+ isa_class = (*env)->NewGlobalRef(env, clazz);
+ isa_ctorID = (*env)->GetMethodID(env, clazz, "<init>",
+ "(Ljava/net/InetAddress;I)V");
+- isa_addrID = (*env)->GetFieldID(env, clazz, "addr",
+- "Ljava/net/InetAddress;");
+- isa_portID = (*env)->GetFieldID(env, clazz, "port", "I");
+
+ clazz = (*env)->FindClass(env, "sun/nio/ch/DatagramChannelImpl");
+ dci_senderID = (*env)->GetFieldID(env, clazz, "sender",
+@@ -268,17 +263,14 @@ Java_sun_nio_ch_DatagramChannelImpl_rece
+
+ JNIEXPORT jint JNICALL
+ Java_sun_nio_ch_DatagramChannelImpl_send0(JNIEnv *env, jobject this,
+- jobject fdo, jlong address,
+- jint len, jobject dest)
++ jobject fdo, jlong address, jint len,
++ jobject destAddress, jint destPort)
+ {
+ jint fd = fdval(env, fdo);
+ void *buf = (void *)jlong_to_ptr(address);
+ SOCKETADDRESS psa;
+ int sa_len = sizeof(psa);
+ jint rv = 0;
+- jobject destAddress = (*env)->GetObjectField(env, dest, isa_addrID);
+- jint destPort = (*env)->GetIntField(env, dest, isa_portID);
+-
+
+ if (NET_InetAddressToSockaddr(env, destAddress, destPort,
+ (struct sockaddr *)&psa,
+diff --git a/test/java/nio/channels/DatagramChannel/SendToUnresolved.java b/test/java/nio/channels/DatagramChannel/SendToUnresolved.java
+--- jdk/test/java/nio/channels/DatagramChannel/SendToUnresolved.java
++++ jdk/test/java/nio/channels/DatagramChannel/SendToUnresolved.java
+@@ -44,6 +44,8 @@ public class SendToUnresolved {
+ throw new RuntimeException("Expected exception not thrown");
+ } catch (IOException e) {
+ // Correct result
++ } catch (UnresolvedAddressException e) {
++ // Correct result
+ }
+ dc.close();
+ }
diff --git a/java/openjdk6/files/icedtea/security/20130201/8000210.patch b/java/openjdk6/files/icedtea/security/20130201/8000210.patch
new file mode 100644
index 000000000000..28bcddfb2ab6
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/8000210.patch
@@ -0,0 +1,104 @@
+# HG changeset patch
+# User weijun
+# Date 1350962115 -28800
+# Node ID 9c2a2aae44a46e0b63b913987672d1488fa4e7a5
+# Parent 6088f35106866940de257456c8eee21b130d5ff5
+8000210: Improve JarFile code quality
+Reviewed-by: ahgross, xuelei, mschoene
+
+diff --git a/src/share/classes/java/util/jar/JarFile.java b/src/share/classes/java/util/jar/JarFile.java
+--- jdk/src/share/classes/java/util/jar/JarFile.java
++++ jdk/src/share/classes/java/util/jar/JarFile.java
+@@ -32,6 +32,7 @@ import java.security.CodeSigner;
+ import java.security.CodeSigner;
+ import java.security.cert.Certificate;
+ import java.security.AccessController;
++import sun.misc.IOUtils;
+ import sun.security.action.GetPropertyAction;
+ import sun.security.util.ManifestEntryVerifier;
+ import sun.misc.SharedSecrets;
+@@ -326,6 +327,9 @@ class JarFile extends ZipFile {
+ if (names != null) {
+ for (int i = 0; i < names.length; i++) {
+ JarEntry e = getJarEntry(names[i]);
++ if (e == null) {
++ throw new JarException("corrupted jar file");
++ }
+ if (!e.isDirectory()) {
+ if (mev == null) {
+ mev = new ManifestEntryVerifier
+@@ -345,6 +349,10 @@ class JarFile extends ZipFile {
+ // treat the jar file as being unsigned
+ jv = null;
+ verify = false;
++ if (JarVerifier.debug != null) {
++ JarVerifier.debug.println("jarfile parsing error!");
++ ex.printStackTrace();
++ }
+ }
+
+ // if after initializing the verifier we have nothing
+@@ -372,9 +380,8 @@ class JarFile extends ZipFile {
+ * META-INF files.
+ */
+ private byte[] getBytes(ZipEntry ze) throws IOException {
+- byte[] b = new byte[(int)ze.getSize()];
+- DataInputStream is = new DataInputStream(super.getInputStream(ze));
+- is.readFully(b, 0, b.length);
++ InputStream is = super.getInputStream(ze);
++ byte[] b = IOUtils.readFully(is, (int)ze.getSize(), true);
+ is.close();
+ return b;
+ }
+@@ -476,12 +483,7 @@ class JarFile extends ZipFile {
+ if (!isKnownToNotHaveClassPathAttribute()) {
+ JarEntry manEntry = getManEntry();
+ if (manEntry != null) {
+- byte[] b = new byte[(int)manEntry.getSize()];
+- DataInputStream dis = new DataInputStream(
+- super.getInputStream(manEntry));
+- dis.readFully(b, 0, b.length);
+- dis.close();
+-
++ byte[] b = getBytes(manEntry);
+ int last = b.length - src.length;
+ int i = 0;
+ next:
+diff --git a/src/share/classes/sun/security/util/DerIndefLenConverter.java b/src/share/classes/sun/security/util/DerIndefLenConverter.java
+--- jdk/src/share/classes/sun/security/util/DerIndefLenConverter.java
++++ jdk/src/share/classes/sun/security/util/DerIndefLenConverter.java
+@@ -50,6 +50,7 @@ class DerIndefLenConverter {
+
+ private byte[] data, newData;
+ private int newDataPos, dataPos, dataSize, index;
++ private int unresolved = 0;
+
+ private ArrayList<Object> ndefsList = new ArrayList<Object>();
+
+@@ -113,6 +114,7 @@ class DerIndefLenConverter {
+ numOfEncapsulatedLenBytes;
+ byte[] sectionLenBytes = getLengthBytes(sectionLen);
+ ndefsList.set(index, sectionLenBytes);
++ unresolved--;
+
+ // Add the number of bytes required to represent this section
+ // to the total number of length bytes,
+@@ -149,6 +151,7 @@ class DerIndefLenConverter {
+ int lenByte = data[dataPos++] & 0xff;
+ if (isIndefinite(lenByte)) {
+ ndefsList.add(new Integer(dataPos));
++ unresolved++;
+ return curLen;
+ }
+ if (isLongForm(lenByte)) {
+@@ -316,6 +319,10 @@ class DerIndefLenConverter {
+ parseValue(len);
+ }
+
++ if (unresolved != 0) {
++ throw new IOException("not all indef len BER resolved");
++ }
++
+ newData = new byte[dataSize + numOfTotalLenBytes];
+ dataPos=0; newDataPos=0; index=0;
+
diff --git a/java/openjdk6/files/icedtea/security/20130201/8000537.patch b/java/openjdk6/files/icedtea/security/20130201/8000537.patch
new file mode 100644
index 000000000000..8e7bb54a4644
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/8000537.patch
@@ -0,0 +1,334 @@
+# HG changeset patch
+# User ewendeli
+# Date 1353844618 -3600
+# Node ID 21415f01c66add2891500f10e41c7e99b2b10447
+# Parent 787e9230b414f346f9c318918aaf58b872b9912e
+8000537: Contextualize RequiredModelMBean class
+Reviewed-by: jbachorik
+Contributed-by: Andreas Eriksson <andreas.eriksson@oracle.com>
+
+diff --git a/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java b/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java
+--- jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java
++++ jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -39,6 +39,9 @@ import java.lang.reflect.InvocationTarge
+ import java.lang.reflect.InvocationTargetException;
+
+ import java.lang.reflect.Method;
++import java.security.AccessControlContext;
++import java.security.AccessController;
++import java.security.PrivilegedAction;
+
+ import java.util.Date;
+ import java.util.HashMap;
+@@ -77,6 +80,8 @@ import javax.management.RuntimeOperation
+ import javax.management.RuntimeOperationsException;
+ import javax.management.ServiceNotFoundException;
+ import javax.management.loading.ClassLoaderRepository;
++import sun.misc.JavaSecurityAccess;
++import sun.misc.SharedSecrets;
+
+ import sun.reflect.misc.MethodUtil;
+ import sun.reflect.misc.ReflectUtil;
+@@ -138,6 +143,9 @@ public class RequiredModelMBean
+ private boolean registered = false;
+ private transient MBeanServer server = null;
+
++ private final static JavaSecurityAccess javaSecurityAccess = SharedSecrets.getJavaSecurityAccess();
++ final private AccessControlContext acc = AccessController.getContext();
++
+ /*************************************/
+ /* constructors */
+ /*************************************/
+@@ -1025,10 +1033,30 @@ public class RequiredModelMBean
+
+ if (opClassName != null) {
+ try {
+- final ClassLoader targetClassLoader =
+- targetObject.getClass().getClassLoader();
+- targetClass = Class.forName(opClassName, false,
+- targetClassLoader);
++ AccessControlContext stack = AccessController.getContext();
++ final Object obj = targetObject;
++ final String className = opClassName;
++ final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
++
++ targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
++
++ public Class<?> run() {
++ try {
++ ReflectUtil.checkPackageAccess(className);
++ final ClassLoader targetClassLoader =
++ obj.getClass().getClassLoader();
++ return Class.forName(className, false,
++ targetClassLoader);
++ } catch (ClassNotFoundException e) {
++ caughtException[0] = e;
++ }
++ return null;
++ }
++ }, stack, acc);
++
++ if (caughtException[0] != null) {
++ throw caughtException[0];
++ }
+ } catch (ClassNotFoundException e) {
+ final String msg =
+ "class for invoke " + opName + " not found";
+@@ -1061,9 +1090,9 @@ public class RequiredModelMBean
+ return result;
+ }
+
+- private static Method resolveMethod(Class<?> targetClass,
++ private Method resolveMethod(Class<?> targetClass,
+ String opMethodName,
+- String[] sig)
++ final String[] sig)
+ throws ReflectionException {
+ final boolean tracing = MODELMBEAN_LOGGER.isLoggable(Level.FINER);
+
+@@ -1078,30 +1107,44 @@ public class RequiredModelMBean
+ if (sig == null)
+ argClasses = null;
+ else {
++ final AccessControlContext stack = AccessController.getContext();
++ final ReflectionException[] caughtException = new ReflectionException[1];
+ final ClassLoader targetClassLoader = targetClass.getClassLoader();
+- argClasses = new Class[sig.length];
+- for (int i = 0; i < sig.length; i++) {
+- if (tracing) {
+- MODELMBEAN_LOGGER.logp(Level.FINER,
+- RequiredModelMBean.class.getName(),"resolveMethod",
+- "resolve type " + sig[i]);
+- }
+- argClasses[i] = (Class) primitiveClassMap.get(sig[i]);
+- if (argClasses[i] == null) {
+- try {
+- argClasses[i] =
+- Class.forName(sig[i], false, targetClassLoader);
+- } catch (ClassNotFoundException e) {
++ argClasses = new Class<?>[sig.length];
++
++ javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Void>() {
++
++ public Void run() {
++ for (int i = 0; i < sig.length; i++) {
+ if (tracing) {
+ MODELMBEAN_LOGGER.logp(Level.FINER,
+- RequiredModelMBean.class.getName(),
+- "resolveMethod",
+- "class not found");
++ RequiredModelMBean.class.getName(),"resolveMethod",
++ "resolve type " + sig[i]);
+ }
+- final String msg = "Parameter class not found";
+- throw new ReflectionException(e, msg);
++ argClasses[i] = (Class<?>) primitiveClassMap.get(sig[i]);
++ if (argClasses[i] == null) {
++ try {
++ ReflectUtil.checkPackageAccess(sig[i]);
++ argClasses[i] =
++ Class.forName(sig[i], false, targetClassLoader);
++ } catch (ClassNotFoundException e) {
++ if (tracing) {
++ MODELMBEAN_LOGGER.logp(Level.FINER,
++ RequiredModelMBean.class.getName(),
++ "resolveMethod",
++ "class not found");
++ }
++ final String msg = "Parameter class not found";
++ caughtException[0] = new ReflectionException(e, msg);
++ }
++ }
+ }
++ return null;
+ }
++ }, stack, acc);
++
++ if (caughtException[0] != null) {
++ throw caughtException[0];
+ }
+ }
+
+@@ -1133,7 +1177,7 @@ public class RequiredModelMBean
+ /* Find a method in RequiredModelMBean as determined by the given
+ parameters. Return null if there is none, or if the parameters
+ exclude using it. Called from invoke. */
+- private static Method findRMMBMethod(String opMethodName,
++ private Method findRMMBMethod(String opMethodName,
+ Object targetObjectField,
+ String opClassName,
+ String[] sig) {
+@@ -1155,19 +1199,28 @@ public class RequiredModelMBean
+ if (opClassName == null)
+ targetClass = rmmbClass;
+ else {
+- try {
+- final ClassLoader targetClassLoader =
+- rmmbClass.getClassLoader();
+- targetClass = Class.forName(opClassName, false,
+- targetClassLoader);
+- if (!rmmbClass.isAssignableFrom(targetClass))
+- return null;
+- } catch (ClassNotFoundException e) {
+- return null;
+- }
++ AccessControlContext stack = AccessController.getContext();
++ final String className = opClassName;
++ targetClass = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
++
++ public Class<?> run() {
++ try {
++ ReflectUtil.checkPackageAccess(className);
++ final ClassLoader targetClassLoader =
++ rmmbClass.getClassLoader();
++ Class clz = Class.forName(className, false,
++ targetClassLoader);
++ if (!rmmbClass.isAssignableFrom(clz))
++ return null;
++ return clz;
++ } catch (ClassNotFoundException e) {
++ return null;
++ }
++ }
++ }, stack, acc);
+ }
+ try {
+- return resolveMethod(targetClass, opMethodName, sig);
++ return targetClass != null ? resolveMethod(targetClass, opMethodName, sig) : null;
+ } catch (ReflectionException e) {
+ return null;
+ }
+@@ -1177,12 +1231,34 @@ public class RequiredModelMBean
+ * Invoke the given method, and throw the somewhat unpredictable
+ * appropriate exception if the method itself gets an exception.
+ */
+- private Object invokeMethod(String opName, Method method,
+- Object targetObject, Object[] opArgs)
++ private Object invokeMethod(String opName, final Method method,
++ final Object targetObject, final Object[] opArgs)
+ throws MBeanException, ReflectionException {
+ try {
+- ReflectUtil.checkPackageAccess(method.getDeclaringClass());
+- return MethodUtil.invoke(method, targetObject, opArgs);
++ final Throwable[] caughtException = new Throwable[1];
++ AccessControlContext stack = AccessController.getContext();
++ Object rslt = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Object>() {
++
++ public Object run() {
++ try {
++ ReflectUtil.checkPackageAccess(method.getDeclaringClass());
++ return MethodUtil.invoke(method, targetObject, opArgs);
++ } catch (InvocationTargetException e) {
++ caughtException[0] = e;
++ } catch (IllegalAccessException e) {
++ caughtException[0] = e;
++ }
++ return null;
++ }
++ }, stack, acc);
++ if (caughtException[0] != null) {
++ if (caughtException[0] instanceof Exception) {
++ throw (Exception)caughtException[0];
++ } else if(caughtException[0] instanceof Error) {
++ throw (Error)caughtException[0];
++ }
++ }
++ return rslt;
+ } catch (RuntimeErrorException ree) {
+ throw new RuntimeOperationsException(ree,
+ "RuntimeException occurred in RequiredModelMBean "+
+@@ -1569,7 +1646,7 @@ public class RequiredModelMBean
+ }
+
+ // make sure response class matches type field
+- String respType = attrInfo.getType();
++ final String respType = attrInfo.getType();
+ if (response != null) {
+ String responseClass = response.getClass().getName();
+ if (!respType.equals(responseClass)) {
+@@ -1592,9 +1669,30 @@ public class RequiredModelMBean
+ // inequality may come from type subclassing
+ boolean subtype;
+ try {
+- ClassLoader cl =
+- response.getClass().getClassLoader();
+- Class c = Class.forName(respType, true, cl);
++ final Class respClass = response.getClass();
++ final Exception[] caughException = new Exception[1];
++
++ AccessControlContext stack = AccessController.getContext();
++
++ Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
++
++ public Class<?> run() {
++ try {
++ ReflectUtil.checkPackageAccess(respType);
++ ClassLoader cl =
++ respClass.getClassLoader();
++ return Class.forName(respType, true, cl);
++ } catch (Exception e) {
++ caughException[0] = e;
++ }
++ return null;
++ }
++ }, stack, acc);
++
++ if (caughException[0] != null) {
++ throw caughException[0];
++ }
++
+ subtype = c.isInstance(response);
+ } catch (Exception e) {
+ subtype = false;
+@@ -2748,16 +2847,36 @@ public class RequiredModelMBean
+ return MBeanServerFactory.getClassLoaderRepository(server);
+ }
+
+- private Class loadClass(String className)
++ private Class<?> loadClass(final String className)
+ throws ClassNotFoundException {
+- try {
+- return Class.forName(className);
+- } catch (ClassNotFoundException e) {
+- final ClassLoaderRepository clr =
+- getClassLoaderRepository();
+- if (clr == null) throw new ClassNotFoundException(className);
+- return clr.loadClass(className);
++ AccessControlContext stack = AccessController.getContext();
++ final ClassNotFoundException[] caughtException = new ClassNotFoundException[1];
++
++ Class c = javaSecurityAccess.doIntersectionPrivilege(new PrivilegedAction<Class<?>>() {
++
++ public Class<?> run() {
++ try {
++ ReflectUtil.checkPackageAccess(className);
++ return Class.forName(className);
++ } catch (ClassNotFoundException e) {
++ final ClassLoaderRepository clr =
++ getClassLoaderRepository();
++ try {
++ if (clr == null) throw new ClassNotFoundException(className);
++ return clr.loadClass(className);
++ } catch (ClassNotFoundException ex) {
++ caughtException[0] = ex;
++ }
++ }
++ return null;
++ }
++ }, stack, acc);
++
++ if (caughtException[0] != null) {
++ throw caughtException[0];
+ }
++
++ return c;
+ }
+
+
diff --git a/java/openjdk6/files/icedtea/security/20130201/8000540.patch b/java/openjdk6/files/icedtea/security/20130201/8000540.patch
new file mode 100644
index 000000000000..4b0495c400f4
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/8000540.patch
@@ -0,0 +1,187 @@
+# HG changeset patch
+# User ngmr
+# Date 1354993606 0
+# Node ID 42b1142b39b5a511e1e07b5877cc55e93767064e
+# Parent c5203e9e0e07559914a9c46dbba4fe85df945624
+8000540: Improve IIOP type reuse management
+Reviewed-by: alanb, ahgross, coffeys
+
+diff --git a/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java b/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
+--- corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
++++ corba/src/share/classes/com/sun/corba/se/impl/io/ObjectStreamClass.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -25,7 +25,7 @@
+ /*
+ * Licensed Materials - Property of IBM
+ * RMI-IIOP v1.0
+- * Copyright IBM Corp. 1998 1999 All Rights Reserved
++ * Copyright IBM Corp. 1998 2012 All Rights Reserved
+ *
+ */
+
+@@ -56,7 +56,8 @@ import java.io.Serializable;
+
+ import java.util.Arrays;
+ import java.util.Comparator;
+-import java.util.Hashtable;
++import java.util.concurrent.ConcurrentHashMap;
++import java.util.concurrent.ConcurrentMap;
+
+ import com.sun.corba.se.impl.util.RepositoryId;
+
+@@ -82,8 +83,6 @@ public class ObjectStreamClass implement
+
+ private static Object noArgsList[] = {};
+ private static Class noTypesList[] = {};
+-
+- private static Hashtable translatedFields;
+
+ private static final Bridge bridge =
+ (Bridge)AccessController.doPrivileged(
+@@ -380,6 +379,58 @@ public class ObjectStreamClass implement
+ */
+ }
+
++ private static final class PersistentFieldsValue {
++ private final ConcurrentMap map = new ConcurrentHashMap();
++ private static final Object NULL_VALUE =
++ (PersistentFieldsValue.class.getName() + ".NULL_VALUE");
++
++ PersistentFieldsValue() { }
++
++ ObjectStreamField[] get(Class type) {
++ Object value = map.get(type);
++ if (value == null) {
++ value = computeValue(type);
++ Object oldValue = map.putIfAbsent(type, value);
++ if (oldValue != null) {
++ value = oldValue;
++ }
++ }
++ return ((value == NULL_VALUE) ? null : (ObjectStreamField[])value);
++ }
++
++ private static Object computeValue(Class<?> type) {
++ try {
++ Field pf = type.getDeclaredField("serialPersistentFields");
++ int mods = pf.getModifiers();
++ if (Modifier.isPrivate(mods) && Modifier.isStatic(mods) &&
++ Modifier.isFinal(mods)) {
++ pf.setAccessible(true);
++ java.io.ObjectStreamField[] fields =
++ (java.io.ObjectStreamField[])pf.get(type);
++ return translateFields(fields);
++ }
++ } catch (NoSuchFieldException e1) {
++ } catch (IllegalAccessException e2) {
++ } catch (IllegalArgumentException e3) {
++ } catch (ClassCastException e4) { }
++ return NULL_VALUE;
++ }
++
++ private static ObjectStreamField[] translateFields(
++ java.io.ObjectStreamField[] fields) {
++ ObjectStreamField[] translation =
++ new ObjectStreamField[fields.length];
++ for (int i = 0; i < fields.length; i++) {
++ translation[i] = new ObjectStreamField(fields[i].getName(),
++ fields[i].getType());
++ }
++ return translation;
++ }
++ }
++
++ private static final PersistentFieldsValue persistentFieldsValue =
++ new PersistentFieldsValue();
++
+ /*
+ * Initialize class descriptor. This method is only invoked on class
+ * descriptors created via calls to lookupInternal(). This method is kept
+@@ -412,35 +463,7 @@ public class ObjectStreamClass implement
+ * If it is declared, use the declared serialPersistentFields.
+ * Otherwise, extract the fields from the class itself.
+ */
+- try {
+- Field pf = cl.getDeclaredField("serialPersistentFields");
+- // serial bug 7; the serialPersistentFields were not
+- // being read and stored as Accessible bit was not set
+- pf.setAccessible(true);
+- // serial bug 7; need to find if the field is of type
+- // java.io.ObjectStreamField
+- java.io.ObjectStreamField[] f =
+- (java.io.ObjectStreamField[])pf.get(cl);
+- int mods = pf.getModifiers();
+- if ((Modifier.isPrivate(mods)) &&
+- (Modifier.isStatic(mods)) &&
+- (Modifier.isFinal(mods)))
+- {
+- fields = (ObjectStreamField[])translateFields((Object[])pf.get(cl));
+- }
+- } catch (NoSuchFieldException e) {
+- fields = null;
+- } catch (IllegalAccessException e) {
+- fields = null;
+- } catch (IllegalArgumentException e) {
+- fields = null;
+- } catch (ClassCastException e) {
+- /* Thrown if a field serialPersistentField exists
+- * but it is not of type ObjectStreamField.
+- */
+- fields = null;
+- }
+-
++ fields = persistentFieldsValue.get(cl);
+
+ if (fields == null) {
+ /* Get all of the declared fields for this
+@@ -635,44 +658,6 @@ public class ObjectStreamClass implement
+ name = n;
+ suid = s;
+ superclass = null;
+- }
+-
+- private static Object[] translateFields(Object objs[])
+- throws NoSuchFieldException {
+- try{
+- java.io.ObjectStreamField fields[] = (java.io.ObjectStreamField[])objs;
+- Object translation[] = null;
+-
+- if (translatedFields == null)
+- translatedFields = new Hashtable();
+-
+- translation = (Object[])translatedFields.get(fields);
+-
+- if (translation != null)
+- return translation;
+- else {
+- Class osfClass = Class.forName("com.sun.corba.se.impl.io.ObjectStreamField");
+- translation = (Object[])java.lang.reflect.Array.newInstance(osfClass, objs.length);
+- Object arg[] = new Object[2];
+- Class types[] = {String.class, Class.class};
+- Constructor constructor = osfClass.getDeclaredConstructor(types);
+- for (int i = fields.length -1; i >= 0; i--){
+- arg[0] = fields[i].getName();
+- arg[1] = fields[i].getType();
+-
+- translation[i] = constructor.newInstance(arg);
+- }
+- translatedFields.put(fields, translation);
+-
+- }
+-
+- return (Object[])translation;
+- }
+- catch(Throwable t){
+- NoSuchFieldException nsfe = new NoSuchFieldException();
+- nsfe.initCause( t ) ;
+- throw nsfe ;
+- }
+ }
+
+ /*
diff --git a/java/openjdk6/files/icedtea/security/20130201/8000631.patch b/java/openjdk6/files/icedtea/security/20130201/8000631.patch
new file mode 100644
index 000000000000..bdf6781e30a5
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/8000631.patch
@@ -0,0 +1,3964 @@
+# HG changeset patch
+# User coffeys
+# Date 1354992561 0
+# Node ID c5203e9e0e07559914a9c46dbba4fe85df945624
+# Parent 7f904eacf818c104549b94b957f34896a8548d9b
+8000631: Restrict access to class constructor
+Reviewed-by: alanb, ahgross
+
+diff --git a/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk b/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk
+--- corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk
++++ corba/make/com/sun/corba/minclude/com_sun_corba_se_impl_orbutil.jmk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
++# Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ #
+ # This code is free software; you can redistribute it and/or modify it
+@@ -29,10 +29,6 @@ com_sun_corba_se_impl_orbutil_java = \
+ com/sun/corba/se/impl/orbutil/DenseIntMapImpl.java \
+ com/sun/corba/se/impl/orbutil/GetPropertyAction.java \
+ com/sun/corba/se/impl/orbutil/HexOutputStream.java \
+- com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3.java \
+- com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3_1.java \
+- com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3.java \
+- com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3_1.java \
+ com/sun/corba/se/impl/orbutil/LegacyHookGetFields.java \
+ com/sun/corba/se/impl/orbutil/LegacyHookPutFields.java \
+ com/sun/corba/se/impl/orbutil/LogKeywords.java \
+@@ -45,19 +41,11 @@ com_sun_corba_se_impl_orbutil_java = \
+ com/sun/corba/se/impl/orbutil/ORBUtility.java \
+ com/sun/corba/se/impl/orbutil/ORBClassLoader.java \
+ com/sun/corba/se/impl/orbutil/RepIdDelegator.java \
+- com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3.java \
+- com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3_1.java \
+- com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3.java \
+- com/sun/corba/se/impl/orbutil/RepositoryId_1_3.java \
+ com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java \
+ com/sun/corba/se/impl/orbutil/RepositoryIdStrings.java \
+ com/sun/corba/se/impl/orbutil/RepositoryIdUtility.java \
+ com/sun/corba/se/impl/orbutil/RepositoryIdInterface.java \
+- com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3_1.java \
+- com/sun/corba/se/impl/orbutil/RepositoryId_1_3_1.java \
+ com/sun/corba/se/impl/orbutil/StackImpl.java \
+- com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3_1.java \
+- com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3.java \
+ com/sun/corba/se/impl/orbutil/closure/Future.java \
+ com/sun/corba/se/impl/orbutil/closure/Constant.java \
+ com/sun/corba/se/impl/orbutil/concurrent/Sync.java \
+diff --git a/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java b/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java
+--- corba/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java
++++ corba/src/share/classes/com/sun/corba/se/impl/corba/AnyImpl.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -1218,7 +1218,7 @@ public class AnyImpl extends Any
+ // See bug 4391648 for more info about the tcORB in this
+ // case.
+ RepositoryIdStrings repStrs
+- = RepositoryIdFactory.getRepIdStringsFactory(tcORB);
++ = RepositoryIdFactory.getRepIdStringsFactory();
+
+
+ // Assertion: c instanceof Serializable?
+@@ -1251,7 +1251,7 @@ public class AnyImpl extends Any
+ // Anything else
+ // We know that this is a TypeCodeImpl since it is our ORB
+ classTC = (TypeCodeImpl)ValueUtility.createTypeCodeForClass(
+- tcORB, c, ORBUtility.createValueHandler(tcORB));
++ tcORB, c, ORBUtility.createValueHandler());
+ // Intruct classTC to store its buffer
+ classTC.setCaching(true);
+ // Update the cache
+diff --git a/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java b/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java
+--- corba/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java
++++ corba/src/share/classes/com/sun/corba/se/impl/encoding/CDRInputStream_1_0.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -269,8 +269,8 @@ public class CDRInputStream_1_0 extends
+
+ private final void createRepositoryIdHandlers()
+ {
+- repIdUtil = RepositoryIdFactory.getRepIdUtility(orb);
+- repIdStrs = RepositoryIdFactory.getRepIdStringsFactory(orb);
++ repIdUtil = RepositoryIdFactory.getRepIdUtility();
++ repIdStrs = RepositoryIdFactory.getRepIdStringsFactory();
+ }
+
+ public GIOPVersion getGIOPVersion() {
+@@ -564,10 +564,7 @@ public class CDRInputStream_1_0 extends
+
+ checkForNegativeLength(len);
+
+- if (orb != null && ORBUtility.isLegacyORB((ORB)orb))
+- return legacyReadString(len);
+- else
+- return internalReadString(len);
++ return internalReadString(len);
+ }
+
+ private final String internalReadString(int len) {
+@@ -586,54 +583,6 @@ public class CDRInputStream_1_0 extends
+ read_octet();
+
+ return new String(result, 0, getCharConverter().getNumChars());
+- }
+-
+- private final String legacyReadString(int len) {
+-
+- //
+- // Workaround for ORBs which send string lengths of
+- // zero to mean empty string.
+- //
+- //
+- // IMPORTANT: Do not replace 'new String("")' with "", it may result
+- // in a Serialization bug (See serialization.zerolengthstring) and
+- // bug id: 4728756 for details
+- if (len == 0)
+- return new String("");
+-
+- len--;
+- char[] c = new char[len];
+-
+- int n = 0;
+- while (n < len) {
+- int avail;
+- int bytes;
+- int wanted;
+-
+- avail = bbwi.buflen - bbwi.position();
+- if (avail <= 0) {
+- grow(1, 1);
+- avail = bbwi.buflen - bbwi.position();
+- }
+- wanted = len - n;
+- bytes = (wanted < avail) ? wanted : avail;
+- // Microbenchmarks are showing a loop of ByteBuffer.get(int) being
+- // faster than ByteBuffer.get(byte[], int, int).
+- for (int i=0; i<bytes; i++) {
+- c[n+i] = (char) (bbwi.byteBuffer.get(bbwi.position()+i) & 0xFF);
+- }
+- bbwi.position(bbwi.position() + bytes);
+- n += bytes;
+- }
+-
+- //
+- // Skip past terminating null byte
+- //
+- if (bbwi.position() + 1 > bbwi.buflen)
+- alignAndCheck(1, 1);
+- bbwi.position(bbwi.position() + 1);
+-
+- return new String(c);
+ }
+
+ public final String read_string() {
+@@ -1045,7 +994,7 @@ public class CDRInputStream_1_0 extends
+
+ try {
+ if (valueHandler == null)
+- valueHandler = ORBUtility.createValueHandler(orb);
++ valueHandler = ORBUtility.createValueHandler();
+
+ value = valueHandler.readValue(parent,
+ indirection,
+diff --git a/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream_1_0.java b/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream_1_0.java
+--- corba/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream_1_0.java
++++ corba/src/share/classes/com/sun/corba/se/impl/encoding/CDROutputStream_1_0.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -189,18 +189,8 @@ public class CDROutputStream_1_0 extends
+
+ private final void createRepositoryIdHandlers()
+ {
+- if (orb != null) {
+- // Get the appropriate versions based on the ORB version. The
+- // ORB versioning info is only in the core ORB.
+- repIdUtil
+- = RepositoryIdFactory.getRepIdUtility(orb);
+- repIdStrs
+- = RepositoryIdFactory.getRepIdStringsFactory(orb);
+- } else {
+- // Get the latest versions
+- repIdUtil = RepositoryIdFactory.getRepIdUtility();
+- repIdStrs = RepositoryIdFactory.getRepIdStringsFactory();
+- }
++ repIdUtil = RepositoryIdFactory.getRepIdUtility();
++ repIdStrs = RepositoryIdFactory.getRepIdStringsFactory();
+ }
+
+ public BufferManagerWrite getBufferManager()
+@@ -705,7 +695,7 @@ public class CDROutputStream_1_0 extends
+ private void writeArray(Serializable array, Class clazz) {
+
+ if (valueHandler == null)
+- valueHandler = ORBUtility.createValueHandler(orb); //d11638
++ valueHandler = ORBUtility.createValueHandler(); //d11638
+
+ // Write value_tag
+ int indirection = writeValueTag(mustChunk, true,
+@@ -768,7 +758,7 @@ public class CDROutputStream_1_0 extends
+
+ private void writeRMIIIOPValueType(Serializable object, Class clazz) {
+ if (valueHandler == null)
+- valueHandler = ORBUtility.createValueHandler(orb); //d11638
++ valueHandler = ORBUtility.createValueHandler(); //d11638
+
+ Serializable key = object;
+
+diff --git a/src/share/classes/com/sun/corba/se/impl/io/FVDCodeBaseImpl.java b/src/share/classes/com/sun/corba/se/impl/io/FVDCodeBaseImpl.java
+--- corba/src/share/classes/com/sun/corba/se/impl/io/FVDCodeBaseImpl.java
++++ corba/src/share/classes/com/sun/corba/se/impl/io/FVDCodeBaseImpl.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -86,7 +86,7 @@ public class FVDCodeBaseImpl extends _Co
+ // default to using the current ORB version in case the
+ // vhandler is not set
+ if (vhandler == null) {
+- vhandler = new ValueHandlerImpl(false);
++ vhandler = ValueHandlerImpl.getInstance(false);
+ }
+
+ // Util.getCodebase may return null which would
+@@ -120,7 +120,7 @@ public class FVDCodeBaseImpl extends _Co
+ // default to using the current ORB version in case the
+ // vhandler is not set
+ if (vhandler == null) {
+- vhandler = new ValueHandlerImpl(false);
++ vhandler = ValueHandlerImpl.getInstance(false);
+ }
+
+ try{
+@@ -161,7 +161,7 @@ public class FVDCodeBaseImpl extends _Co
+ // default to using the current ORB version in case the
+ // vhandler is not set
+ if (vhandler == null) {
+- vhandler = new ValueHandlerImpl(false);
++ vhandler = ValueHandlerImpl.getInstance(false);
+ }
+
+ Stack repIds = new Stack();
+diff --git a/src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java b/src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java
+--- corba/src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java
++++ corba/src/share/classes/com/sun/corba/se/impl/io/ValueHandlerImpl.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -53,7 +53,7 @@ import com.sun.corba.se.impl.logging.OMG
+ import com.sun.corba.se.impl.logging.OMGSystemException;
+ import com.sun.corba.se.impl.logging.UtilSystemException;
+
+-public class ValueHandlerImpl implements javax.rmi.CORBA.ValueHandlerMultiFormat {
++public final class ValueHandlerImpl implements javax.rmi.CORBA.ValueHandlerMultiFormat {
+
+ // Property to override our maximum stream format version
+ public static final String FORMAT_VERSION_PROPERTY
+@@ -150,12 +150,20 @@ public class ValueHandlerImpl implements
+ writeValueWithVersion(out, value, streamFormatVersion);
+ }
+
+- public ValueHandlerImpl(){}
++ private ValueHandlerImpl(){}
+
+- public ValueHandlerImpl(boolean isInputStream) {
++ private ValueHandlerImpl(boolean isInputStream) {
+ this();
+ useHashtables = false;
+ this.isInputStream = isInputStream;
++ }
++
++ static ValueHandlerImpl getInstance() {
++ return new ValueHandlerImpl();
++ }
++
++ static ValueHandlerImpl getInstance(boolean isInputStream) {
++ return new ValueHandlerImpl(isInputStream);
+ }
+
+ /**
+@@ -458,12 +466,7 @@ public class ValueHandlerImpl implements
+ return ObjectStreamClass.lookup(value.getClass()).writeReplace(value);
+ }
+
+- /**
+- * Encapsulates writing of Java char arrays so that the 1.3 subclass
+- * can override it without exposing internals across packages. This
+- * is a fix for bug 4367783.
+- */
+- protected void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream out,
++ private void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream out,
+ char[] array,
+ int offset,
+ int length)
+@@ -576,12 +579,7 @@ public class ValueHandlerImpl implements
+ }
+ }
+
+- /**
+- * Encapsulates reading of Java char arrays so that the 1.3 subclass
+- * can override it without exposing internals across packages. This
+- * is a fix for bug 4367783.
+- */
+- protected void readCharArray(org.omg.CORBA_2_3.portable.InputStream in,
++ private void readCharArray(org.omg.CORBA_2_3.portable.InputStream in,
+ char[] array,
+ int offset,
+ int length)
+@@ -795,7 +793,7 @@ public class ValueHandlerImpl implements
+ return RepositoryId.cache.getId(repId).isSequence();
+ }
+
+- protected String getOutputStreamClassName() {
++ private String getOutputStreamClassName() {
+ return "com.sun.corba.se.impl.io.IIOPOutputStream";
+ }
+
+@@ -843,29 +841,11 @@ public class ValueHandlerImpl implements
+ private IIOPOutputStream createOutputStreamBuiltInNoPriv(
+ final String name
+ ) throws IOException {
+- return
+- name.equals(
+- IIOPOutputStream
+- .class.getName()
+- ) ?
+- new IIOPOutputStream() :
+-
+- name.equals(
+- com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3
+- .class.getName()
+- ) ?
+- new com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3() :
+-
+- name.equals(
+- com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1
+- .class.getName()
+- ) ?
+- new com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1() :
+-
+- null;
++ return name.equals(IIOPOutputStream.class.getName()) ?
++ new IIOPOutputStream() : null;
+ }
+
+- protected String getInputStreamClassName() {
++ private String getInputStreamClassName() {
+ return "com.sun.corba.se.impl.io.IIOPInputStream";
+ }
+
+@@ -913,26 +893,8 @@ public class ValueHandlerImpl implements
+ private IIOPInputStream createInputStreamBuiltInNoPriv(
+ final String name
+ ) throws IOException {
+- return
+- name.equals(
+- IIOPInputStream
+- .class.getName()
+- ) ?
+- new IIOPInputStream() :
+-
+- name.equals(
+- com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3
+- .class.getName()
+- ) ?
+- new com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3() :
+-
+- name.equals(
+- com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1
+- .class.getName()
+- ) ?
+- new com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1() :
+-
+- null;
++ return name.equals(IIOPInputStream.class.getName()) ?
++ new IIOPInputStream() : null;
+ }
+
+ /**
+@@ -958,12 +920,7 @@ public class ValueHandlerImpl implements
+
+ }
+
+- /**
+- * Our JDK 1.3 and JDK 1.3.1 behavior subclasses override this.
+- * The correct behavior is for a Java char to map to a CORBA wchar,
+- * but our older code mapped it to a CORBA char.
+- */
+- protected TCKind getJavaCharTCKind() {
++ TCKind getJavaCharTCKind() {
+ return TCKind.tk_wchar;
+ }
+ }
+diff --git a/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java b/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java
+--- corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java
++++ corba/src/share/classes/com/sun/corba/se/impl/io/ValueUtility.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -92,6 +92,14 @@ public class ValueUtility {
+ null, // tk_native 31
+ null, // tk_abstract_interface 32
+ };
++
++ static {
++ sun.corba.SharedSecrets.setJavaCorbaAccess(new sun.corba.JavaCorbaAccess() {
++ public ValueHandlerImpl newValueHandlerImpl() {
++ return ValueHandlerImpl.getInstance();
++ }
++ });
++ }
+
+ public static String getSignature(ValueMember member)
+ throws ClassNotFoundException {
+diff --git a/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java b/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java
+--- corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java
++++ corba/src/share/classes/com/sun/corba/se/impl/javax/rmi/CORBA/Util.java
+@@ -112,6 +112,9 @@ import com.sun.corba.se.impl.orbutil.ORB
+ import com.sun.corba.se.impl.orbutil.ORBClassLoader;
+ import com.sun.corba.se.impl.logging.UtilSystemException;
+ import com.sun.corba.se.spi.logging.CORBALogDomains;
++import sun.corba.SharedSecrets;
++import sun.corba.JavaCorbaAccess;
++
+
+ /**
+ * Provides utility methods that can be used by stubs and ties to
+@@ -125,7 +128,8 @@ public class Util implements javax.rmi.C
+ // Maps targets to ties.
+ private static IdentityHashtable exportedServants = new IdentityHashtable();
+
+- private static ValueHandlerImpl valueHandlerSingleton = new ValueHandlerImpl();
++ private static final ValueHandlerImpl valueHandlerSingleton =
++ SharedSecrets.getJavaCorbaAccess().newValueHandlerImpl();
+
+ private UtilSystemException utilWrapper = UtilSystemException.get(
+ CORBALogDomains.RPC_ENCODING);
+diff --git a/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java b/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
+--- corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
++++ corba/src/share/classes/com/sun/corba/se/impl/orb/ORBImpl.java
+@@ -848,7 +848,7 @@ public class ORBImpl extends com.sun.cor
+ // backward compatability 4365188
+ CodeBase cb;
+
+- ValueHandler vh = ORBUtility.createValueHandler(this);
++ ValueHandler vh = ORBUtility.createValueHandler();
+
+ cb = (CodeBase)vh.getRunTimeCodeBase();
+ return ORBUtility.connectAndGetIOR( this, cb ) ;
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3.java
++++ /dev/null
+@@ -1,57 +0,0 @@
+-/*
+- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-package com.sun.corba.se.impl.orbutil;
+-
+-import java.io.*;
+-import java.util.Hashtable;
+-
+-/**
+- * Implements legacy behavior from before Ladybird to maintain
+- * backwards compatibility.
+- */
+-public class IIOPInputStream_1_3 extends com.sun.corba.se.impl.io.IIOPInputStream
+-{
+- // The newer version in the io package correctly reads a wstring instead.
+- // This concerns bug 4379597.
+- protected String internalReadUTF(org.omg.CORBA.portable.InputStream stream)
+- {
+- return stream.read_string();
+- }
+-
+- /**
+- * Before JDK 1.3.1_01, the PutField/GetField implementation
+- * actually sent a Hashtable.
+- */
+- public ObjectInputStream.GetField readFields()
+- throws IOException, ClassNotFoundException, NotActiveException {
+- Hashtable fields = (Hashtable)readObject();
+- return new LegacyHookGetFields(fields);
+- }
+-
+- public IIOPInputStream_1_3()
+- throws java.io.IOException {
+- super();
+- }
+-}
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3_1.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPInputStream_1_3_1.java
++++ /dev/null
+@@ -1,54 +0,0 @@
+-/*
+- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/*
+- */
+-package com.sun.corba.se.impl.orbutil;
+-
+-import java.io.*;
+-import java.util.Hashtable;
+-
+-/**
+- * Implements legacy behavior from Ladybird to maintain
+- * backwards compatibility.
+- */
+-public class IIOPInputStream_1_3_1 extends com.sun.corba.se.impl.io.IIOPInputStream
+-{
+- public IIOPInputStream_1_3_1()
+- throws java.io.IOException {
+- super();
+- }
+-
+- /**
+- * Before JDK 1.3.1_01, the PutField/GetField implementation
+- * actually sent a Hashtable.
+- */
+- public ObjectInputStream.GetField readFields()
+- throws IOException, ClassNotFoundException, NotActiveException {
+-
+- Hashtable fields = (Hashtable)readObject();
+- return new LegacyHookGetFields(fields);
+- }
+-}
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3.java
++++ /dev/null
+@@ -1,68 +0,0 @@
+-/*
+- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-package com.sun.corba.se.impl.orbutil;
+-
+-import java.io.*;
+-
+-/**
+- * Implements legacy behavior from before Ladybird to maintain
+- * backwards compatibility.
+- */
+-public class IIOPOutputStream_1_3 extends com.sun.corba.se.impl.io.IIOPOutputStream
+-{
+- // We can't assume that the superclass's putFields
+- // member will be non-private. We must allow
+- // the RI to run on JDK 1.3.1 FCS as well as
+- // the JDK 1.3.1_01 patch.
+- private ObjectOutputStream.PutField putFields_1_3;
+-
+- // The newer version in the io package correctly writes a wstring instead.
+- // This concerns bug 4379597.
+- protected void internalWriteUTF(org.omg.CORBA.portable.OutputStream stream,
+- String data)
+- {
+- stream.write_string(data);
+- }
+-
+- public IIOPOutputStream_1_3()
+- throws java.io.IOException {
+- super();
+- }
+-
+- /**
+- * Before JDK 1.3.1_01, the PutField/GetField implementation
+- * actually sent a Hashtable.
+- */
+- public ObjectOutputStream.PutField putFields()
+- throws IOException {
+- putFields_1_3 = new LegacyHookPutFields();
+- return putFields_1_3;
+- }
+-
+- public void writeFields()
+- throws IOException {
+- putFields_1_3.write(this);
+- }
+-}
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3_1.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/IIOPOutputStream_1_3_1.java
++++ /dev/null
+@@ -1,66 +0,0 @@
+-/*
+- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/*
+- */
+-package com.sun.corba.se.impl.orbutil;
+-
+-import java.io.*;
+-import java.util.Hashtable;
+-
+-/**
+- * Implements legacy behavior from Ladybird to maintain
+- * backwards compatibility.
+- */
+-public class IIOPOutputStream_1_3_1 extends com.sun.corba.se.impl.io.IIOPOutputStream
+-{
+- // We can't assume that the superclass's putFields
+- // member will be non-private. We must allow
+- // the RI to run on JDK 1.3.1 FCS as well as
+- // the JDK 1.3.1_01 patch.
+- private ObjectOutputStream.PutField putFields_1_3_1;
+-
+- public IIOPOutputStream_1_3_1()
+- throws java.io.IOException {
+- super();
+- }
+-
+- /**
+- * Before JDK 1.3.1_01, the PutField/GetField implementation
+- * actually sent a Hashtable.
+- */
+- public ObjectOutputStream.PutField putFields()
+- throws IOException {
+-
+- putFields_1_3_1 = new LegacyHookPutFields();
+- return putFields_1_3_1;
+- }
+-
+- public void writeFields()
+- throws IOException {
+-
+- putFields_1_3_1.write(this);
+- }
+-}
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java b/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java
++++ corba/src/share/classes/com/sun/corba/se/impl/orbutil/ORBUtility.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -160,42 +160,10 @@ public final class ORBUtility {
+ }
+
+ /**
+- * Creates the correct ValueHandler for the given ORB,
+- * querying ORBVersion information. If the ORB or
+- * ORBVersion is null, gets the ValueHandler from
+- * Util.createValueHandler.
++ * Return default ValueHandler
+ */
+- public static ValueHandler createValueHandler(ORB orb) {
+-
+- if (orb == null)
+- return Util.createValueHandler();
+-
+- ORBVersion version = orb.getORBVersion();
+-
+- if (version == null)
+- return Util.createValueHandler();
+-
+- if (version.equals(ORBVersionFactory.getOLD()))
+- return new ValueHandlerImpl_1_3();
+- if (version.equals(ORBVersionFactory.getNEW()))
+- return new ValueHandlerImpl_1_3_1();
+-
++ public static ValueHandler createValueHandler() {
+ return Util.createValueHandler();
+- }
+-
+- /**
+- * Returns true if the given ORB could accurately be determined to be a
+- * Kestrel or earlier ORB. Note: If passed the ORBSingleton, this will return
+- * false.
+- */
+- public static boolean isLegacyORB(ORB orb)
+- {
+- try {
+- ORBVersion currentORB = orb.getORBVersion();
+- return currentORB.equals( ORBVersionFactory.getOLD() ) ;
+- } catch (SecurityException se) {
+- return false;
+- }
+ }
+
+ /**
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3.java
++++ /dev/null
+@@ -1,177 +0,0 @@
+-/*
+- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-package com.sun.corba.se.impl.orbutil;
+-
+-import org.omg.CORBA.ORB;
+-import java.io.Serializable;
+-import java.util.Hashtable;
+-import java.net.MalformedURLException;
+-import com.sun.corba.se.impl.io.TypeMismatchException;
+-import com.sun.corba.se.impl.util.RepositoryId;
+-
+-/**
+- * Delegates to the RepositoryId_1_3 implementation in
+- * com.sun.corba.se.impl.orbutil. This is necessary to
+- * overcome the fact that many of RepositoryId's methods
+- * are static.
+- */
+-public final class RepIdDelegator_1_3
+- implements RepositoryIdStrings,
+- RepositoryIdUtility,
+- RepositoryIdInterface
+-{
+- // RepositoryIdFactory methods
+-
+- public String createForAnyType(Class type) {
+- return RepositoryId_1_3.createForAnyType(type);
+- }
+-
+- public String createForJavaType(Serializable ser)
+- throws TypeMismatchException
+- {
+- return RepositoryId_1_3.createForJavaType(ser);
+- }
+-
+- public String createForJavaType(Class clz)
+- throws TypeMismatchException
+- {
+- return RepositoryId_1_3.createForJavaType(clz);
+- }
+-
+- public String createSequenceRepID(java.lang.Object ser) {
+- return RepositoryId_1_3.createSequenceRepID(ser);
+- }
+-
+- public String createSequenceRepID(Class clazz) {
+- return RepositoryId_1_3.createSequenceRepID(clazz);
+- }
+-
+- public RepositoryIdInterface getFromString(String repIdString) {
+- return new RepIdDelegator_1_3(RepositoryId_1_3.cache.getId(repIdString));
+- }
+-
+- // RepositoryIdUtility methods
+-
+- public boolean isChunkedEncoding(int valueTag) {
+- return RepositoryId.isChunkedEncoding(valueTag);
+- }
+-
+- public boolean isCodeBasePresent(int valueTag) {
+- return RepositoryId.isCodeBasePresent(valueTag);
+- }
+-
+- public String getClassDescValueRepId() {
+- return RepositoryId_1_3.kClassDescValueRepID;
+- }
+-
+- public String getWStringValueRepId() {
+- return RepositoryId_1_3.kWStringValueRepID;
+- }
+-
+- public int getTypeInfo(int valueTag) {
+- return RepositoryId.getTypeInfo(valueTag);
+- }
+-
+- public int getStandardRMIChunkedNoRepStrId() {
+- return RepositoryId.kPreComputed_StandardRMIChunked_NoRep;
+- }
+-
+- public int getCodeBaseRMIChunkedNoRepStrId() {
+- return RepositoryId.kPreComputed_CodeBaseRMIChunked_NoRep;
+- }
+-
+- public int getStandardRMIChunkedId() {
+- return RepositoryId.kPreComputed_StandardRMIChunked;
+- }
+-
+- public int getCodeBaseRMIChunkedId() {
+- return RepositoryId.kPreComputed_CodeBaseRMIChunked;
+- }
+-
+- public int getStandardRMIUnchunkedId() {
+- return RepositoryId.kPreComputed_StandardRMIUnchunked;
+- }
+-
+- public int getCodeBaseRMIUnchunkedId() {
+- return RepositoryId.kPreComputed_CodeBaseRMIUnchunked;
+- }
+-
+- public int getStandardRMIUnchunkedNoRepStrId() {
+- return RepositoryId.kPreComputed_StandardRMIUnchunked_NoRep;
+- }
+-
+- public int getCodeBaseRMIUnchunkedNoRepStrId() {
+- return RepositoryId.kPreComputed_CodeBaseRMIUnchunked_NoRep;
+- }
+-
+- // RepositoryIdInterface methods
+-
+- public Class getClassFromType() throws ClassNotFoundException {
+- return delegate.getClassFromType();
+- }
+-
+- public Class getClassFromType(String codebaseURL)
+- throws ClassNotFoundException, MalformedURLException
+- {
+- return delegate.getClassFromType(codebaseURL);
+- }
+-
+- public Class getClassFromType(Class expectedType,
+- String codebaseURL)
+- throws ClassNotFoundException, MalformedURLException
+- {
+- return delegate.getClassFromType(expectedType, codebaseURL);
+- }
+-
+- public String getClassName() {
+- return delegate.getClassName();
+- }
+-
+- // Constructor used for factory/utility cases
+- public RepIdDelegator_1_3() {}
+-
+- // Constructor used by getIdFromString. All non-static
+- // RepositoryId methods will use the provided delegate.
+- private RepIdDelegator_1_3(RepositoryId_1_3 _delegate) {
+- this.delegate = _delegate;
+- }
+-
+- private RepositoryId_1_3 delegate = null;
+-
+- public String toString() {
+- if (delegate != null)
+- return delegate.toString();
+- else
+- return this.getClass().getName();
+- }
+-
+- public boolean equals(Object obj) {
+- if (delegate != null)
+- return delegate.equals(obj);
+- else
+- return super.equals(obj);
+- }
+-}
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3_1.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepIdDelegator_1_3_1.java
++++ /dev/null
+@@ -1,177 +0,0 @@
+-/*
+- * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-package com.sun.corba.se.impl.orbutil;
+-
+-import org.omg.CORBA.ORB;
+-import java.io.Serializable;
+-import java.util.Hashtable;
+-import java.net.MalformedURLException;
+-import com.sun.corba.se.impl.io.TypeMismatchException;
+-import com.sun.corba.se.impl.util.RepositoryId;
+-
+-/**
+- * Delegates to the RepositoryId_1_3_1 implementation in
+- * com.sun.corba.se.impl.orbutil. This is necessary to
+- * overcome the fact that many of RepositoryId's methods
+- * are static.
+- */
+-public final class RepIdDelegator_1_3_1
+- implements RepositoryIdStrings,
+- RepositoryIdUtility,
+- RepositoryIdInterface
+-{
+- // RepositoryIdFactory methods
+-
+- public String createForAnyType(Class type) {
+- return RepositoryId_1_3_1.createForAnyType(type);
+- }
+-
+- public String createForJavaType(Serializable ser)
+- throws TypeMismatchException
+- {
+- return RepositoryId_1_3_1.createForJavaType(ser);
+- }
+-
+- public String createForJavaType(Class clz)
+- throws TypeMismatchException
+- {
+- return RepositoryId_1_3_1.createForJavaType(clz);
+- }
+-
+- public String createSequenceRepID(java.lang.Object ser) {
+- return RepositoryId_1_3_1.createSequenceRepID(ser);
+- }
+-
+- public String createSequenceRepID(Class clazz) {
+- return RepositoryId_1_3_1.createSequenceRepID(clazz);
+- }
+-
+- public RepositoryIdInterface getFromString(String repIdString) {
+- return new RepIdDelegator_1_3_1(RepositoryId_1_3_1.cache.getId(repIdString));
+- }
+-
+- // RepositoryIdUtility methods
+-
+- public boolean isChunkedEncoding(int valueTag) {
+- return RepositoryId.isChunkedEncoding(valueTag);
+- }
+-
+- public boolean isCodeBasePresent(int valueTag) {
+- return RepositoryId.isCodeBasePresent(valueTag);
+- }
+-
+- public String getClassDescValueRepId() {
+- return RepositoryId_1_3_1.kClassDescValueRepID;
+- }
+-
+- public String getWStringValueRepId() {
+- return RepositoryId_1_3_1.kWStringValueRepID;
+- }
+-
+- public int getTypeInfo(int valueTag) {
+- return RepositoryId.getTypeInfo(valueTag);
+- }
+-
+- public int getStandardRMIChunkedNoRepStrId() {
+- return RepositoryId.kPreComputed_StandardRMIChunked_NoRep;
+- }
+-
+- public int getCodeBaseRMIChunkedNoRepStrId() {
+- return RepositoryId.kPreComputed_CodeBaseRMIChunked_NoRep;
+- }
+-
+- public int getStandardRMIChunkedId() {
+- return RepositoryId.kPreComputed_StandardRMIChunked;
+- }
+-
+- public int getCodeBaseRMIChunkedId() {
+- return RepositoryId.kPreComputed_CodeBaseRMIChunked;
+- }
+-
+- public int getStandardRMIUnchunkedId() {
+- return RepositoryId.kPreComputed_StandardRMIUnchunked;
+- }
+-
+- public int getCodeBaseRMIUnchunkedId() {
+- return RepositoryId.kPreComputed_CodeBaseRMIUnchunked;
+- }
+-
+- public int getStandardRMIUnchunkedNoRepStrId() {
+- return RepositoryId.kPreComputed_StandardRMIUnchunked_NoRep;
+- }
+-
+- public int getCodeBaseRMIUnchunkedNoRepStrId() {
+- return RepositoryId.kPreComputed_CodeBaseRMIUnchunked_NoRep;
+- }
+-
+- // RepositoryIdInterface methods
+-
+- public Class getClassFromType() throws ClassNotFoundException {
+- return delegate.getClassFromType();
+- }
+-
+- public Class getClassFromType(String codebaseURL)
+- throws ClassNotFoundException, MalformedURLException
+- {
+- return delegate.getClassFromType(codebaseURL);
+- }
+-
+- public Class getClassFromType(Class expectedType,
+- String codebaseURL)
+- throws ClassNotFoundException, MalformedURLException
+- {
+- return delegate.getClassFromType(expectedType, codebaseURL);
+- }
+-
+- public String getClassName() {
+- return delegate.getClassName();
+- }
+-
+- // Constructor used for factory/utility cases
+- public RepIdDelegator_1_3_1() {}
+-
+- // Constructor used by getIdFromString. All non-static
+- // RepositoryId methods will use the provided delegate.
+- private RepIdDelegator_1_3_1(RepositoryId_1_3_1 _delegate) {
+- this.delegate = _delegate;
+- }
+-
+- private RepositoryId_1_3_1 delegate = null;
+-
+- public String toString() {
+- if (delegate != null)
+- return delegate.toString();
+- else
+- return this.getClass().getName();
+- }
+-
+- public boolean equals(Object obj) {
+- if (delegate != null)
+- return delegate.equals(obj);
+- else
+- return super.equals(obj);
+- }
+-}
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3.java
++++ /dev/null
+@@ -1,108 +0,0 @@
+-/*
+- * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-/*
+- * Licensed Materials - Property of IBM
+- * RMI-IIOP v1.0
+- * Copyright IBM Corp. 1998 1999 All Rights Reserved
+- *
+- */
+-
+-package com.sun.corba.se.impl.orbutil;
+-
+-import java.util.Stack;
+-import java.util.Hashtable;
+-import java.util.EmptyStackException;
+-import java.util.Enumeration;
+-
+-// Really limited pool - in this case just creating several at a time...
+-class RepositoryIdPool_1_3 extends Stack {
+-
+- private static int MAX_CACHE_SIZE = 4;
+- private RepositoryIdCache_1_3 cache;
+-
+- public final synchronized RepositoryId_1_3 popId() {
+-
+- try {
+- return (RepositoryId_1_3)super.pop();
+- }
+- catch(EmptyStackException e) {
+- increasePool(5);
+- return (RepositoryId_1_3)super.pop();
+- }
+-
+- }
+-
+- // Pool management
+- final void increasePool(int size) {
+- //if (cache.size() <= MAX_CACHE_SIZE)
+- for (int i = size; i > 0; i--)
+- push(new RepositoryId_1_3());
+- /*
+- // _REVISIT_ This will not work w/out either thread tracing or weak references. I am
+- // betting that thread tracing almost completely negates benefit of reuse. Until either
+- // 1.2 only inclusion or proof to the contrary, I'll leave it this way...
+- else {
+- int numToReclaim = cache.size() / 2;
+- Enumeration keys = cache.keys();
+- Enumeration elements = cache.elements();
+- for (int i = numToReclaim; i > 0; i--) {
+- Object key = keys.nextElement();
+- Object element = elements.nextElement();
+-
+- push(element);
+- cache.remove(key);
+- }
+- }
+- */
+- }
+-
+- final void setCaches(RepositoryIdCache_1_3 cache) {
+- this.cache = cache;
+- }
+-
+-}
+-
+-public class RepositoryIdCache_1_3 extends Hashtable {
+-
+- private RepositoryIdPool_1_3 pool = new RepositoryIdPool_1_3();
+-
+- public RepositoryIdCache_1_3() {
+- pool.setCaches(this);
+- }
+-
+- public final synchronized RepositoryId_1_3 getId(String key) {
+- RepositoryId_1_3 repId = (RepositoryId_1_3)super.get(key);
+-
+- if (repId != null)
+- return repId;
+- else {
+- //repId = pool.popId().init(key);
+- repId = new RepositoryId_1_3(key);
+- put(key, repId);
+- return repId;
+- }
+-
+- }
+-}
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3_1.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdCache_1_3_1.java
++++ /dev/null
+@@ -1,102 +0,0 @@
+-/*
+- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-package com.sun.corba.se.impl.orbutil;
+-
+-import java.util.Stack;
+-import java.util.Hashtable;
+-import java.util.EmptyStackException;
+-import java.util.Enumeration;
+-
+-// Really limited pool - in this case just creating several at a time...
+-class RepositoryIdPool_1_3_1 extends Stack {
+-
+- private static int MAX_CACHE_SIZE = 4;
+- private RepositoryIdCache_1_3_1 cache;
+-
+- public final synchronized RepositoryId_1_3_1 popId() {
+-
+- try {
+- return (RepositoryId_1_3_1)super.pop();
+- }
+- catch(EmptyStackException e) {
+- increasePool(5);
+- return (RepositoryId_1_3_1)super.pop();
+- }
+-
+- }
+-
+- // Pool management
+- final void increasePool(int size) {
+- //if (cache.size() <= MAX_CACHE_SIZE)
+- for (int i = size; i > 0; i--)
+- push(new RepositoryId_1_3_1());
+- /*
+- // _REVISIT_ This will not work w/out either thread tracing or weak references. I am
+- // betting that thread tracing almost completely negates benefit of reuse. Until either
+- // 1.2 only inclusion or proof to the contrary, I'll leave it this way...
+- else {
+- int numToReclaim = cache.size() / 2;
+- Enumeration keys = cache.keys();
+- Enumeration elements = cache.elements();
+- for (int i = numToReclaim; i > 0; i--) {
+- Object key = keys.nextElement();
+- Object element = elements.nextElement();
+-
+- push(element);
+- cache.remove(key);
+- }
+- }
+- */
+- }
+-
+- final void setCaches(RepositoryIdCache_1_3_1 cache) {
+- this.cache = cache;
+- }
+-
+-}
+-
+-public class RepositoryIdCache_1_3_1 extends Hashtable {
+-
+- private RepositoryIdPool_1_3_1 pool = new RepositoryIdPool_1_3_1();
+-
+- public RepositoryIdCache_1_3_1() {
+- pool.setCaches(this);
+- }
+-
+- public final synchronized RepositoryId_1_3_1 getId(String key) {
+- RepositoryId_1_3_1 repId = (RepositoryId_1_3_1)super.get(key);
+-
+- if (repId != null)
+- return repId;
+- else {
+- //repId = pool.popId().init(key);
+- repId = new RepositoryId_1_3_1(key);
+- put(key, repId);
+- return repId;
+- }
+-
+- }
+-}
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java
++++ corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryIdFactory.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -30,12 +30,6 @@ import com.sun.corba.se.spi.orb.ORB;
+
+ public abstract class RepositoryIdFactory
+ {
+- private static final RepIdDelegator_1_3 legacyDelegator
+- = new RepIdDelegator_1_3();
+-
+- private static final RepIdDelegator_1_3_1 ladybirdDelegator
+- = new RepIdDelegator_1_3_1();
+-
+ private static final RepIdDelegator currentDelegator
+ = new RepIdDelegator();
+
+@@ -48,29 +42,6 @@ public abstract class RepositoryIdFactor
+ }
+
+ /**
+- * Checks the version of the ORB and returns the appropriate
+- * RepositoryIdStrings instance.
+- */
+- public static RepositoryIdStrings getRepIdStringsFactory(ORB orb)
+- {
+- if (orb != null) {
+- switch (orb.getORBVersion().getORBType()) {
+- case ORBVersion.NEWER:
+- case ORBVersion.FOREIGN:
+- case ORBVersion.JDK1_3_1_01:
+- return currentDelegator;
+- case ORBVersion.OLD:
+- return legacyDelegator;
+- case ORBVersion.NEW:
+- return ladybirdDelegator;
+- default:
+- return currentDelegator;
+- }
+- } else
+- return currentDelegator;
+- }
+-
+- /**
+ * Returns the latest version RepositoryIdUtility instance
+ */
+ public static RepositoryIdUtility getRepIdUtility()
+@@ -78,26 +49,4 @@ public abstract class RepositoryIdFactor
+ return currentDelegator;
+ }
+
+- /**
+- * Checks the version of the ORB and returns the appropriate
+- * RepositoryIdUtility instance.
+- */
+- public static RepositoryIdUtility getRepIdUtility(ORB orb)
+- {
+- if (orb != null) {
+- switch (orb.getORBVersion().getORBType()) {
+- case ORBVersion.NEWER:
+- case ORBVersion.FOREIGN:
+- case ORBVersion.JDK1_3_1_01:
+- return currentDelegator;
+- case ORBVersion.OLD:
+- return legacyDelegator;
+- case ORBVersion.NEW:
+- return ladybirdDelegator;
+- default:
+- return currentDelegator;
+- }
+- } else
+- return currentDelegator;
+- }
+ }
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3.java
++++ /dev/null
+@@ -1,990 +0,0 @@
+-/*
+- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-/*
+- * Licensed Materials - Property of IBM
+- * RMI-IIOP v1.0
+- * Copyright IBM Corp. 1998 1999 All Rights Reserved
+- *
+- */
+-
+-package com.sun.corba.se.impl.orbutil;
+-
+-import java.util.StringTokenizer;
+-import java.util.Hashtable;
+-import java.io.IOException;
+-import java.lang.reflect.Method;
+-
+-// Imports for using codebase URL to load class
+-import java.net.MalformedURLException;
+-import org.omg.CORBA.portable.ValueBase;
+-import org.omg.CORBA.portable.IDLEntity;
+-
+-import com.sun.corba.se.impl.util.JDKBridge;
+-import com.sun.corba.se.impl.util.Utility;
+-import com.sun.corba.se.impl.util.PackagePrefixChecker;
+-import com.sun.corba.se.impl.util.IdentityHashtable;
+-import com.sun.corba.se.impl.io.ObjectStreamClass;
+-
+-import javax.rmi.CORBA.Util;
+-
+-// keeping the original RepositoryId class that was shipped in
+-// JDK 1.3. It has interoperability bugs
+-
+-public class RepositoryId_1_3 {
+-
+- // Legal IDL Identifier characters (1 = legal). Note
+- // that '.' (2E) is marked as legal even though it is
+- // not legal in IDL. This allows us to treat a fully
+- // qualified Java name with '.' package separators
+- // uniformly, and is safe because that is the only
+- // legal use of '.' in a Java name.
+-
+- public static final RepositoryIdCache_1_3 cache = new RepositoryIdCache_1_3();
+- private static final byte[] IDL_IDENTIFIER_CHARS = {
+-
+- // 0 1 2 3 4 5 6 7 8 9 a b c d e f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 00-0f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 10-1f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0, // 20-2f
+- 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, // 30-3f
+- 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 40-4f
+- 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, // 50-5f
+- 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 60-6f
+- 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, // 70-7f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 80-8f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 90-9f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // a0-af
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // b0-bf
+- 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // c0-cf
+- 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // d0-df
+- 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // e0-ef
+- 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // f0-ff
+- };
+-
+- private static String defaultServerURL = null;
+- private static boolean useCodebaseOnly = false;
+-
+- static {
+- if (defaultServerURL == null)
+- defaultServerURL = (String)JDKBridge.getLocalCodebase();
+- useCodebaseOnly = JDKBridge.useCodebaseOnly();
+-
+- }
+-
+- private static IdentityHashtable classToRepStr = new IdentityHashtable();
+- private static IdentityHashtable classIDLToRepStr = new IdentityHashtable();
+- private static IdentityHashtable classSeqToRepStr = new IdentityHashtable();
+-
+- private static IdentityHashtable repStrToByteArray = new IdentityHashtable();
+- private static Hashtable repStrToClass = new Hashtable();
+-
+- private String repId = null;
+- private boolean isSupportedFormat = true;
+- private String typeString = null;
+- private String versionString = null;
+- private boolean isSequence = false;
+- private boolean isRMIValueType = false;
+- private boolean isIDLType = false;
+- private String completeClassName = null;
+- private String unqualifiedName = null;
+- private String definedInId = null;
+- private Class clazz = null;
+- private String suid = null, actualSuid = null;
+- private long suidLong = ObjectStreamClass.kDefaultUID, actualSuidLong = ObjectStreamClass.kDefaultUID;
+-
+- // Repository ID fragments
+- private static final String kValuePrefix = "RMI:";
+- private static final String kIDLPrefix = "IDL:";
+- private static final String kIDLNamePrefix = "omg.org/";
+- private static final String kIDLClassnamePrefix = "org.omg.";
+- private static final String kSequencePrefix = "[";
+- private static final String kCORBAPrefix = "CORBA/";
+- private static final String kArrayPrefix = kValuePrefix + kSequencePrefix + kCORBAPrefix;
+- private static final int kValuePrefixLength = kValuePrefix.length();
+- private static final int kIDLPrefixLength = kIDLPrefix.length();
+- private static final int kSequencePrefixLength = kSequencePrefix.length();
+- private static final String kInterfaceHashCode = ":0000000000000000";
+- private static final String kInterfaceOnlyHashStr = "0000000000000000";
+- private static final String kExternalizableHashStr = "0000000000000001";
+-
+- // Value tag utility methods and constants
+- public static final int kInitialValueTag= 0x7fffff00;
+- public static final int kNoTypeInfo = 0;
+- public static final int kSingleRepTypeInfo = 0x02;
+- public static final int kPartialListTypeInfo = 0x06;
+- public static final int kChunkedMask = 0x08;
+-
+- // Public, well known repository IDs
+-
+- // _REVISIT_ : A table structure with a good search routine for all of this
+- // would be more efficient and easier to maintain...
+-
+- // String
+- public static final String kWStringValueVersion = "1.0";
+- public static final String kWStringValueHash = ":"+kWStringValueVersion;
+- public static final String kWStringStubValue = "WStringValue";
+- public static final String kWStringTypeStr = "omg.org/CORBA/"+kWStringStubValue;
+- public static final String kWStringValueRepID = kIDLPrefix + kWStringTypeStr + kWStringValueHash;
+-
+- // Any
+- public static final String kAnyRepID = kIDLPrefix + "omg.org/CORBA/Any";
+-
+- // Class
+- public static final String kClassDescValueHash = ":" + Long.toHexString(
+- ObjectStreamClass.getSerialVersionUID(javax.rmi.CORBA.ClassDesc.class));
+- public static final String kClassDescStubValue = "ClassDesc";
+- public static final String kClassDescTypeStr = "javax.rmi.CORBA."+kClassDescStubValue;
+- public static final String kClassDescValueRepID = kValuePrefix + kClassDescTypeStr + kClassDescValueHash;
+-
+- // Object
+- public static final String kObjectValueHash = ":1.0";
+- public static final String kObjectStubValue = "Object";
+-
+- // Sequence
+- public static final String kSequenceValueHash = ":1.0";
+- public static final String kPrimitiveSequenceValueHash = ":0000000000000000";
+-
+- // Serializable
+- public static final String kSerializableValueHash = ":1.0";
+- public static final String kSerializableStubValue = "Serializable";
+-
+- // Externalizable
+- public static final String kExternalizableValueHash = ":1.0";
+- public static final String kExternalizableStubValue = "Externalizable";
+-
+- // Remote (The empty string is used for java.rmi.Remote)
+- public static final String kRemoteValueHash = "";
+- public static final String kRemoteStubValue = "";
+- public static final String kRemoteTypeStr = "";
+- public static final String kRemoteValueRepID = "";
+-
+- private static final Hashtable kSpecialArrayTypeStrings = new Hashtable();
+-
+- static {
+- kSpecialArrayTypeStrings.put("CORBA.WStringValue", new StringBuffer(java.lang.String.class.getName()));
+- kSpecialArrayTypeStrings.put("javax.rmi.CORBA.ClassDesc", new StringBuffer(java.lang.Class.class.getName()));
+- kSpecialArrayTypeStrings.put("CORBA.Object", new StringBuffer(java.rmi.Remote.class.getName()));
+-
+- }
+-
+- private static final Hashtable kSpecialCasesRepIDs = new Hashtable();
+-
+- static {
+- kSpecialCasesRepIDs.put(java.lang.String.class, kWStringValueRepID);
+- kSpecialCasesRepIDs.put(java.lang.Class.class, kClassDescValueRepID);
+- kSpecialCasesRepIDs.put(java.rmi.Remote.class, kRemoteValueRepID);
+- }
+-
+- private static final Hashtable kSpecialCasesStubValues = new Hashtable();
+-
+- static {
+- kSpecialCasesStubValues.put(java.lang.String.class, kWStringStubValue);
+- kSpecialCasesStubValues.put(java.lang.Class.class, kClassDescStubValue);
+- kSpecialCasesStubValues.put(java.lang.Object.class, kObjectStubValue);
+- kSpecialCasesStubValues.put(java.io.Serializable.class, kSerializableStubValue);
+- kSpecialCasesStubValues.put(java.io.Externalizable.class, kExternalizableStubValue);
+- kSpecialCasesStubValues.put(java.rmi.Remote.class, kRemoteStubValue);
+- }
+-
+-
+- private static final Hashtable kSpecialCasesVersions = new Hashtable();
+-
+- static {
+- kSpecialCasesVersions.put(java.lang.String.class, kWStringValueHash);
+- kSpecialCasesVersions.put(java.lang.Class.class, kClassDescValueHash);
+- kSpecialCasesVersions.put(java.lang.Object.class, kObjectValueHash);
+- kSpecialCasesVersions.put(java.io.Serializable.class, kSerializableValueHash);
+- kSpecialCasesVersions.put(java.io.Externalizable.class, kExternalizableValueHash);
+- kSpecialCasesVersions.put(java.rmi.Remote.class, kRemoteValueHash);
+- }
+-
+- private static final Hashtable kSpecialCasesClasses = new Hashtable();
+-
+- static {
+- kSpecialCasesClasses.put(kWStringTypeStr, java.lang.String.class);
+- kSpecialCasesClasses.put(kClassDescTypeStr, java.lang.Class.class);
+- kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class);
+-
+- kSpecialCasesClasses.put("org.omg.CORBA.WStringValue", java.lang.String.class);
+- kSpecialCasesClasses.put("javax.rmi.CORBA.ClassDesc", java.lang.Class.class);
+- //kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class);
+- }
+-
+- private static final Hashtable kSpecialCasesArrayPrefix = new Hashtable();
+-
+- static {
+- kSpecialCasesArrayPrefix.put(java.lang.String.class, kValuePrefix + kSequencePrefix + kCORBAPrefix);
+- kSpecialCasesArrayPrefix.put(java.lang.Class.class, kValuePrefix + kSequencePrefix + "javax/rmi/CORBA/");
+- kSpecialCasesArrayPrefix.put(java.lang.Object.class, kValuePrefix + kSequencePrefix + "java/lang/");
+- kSpecialCasesArrayPrefix.put(java.io.Serializable.class, kValuePrefix + kSequencePrefix + "java/io/");
+- kSpecialCasesArrayPrefix.put(java.io.Externalizable.class, kValuePrefix + kSequencePrefix + "java/io/");
+- kSpecialCasesArrayPrefix.put(java.rmi.Remote.class, kValuePrefix + kSequencePrefix + kCORBAPrefix);
+- }
+-
+- private static final Hashtable kSpecialPrimitives = new Hashtable();
+-
+- static {
+- kSpecialPrimitives.put("int","long");
+- kSpecialPrimitives.put("long","longlong");
+- kSpecialPrimitives.put("byte","octet");
+- }
+-
+- /**
+- * Used to convert ascii to hex.
+- */
+- private static final byte ASCII_HEX[] = {
+- (byte)'0',
+- (byte)'1',
+- (byte)'2',
+- (byte)'3',
+- (byte)'4',
+- (byte)'5',
+- (byte)'6',
+- (byte)'7',
+- (byte)'8',
+- (byte)'9',
+- (byte)'A',
+- (byte)'B',
+- (byte)'C',
+- (byte)'D',
+- (byte)'E',
+- (byte)'F',
+- };
+-
+-
+- // Interface Rep ID Strings
+- public static final String kjava_rmi_Remote = createForAnyType(java.rmi.Remote.class);
+- public static final String korg_omg_CORBA_Object = createForAnyType(org.omg.CORBA.Object.class);
+-
+- // Dummy arguments for getIdFromHelper method
+- public static final Class kNoParamTypes[] ={};
+- public static final Object kNoArgs[] = {};
+-
+-
+- RepositoryId_1_3(){}
+-
+- RepositoryId_1_3(String aRepId){
+- init(aRepId);
+- }
+-
+- RepositoryId_1_3 init(String aRepId){
+-
+- this.repId = aRepId;
+-
+- // Special case for remote
+- if (aRepId.length() == 0) {
+- clazz = java.rmi.Remote.class;
+- typeString = "";
+- isRMIValueType = true;
+- suid = kInterfaceOnlyHashStr;
+- return this;
+- }
+- else if (aRepId.equals(kWStringValueRepID)) {
+- clazz = java.lang.String.class;
+- typeString = kWStringTypeStr;
+- isIDLType = true;
+- versionString = kWStringValueVersion;
+- return this;
+- }
+- else {
+-
+- String repId = convertFromISOLatin1(aRepId);
+-
+- versionString = repId.substring(repId.indexOf(':', repId.indexOf(':')+1));
+- if (repId.startsWith(kIDLPrefix)) {
+- typeString =
+- repId.substring(kIDLPrefixLength, repId.indexOf(':', kIDLPrefixLength));
+- isIDLType = true;
+- if (typeString.startsWith(kIDLNamePrefix))
+- completeClassName = kIDLClassnamePrefix +
+- typeString.substring(kIDLNamePrefix.length()).replace('/','.');
+- else completeClassName = typeString.replace('/','.');
+-
+- }
+- else if (repId.startsWith(kValuePrefix)) {
+- typeString =
+- repId.substring(kValuePrefixLength, repId.indexOf(':', kValuePrefixLength));
+- isRMIValueType = true;
+-
+- if (versionString.indexOf('.') == -1) {
+- actualSuid = versionString.substring(1);
+- suid = actualSuid; // default if not explicitly specified
+-
+- if (actualSuid.indexOf(':') != -1){
+- // we have a declared hash also
+- int pos = actualSuid.indexOf(':')+1;
+- // actualSuid = suid.substring(pos);
+- // suid = suid.substring(0, pos-1);
+- suid = actualSuid.substring(pos);
+- actualSuid = actualSuid.substring(0, pos-1);
+- }
+-
+- }
+- else {
+- // _REVISIT_ : Special case version failure ?
+- }
+- }
+- else isSupportedFormat = false;
+-
+- if (typeString.startsWith(kSequencePrefix)) {
+- isSequence = true;
+- }
+-
+-
+- return this;
+- }
+- }
+-
+- public final String getUnqualifiedName() {
+- if (unqualifiedName == null){
+- String className = getClassName();
+- int index = (className != null) ? className.lastIndexOf('.') : -1;
+- if (index == -1){
+- unqualifiedName = className;
+- definedInId = "IDL::1.0";
+- }
+- else {
+- unqualifiedName = className.substring(index);
+- definedInId = "IDL:" + className.substring(0, index).replace('.','/') + ":1.0";
+- }
+- }
+-
+- return unqualifiedName;
+- }
+-
+- public final String getDefinedInId() {
+- if (definedInId == null){
+- getUnqualifiedName();
+- }
+-
+- return definedInId;
+- }
+-
+- public final String getTypeString() {
+- return typeString;
+- }
+-
+- public final String getVersionString() {
+- return versionString;
+- }
+-
+- public final String getSerialVersionUID() {
+- return suid;
+- }
+-
+- public final String getActualSerialVersionUID() {
+- return actualSuid;
+- }
+- public final long getSerialVersionUIDAsLong() {
+- return suidLong;
+- }
+-
+- public final long getActualSerialVersionUIDAsLong() {
+- return actualSuidLong;
+- }
+-
+- public final boolean isRMIValueType() {
+- return isRMIValueType;
+- }
+-
+- public final boolean isIDLType() {
+- return isIDLType;
+- }
+-
+- public final String getRepositoryId() {
+- return repId;
+- }
+-
+- public static byte[] getByteArray(String repStr) {
+- synchronized (repStrToByteArray){
+- return (byte[]) repStrToByteArray.get(repStr);
+- }
+- }
+-
+- public static void setByteArray(String repStr, byte[] repStrBytes) {
+- synchronized (repStrToByteArray){
+- repStrToByteArray.put(repStr, repStrBytes);
+- }
+- }
+-
+- public final boolean isSequence() {
+- return isSequence;
+- }
+-
+- public final boolean isSupportedFormat() {
+- return isSupportedFormat;
+- }
+-
+-
+- // This method will return the classname from the typestring OR if the classname turns out to be
+- // a special class "pseudo" name, then the matching real classname is returned.
+- public final String getClassName() {
+-
+- if (isRMIValueType)
+- return typeString;
+- else if (isIDLType)
+- return completeClassName;
+- else return null;
+-
+- }
+-
+- // This method calls getClazzFromType() and falls back to the repStrToClass
+- // cache if no class was found. It's used where any class matching the
+- // given repid is an acceptable result.
+- public final Class getAnyClassFromType() throws ClassNotFoundException {
+- try {
+- return getClassFromType();
+- } catch (ClassNotFoundException cnfe) {
+- Class clz = (Class)repStrToClass.get(repId);
+- if (clz != null)
+- return clz;
+- else
+- throw cnfe;
+- }
+- }
+-
+- public final Class getClassFromType()
+- throws ClassNotFoundException {
+- if (clazz != null)
+- return clazz;
+-
+- Class specialCase = (Class)kSpecialCasesClasses.get(getClassName());
+-
+- if (specialCase != null){
+- clazz = specialCase;
+- return specialCase;
+- }
+- else
+- {
+- try{
+- return Util.loadClass(getClassName(), null, null);
+- }
+- catch(ClassNotFoundException cnfe){
+- if (defaultServerURL != null) {
+- try{
+- return getClassFromType(defaultServerURL);
+- }
+- catch(MalformedURLException mue){
+- throw cnfe;
+- }
+- }
+- else throw cnfe;
+- }
+- }
+-
+- }
+-
+- public final Class getClassFromType(Class expectedType, String codebase)
+- throws ClassNotFoundException {
+- if (clazz != null)
+- return clazz;
+-
+- Class specialCase = (Class)kSpecialCasesClasses.get(getClassName());
+-
+- if (specialCase != null){
+- clazz = specialCase;
+- return specialCase;
+- } else {
+- ClassLoader expectedTypeClassLoader = (expectedType == null ? null : expectedType.getClassLoader());
+- return loadClassOfType(getClassName(),
+- codebase,
+- expectedTypeClassLoader,
+- expectedType,
+- expectedTypeClassLoader);
+- }
+-
+- }
+-
+- public final Class getClassFromType(String url)
+- throws ClassNotFoundException, MalformedURLException {
+- return Util.loadClass(getClassName(), url, null);
+- }
+-
+- public final String toString() {
+- return repId;
+- }
+-
+- private static String createHashString(java.io.Serializable ser) {
+-
+- return createHashString(ser.getClass());
+- }
+-
+- private static String createHashString(java.lang.Class clazz) {
+-
+- if (clazz.isInterface() || !java.io.Serializable.class.isAssignableFrom(clazz))
+- return kInterfaceHashCode;
+-
+-
+- long actualLong = ObjectStreamClassUtil_1_3.computeStructuralUID(false, clazz);
+- String hash = null;
+- if (actualLong == 0)
+- hash = kInterfaceOnlyHashStr;
+- else if (actualLong == 1)
+- hash = kExternalizableHashStr;
+- else
+- hash = Long.toHexString(actualLong).toUpperCase();
+- while(hash.length() < 16){
+- hash = "0" + hash;
+- }
+-
+- long declaredLong = ObjectStreamClassUtil_1_3.computeSerialVersionUID(clazz);
+- String declared = null;
+- if (declaredLong == 0)
+- declared = kInterfaceOnlyHashStr;
+- else if (declaredLong == 1)
+- declared = kExternalizableHashStr;
+- else
+- declared = Long.toHexString(declaredLong).toUpperCase();
+- while (declared.length() < 16){
+- declared = "0" + declared;
+- }
+- hash = hash + ":" + declared;
+-
+- return ":" + hash;
+- }
+-
+- /**
+- * Creates a repository ID for a sequence. This is for expert users only as
+- * this method assumes the object passed is an array. If passed an object
+- * that is not an array, it will produce a rep id for a sequence of zero
+- * length. This would be an error.
+- * @param ser The Java object to create a repository ID for
+- **/
+- public static String createSequenceRepID(java.lang.Object ser){
+- return createSequenceRepID(ser.getClass());
+- }
+-
+- /**
+- * Creates a repository ID for a sequence. This is for expert users only as
+- * this method assumes the object passed is an array. If passed an object
+- * that is not an array, it will produce a malformed rep id.
+- * @param clazz The Java class to create a repository ID for
+- **/
+- public static String createSequenceRepID(java.lang.Class clazz){
+- synchronized (classSeqToRepStr){
+-
+- String repid = (String)classSeqToRepStr.get(clazz);
+- if (repid != null)
+- return repid;
+-
+- Class originalClazz = clazz;
+-
+- Class type = null;
+- int numOfDims = 0;
+-
+- while ((type = clazz.getComponentType()) != null) {
+- numOfDims++;
+- clazz = type;
+- }
+-
+- if (clazz.isPrimitive())
+- repid = kValuePrefix + originalClazz.getName() + kPrimitiveSequenceValueHash;
+- else {
+- StringBuffer buf = new StringBuffer();
+- buf.append(kValuePrefix);
+- while(numOfDims-- > 0) {
+- buf.append("[");
+- }
+- buf.append("L");
+- buf.append(convertToISOLatin1(clazz.getName()));
+- buf.append(";");
+- buf.append(createHashString(clazz));
+- repid = buf.toString();
+- }
+- classSeqToRepStr.put(originalClazz,repid);
+- return repid;
+- }
+-
+- }
+-
+-
+- public static String createForSpecialCase(java.lang.Class clazz){
+- if (clazz.isArray()){
+- return createSequenceRepID(clazz);
+- }
+- else {
+- return (String)kSpecialCasesRepIDs.get(clazz);
+- }
+- }
+-
+- public static String createForSpecialCase(java.io.Serializable ser){
+- Class clazz = ser.getClass();
+- if (clazz.isArray()){
+- return createSequenceRepID(ser);
+- }
+- else
+- return createForSpecialCase(clazz);
+- }
+-
+- /**
+- * Creates a repository ID for a normal Java Type.
+- * @param ser The Java object to create a repository ID for
+- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the
+- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
+- **/
+- public static String createForJavaType(java.io.Serializable ser)
+- throws com.sun.corba.se.impl.io.TypeMismatchException
+- {
+- synchronized (classToRepStr) {
+- String repid = createForSpecialCase(ser);
+- if (repid != null)
+- return repid;
+- Class clazz = ser.getClass();
+- repid = (String)classToRepStr.get(clazz);
+-
+- if (repid != null)
+- return repid;
+-
+- repid = kValuePrefix + convertToISOLatin1(clazz.getName()) +
+- createHashString(clazz);
+-
+- classToRepStr.put(clazz, repid);
+- repStrToClass.put(repid, clazz);
+- return repid;
+- }
+- }
+-
+- /**
+- * Creates a repository ID for a normal Java Type.
+- * @param clz The Java class to create a repository ID for
+- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the
+- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
+- **/
+- public static String createForJavaType(Class clz)
+- throws com.sun.corba.se.impl.io.TypeMismatchException
+- {
+- synchronized (classToRepStr){
+- String repid = createForSpecialCase(clz);
+- if (repid != null)
+- return repid;
+-
+- repid = (String)classToRepStr.get(clz);
+- if (repid != null)
+- return repid;
+-
+- repid = kValuePrefix + convertToISOLatin1(clz.getName()) +
+- createHashString(clz);
+-
+- classToRepStr.put(clz, repid);
+- repStrToClass.put(repid, clz);
+- return repid;
+- }
+- }
+-
+- /**
+- * Creates a repository ID for an IDL Java Type.
+- * @param ser The IDL Value object to create a repository ID for
+- * @param major The major version number
+- * @param minor The minor version number
+- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser does not implement the
+- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
+- **/
+- public static String createForIDLType(Class ser, int major, int minor)
+- throws com.sun.corba.se.impl.io.TypeMismatchException
+- {
+- synchronized (classIDLToRepStr){
+- String repid = (String)classIDLToRepStr.get(ser);
+- if (repid != null)
+- return repid;
+-
+- repid = kIDLPrefix + convertToISOLatin1(ser.getName()).replace('.','/') +
+- ":" + major + "." + minor;
+- classIDLToRepStr.put(ser, repid);
+- return repid;
+- }
+- }
+-
+- private static String getIdFromHelper(Class clazz){
+- try {
+- Class helperClazz = Utility.loadClassForClass(clazz.getName()+"Helper", null,
+- clazz.getClassLoader(), clazz, clazz.getClassLoader());
+- Method idMethod = helperClazz.getDeclaredMethod("id", kNoParamTypes);
+- return (String)idMethod.invoke(null, kNoArgs);
+- }
+- catch(java.lang.ClassNotFoundException cnfe)
+- {
+- throw new org.omg.CORBA.MARSHAL(cnfe.toString());
+- }
+- catch(java.lang.NoSuchMethodException nsme)
+- {
+- throw new org.omg.CORBA.MARSHAL(nsme.toString());
+- }
+- catch(java.lang.reflect.InvocationTargetException ite)
+- {
+- throw new org.omg.CORBA.MARSHAL(ite.toString());
+- }
+- catch(java.lang.IllegalAccessException iae)
+- {
+- throw new org.omg.CORBA.MARSHAL(iae.toString());
+- }
+- }
+-
+- /**
+- * Createa a repository ID for the type if it is either a java type
+- * or an IDL type.
+- * @param type The type to create rep. id for
+- * @return The rep. id.
+- **/
+- public static String createForAnyType(Class type) {
+- try{
+- if (type.isArray())
+- return createSequenceRepID(type);
+- else if (IDLEntity.class.isAssignableFrom(type))
+- {
+- try{
+- return getIdFromHelper(type);
+- }
+- catch(Throwable t) {
+- return createForIDLType(type, 1, 0);
+- }
+- }
+- else return createForJavaType(type);
+- }
+- catch(com.sun.corba.se.impl.io.TypeMismatchException e){
+- return null;
+- }
+-
+- }
+-
+- public static boolean isAbstractBase(Class clazz) {
+- return (clazz.isInterface() &&
+- IDLEntity.class.isAssignableFrom(clazz) &&
+- (!ValueBase.class.isAssignableFrom(clazz)) &&
+- (!org.omg.CORBA.Object.class.isAssignableFrom(clazz)));
+-
+- }
+-
+- /**
+- * Convert strings with illegal IDL identifier characters.
+- * <p>
+- * Section 5.5.7 of OBV spec.
+- */
+- private static String convertToISOLatin1 (String name) {
+-
+- int length = name.length();
+- if (length == 0) {
+- return name;
+- }
+- StringBuffer buffer = null;
+-
+- for (int i = 0; i < length; i++) {
+-
+- char c = name.charAt(i);
+-
+- if (c > 255 || IDL_IDENTIFIER_CHARS[c] == 0) {
+-
+- // We gotta convert. Have we already started?
+-
+- if (buffer == null) {
+-
+- // No, so get set up...
+-
+- buffer = new StringBuffer(name.substring(0,i));
+- }
+-
+- // Convert the character into the IDL escape syntax...
+- buffer.append(
+- "\\U" +
+- (char)ASCII_HEX[(c & 0xF000) >>> 12] +
+- (char)ASCII_HEX[(c & 0x0F00) >>> 8] +
+- (char)ASCII_HEX[(c & 0x00F0) >>> 4] +
+- (char)ASCII_HEX[(c & 0x000F)]);
+-
+- } else {
+- if (buffer != null) {
+- buffer.append(c);
+- }
+- }
+- }
+-
+- if (buffer != null) {
+- name = buffer.toString();
+- }
+-
+- return name;
+- }
+-
+- /**
+- * Convert strings with ISO Latin 1 escape sequences back to original strings.
+- * <p>
+- * Section 5.5.7 of OBV spec.
+- */
+- private static String convertFromISOLatin1 (String name) {
+-
+- int index = -1;
+- StringBuffer buf = new StringBuffer(name);
+-
+- while ((index = buf.toString().indexOf("\\U")) != -1){
+- String str = "0000" + buf.toString().substring(index+2, index+6);
+-
+- // Convert Hexadecimal
+- byte[] buffer = new byte[(str.length() - 4) / 2];
+- for (int i=4, j=0; i < str.length(); i +=2, j++) {
+- buffer[j] = (byte)((ORBUtility.hexOf(str.charAt(i)) << 4) & 0xF0);
+- buffer[j] |= (byte)((ORBUtility.hexOf(str.charAt(i+1)) << 0) & 0x0F);
+- }
+- buf = new StringBuffer(delete(buf.toString(), index, index+6));
+- buf.insert(index, (char)buffer[1]);
+- }
+-
+- return buf.toString();
+-
+-
+- }
+-
+- private static String delete(String str, int from, int to)
+- {
+- return str.substring(0, from) + str.substring(to, str.length());
+- }
+-
+- private static String replace(String target, String arg, String source)
+- {
+- int i = 0;
+- i = target.indexOf(arg);
+-
+- while(i != -1)
+- {
+- String left = target.substring(0, i);
+- String right = target.substring(i+arg.length());
+- target = new String(left+source+right);
+- i = target.indexOf(arg);
+- }
+- return target;
+- }
+-
+- /*
+- * Load a class and check that it is assignable to a given type.
+- * @param className the class name.
+- * @param remoteCodebase the codebase to use. May be null.
+- * @param loader the class loader of last resort. May be null.
+- * @param expectedType the expected type. May be null.
+- * @return the loaded class.
+- */
+- private Class loadClassOfType (String className,
+- String remoteCodebase,
+- ClassLoader loader,
+- Class expectedType,
+- ClassLoader expectedTypeClassLoader)
+- throws ClassNotFoundException {
+-
+- Class loadedClass = null;
+-
+- try {
+- //Sequence finding of the stubs according to spec
+- try{
+- //If-else is put here for speed up of J2EE.
+- //According to the OMG spec, the if clause is not dead code.
+- //It can occur if some compiler has allowed generation
+- //into org.omg.stub hierarchy for non-offending
+- //classes. This will encourage people to
+- //produce non-offending class stubs in their own hierarchy.
+- if(!PackagePrefixChecker
+- .hasOffendingPrefix(PackagePrefixChecker
+- .withoutPackagePrefix(className))){
+- loadedClass = Util.loadClass
+- (PackagePrefixChecker.withoutPackagePrefix(className),
+- remoteCodebase,
+- loader);
+- } else {
+- loadedClass = Util.loadClass
+- (className,
+- remoteCodebase,
+- loader);
+- }
+- } catch (ClassNotFoundException cnfe) {
+- loadedClass = Util.loadClass
+- (className,
+- remoteCodebase,
+- loader);
+- }
+- if (expectedType == null)
+- return loadedClass;
+- } catch (ClassNotFoundException cnfe) {
+- if (expectedType == null)
+- throw cnfe;
+- }
+-
+- // If no class was not loaded, or if the loaded class is not of the
+- // correct type, make a further attempt to load the correct class
+- // using the classloader of the expected type.
+- // _REVISIT_ Is this step necessary, or should the Util,loadClass
+- // algorithm always produce a valid class if the setup is correct?
+- // Does the OMG standard algorithm need to be changed to include
+- // this step?
+- if (loadedClass == null || !expectedType.isAssignableFrom(loadedClass)) {
+- if (expectedType.getClassLoader() != expectedTypeClassLoader)
+- throw new IllegalArgumentException("expectedTypeClassLoader not class loader of expectedType.");
+-
+- if (expectedTypeClassLoader != null)
+- loadedClass = expectedTypeClassLoader.loadClass(className);
+- else
+- loadedClass = ORBClassLoader.loadClass(className);
+- }
+-
+- return loadedClass;
+- }
+-
+- /**
+- * Checks to see if the FullValueDescription should be retrieved.
+- * @exception Throws IOException if suids do not match or if the repositoryID
+- * is not an RMIValueType
+- */
+- public static boolean useFullValueDescription(Class clazz, String repositoryID)
+- throws IOException{
+-
+- String clazzRepIDStr = createForAnyType(clazz);
+-
+- if (clazzRepIDStr.equals(repositoryID))
+- return false;
+-
+- RepositoryId_1_3 targetRepid;
+- RepositoryId_1_3 clazzRepid;
+-
+- synchronized(cache) {
+- // to avoid race condition where multiple threads could be
+- // accessing this method, and their access to the cache may
+- // be interleaved giving unexpected results
+-
+- targetRepid = cache.getId(repositoryID);
+- clazzRepid = cache.getId(clazzRepIDStr);
+- }
+-
+- if ((targetRepid.isRMIValueType()) && (clazzRepid.isRMIValueType())){
+- if (!targetRepid.getSerialVersionUID().equals(clazzRepid.getSerialVersionUID())) {
+-
+- String mssg = "Mismatched serialization UIDs : Source (Rep. ID" +
+- clazzRepid + ") = " +
+- clazzRepid.getSerialVersionUID() + " whereas Target (Rep. ID " + repositoryID +
+- ") = " + targetRepid.getSerialVersionUID();
+- throw new IOException(mssg);
+- } else {
+- return true;
+- }
+- } else {
+-
+- throw new IOException("The repository ID is not of an RMI value type (Expected ID = " + clazzRepIDStr + "; Received ID = " + repositoryID +")");
+- }
+- }
+-}
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3_1.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/RepositoryId_1_3_1.java
++++ /dev/null
+@@ -1,1065 +0,0 @@
+-/*
+- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-
+-/*
+- */
+-package com.sun.corba.se.impl.orbutil;
+-
+-import java.util.StringTokenizer;
+-import java.util.Hashtable;
+-import java.io.IOException;
+-import java.lang.reflect.Method;
+-import java.net.MalformedURLException;
+-import org.omg.CORBA.portable.ValueBase;
+-import org.omg.CORBA.portable.IDLEntity;
+-
+-//d11638 files in the same package, therefore remove their reference
+-//import com.sun.corba.se.impl.util.JDKBridge;
+-//import com.sun.corba.se.impl.util.IdentityHashtable;
+-import com.sun.corba.se.impl.util.JDKBridge;
+-import com.sun.corba.se.impl.util.Utility;
+-import com.sun.corba.se.impl.util.PackagePrefixChecker;
+-import com.sun.corba.se.impl.util.IdentityHashtable;
+-
+-import javax.rmi.CORBA.Util;
+-
+-/**
+- * Because all methods in RepositoryId are static, we have
+- * to duplicate all of this code, freezing it in its 1.3.1
+- * form for backwards compatibility.
+- *
+- * For security reasons, we can't expose enough of
+- * io/ObjectStreamClass, so it has to be duplicated in
+- * orbutil.
+- */
+-public class RepositoryId_1_3_1 {
+-
+- // Legal IDL Identifier characters (1 = legal). Note
+- // that '.' (2E) is marked as legal even though it is
+- // not legal in IDL. This allows us to treat a fully
+- // qualified Java name with '.' package separators
+- // uniformly, and is safe because that is the only
+- // legal use of '.' in a Java name.
+-
+- private static final byte[] IDL_IDENTIFIER_CHARS = {
+-
+- // 0 1 2 3 4 5 6 7 8 9 a b c d e f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 00-0f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 10-1f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0, // 20-2f
+- 1,1,1,1, 1,1,1,1, 1,1,0,0, 0,0,0,0, // 30-3f
+- 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 40-4f
+- 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,1, // 50-5f
+- 0,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 60-6f
+- 1,1,1,1, 1,1,1,1, 1,1,1,0, 0,0,0,0, // 70-7f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 80-8f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 90-9f
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // a0-af
+- 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // b0-bf
+- 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // c0-cf
+- 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // d0-df
+- 1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // e0-ef
+- 0,1,1,1, 1,1,1,0, 1,1,1,1, 1,0,0,1, // f0-ff
+- };
+-
+-
+- private static final long serialVersionUID = 123456789L;
+-
+- private static String defaultServerURL = null;
+- private static boolean useCodebaseOnly = false;
+-
+- static {
+- if (defaultServerURL == null)
+- defaultServerURL = (String)JDKBridge.getLocalCodebase();
+- useCodebaseOnly = JDKBridge.useCodebaseOnly();
+-
+- }
+-
+- private static IdentityHashtable classToRepStr = new IdentityHashtable();
+- private static IdentityHashtable classIDLToRepStr = new IdentityHashtable();
+- private static IdentityHashtable classSeqToRepStr = new IdentityHashtable();
+-
+- private static IdentityHashtable repStrToByteArray = new IdentityHashtable();
+- private static Hashtable repStrToClass = new Hashtable();
+-
+- private String repId = null;
+- private boolean isSupportedFormat = true;
+- private String typeString = null;
+- private String versionString = null;
+- private boolean isSequence = false;
+- private boolean isRMIValueType = false;
+- private boolean isIDLType = false;
+- private String completeClassName = null;
+- private String unqualifiedName = null;
+- private String definedInId = null;
+- private Class clazz = null;
+- private String suid = null, actualSuid = null;
+- private long suidLong = ObjectStreamClass_1_3_1.kDefaultUID, actualSuidLong = ObjectStreamClass_1_3_1.kDefaultUID;
+-
+- // Repository ID fragments
+- private static final String kSequenceKeyword = "seq";
+- private static final String kValuePrefix = "RMI:";
+- private static final String kIDLPrefix = "IDL:";
+- private static final String kIDLNamePrefix = "omg.org/";
+- private static final String kIDLClassnamePrefix = "org.omg.";
+- private static final String kSequencePrefix = "[";
+- private static final String kCORBAPrefix = "CORBA/";
+- private static final String kArrayPrefix = kValuePrefix + kSequencePrefix + kCORBAPrefix;
+- private static final int kValuePrefixLength = kValuePrefix.length();
+- private static final int kIDLPrefixLength = kIDLPrefix.length();
+- private static final int kSequencePrefixLength = kSequencePrefix.length();
+- private static final String kInterfaceHashCode = ":0000000000000000";
+- private static final String kInterfaceOnlyHashStr = "0000000000000000";
+- private static final String kExternalizableHashStr = "0000000000000001";
+-
+- // Value tag utility methods and constants
+- public static final int kInitialValueTag= 0x7fffff00;
+- public static final int kNoTypeInfo = 0;
+- public static final int kSingleRepTypeInfo = 0x02;
+- public static final int kPartialListTypeInfo = 0x06;
+- public static final int kChunkedMask = 0x08;
+- public static final int kPreComputed_StandardRMIUnchunked = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kSingleRepTypeInfo, false);
+- public static final int kPreComputed_CodeBaseRMIUnchunked = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kSingleRepTypeInfo, false);
+- public static final int kPreComputed_StandardRMIChunked = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kSingleRepTypeInfo, true);
+- public static final int kPreComputed_CodeBaseRMIChunked = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kSingleRepTypeInfo, true);
+-
+- public static final int kPreComputed_StandardRMIUnchunked_NoRep = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kNoTypeInfo, false);
+- public static final int kPreComputed_CodeBaseRMIUnchunked_NoRep = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kNoTypeInfo, false);
+- public static final int kPreComputed_StandardRMIChunked_NoRep = RepositoryId_1_3_1.computeValueTag(false, RepositoryId_1_3_1.kNoTypeInfo, true);
+- public static final int kPreComputed_CodeBaseRMIChunked_NoRep = RepositoryId_1_3_1.computeValueTag(true, RepositoryId_1_3_1.kNoTypeInfo, true);
+-
+- // Public, well known repository IDs
+-
+- // _REVISIT_ : A table structure with a good search routine for all of this
+- // would be more efficient and easier to maintain...
+-
+- // String
+- public static final String kWStringValueVersion = "1.0";
+- public static final String kWStringValueHash = ":"+kWStringValueVersion;
+- public static final String kWStringStubValue = "WStringValue";
+- public static final String kWStringTypeStr = "omg.org/CORBA/"+kWStringStubValue;
+- public static final String kWStringValueRepID = kIDLPrefix + kWStringTypeStr + kWStringValueHash;
+-
+- // Any
+- public static final String kAnyRepID = kIDLPrefix + "omg.org/CORBA/Any";
+-
+- // Class
+- // Anita4: convert to uppercase
+- public static final String kClassDescValueHash = ":" +
+- Long.toHexString(
+- ObjectStreamClass_1_3_1.getActualSerialVersionUID(javax.rmi.CORBA.ClassDesc.class)).toUpperCase() + ":" +
+- Long.toHexString(
+- ObjectStreamClass_1_3_1.getSerialVersionUID(javax.rmi.CORBA.ClassDesc.class)).toUpperCase();
+- public static final String kClassDescStubValue = "ClassDesc";
+- public static final String kClassDescTypeStr = "javax.rmi.CORBA."+kClassDescStubValue;
+- public static final String kClassDescValueRepID = kValuePrefix + kClassDescTypeStr + kClassDescValueHash;
+-
+- // Object
+- public static final String kObjectValueHash = ":1.0";
+- public static final String kObjectStubValue = "Object";
+-
+- // Sequence
+- public static final String kSequenceValueHash = ":1.0";
+- public static final String kPrimitiveSequenceValueHash = ":0000000000000000";
+-
+- // Serializable
+- public static final String kSerializableValueHash = ":1.0";
+- public static final String kSerializableStubValue = "Serializable";
+-
+- // Externalizable
+- public static final String kExternalizableValueHash = ":1.0";
+- public static final String kExternalizableStubValue = "Externalizable";
+-
+- // Remote (The empty string is used for java.rmi.Remote)
+- public static final String kRemoteValueHash = "";
+- public static final String kRemoteStubValue = "";
+- public static final String kRemoteTypeStr = "";
+- public static final String kRemoteValueRepID = "";
+-
+- private static final Hashtable kSpecialArrayTypeStrings = new Hashtable();
+-
+- static {
+- kSpecialArrayTypeStrings.put("CORBA.WStringValue", new StringBuffer(java.lang.String.class.getName()));
+- kSpecialArrayTypeStrings.put("javax.rmi.CORBA.ClassDesc", new StringBuffer(java.lang.Class.class.getName()));
+- kSpecialArrayTypeStrings.put("CORBA.Object", new StringBuffer(java.rmi.Remote.class.getName()));
+-
+- }
+-
+- private static final Hashtable kSpecialCasesRepIDs = new Hashtable();
+-
+- static {
+- kSpecialCasesRepIDs.put(java.lang.String.class, kWStringValueRepID);
+- kSpecialCasesRepIDs.put(java.lang.Class.class, kClassDescValueRepID);
+- kSpecialCasesRepIDs.put(java.rmi.Remote.class, kRemoteValueRepID);
+- }
+-
+- private static final Hashtable kSpecialCasesStubValues = new Hashtable();
+-
+- static {
+- kSpecialCasesStubValues.put(java.lang.String.class, kWStringStubValue);
+- kSpecialCasesStubValues.put(java.lang.Class.class, kClassDescStubValue);
+- kSpecialCasesStubValues.put(java.lang.Object.class, kObjectStubValue);
+- kSpecialCasesStubValues.put(java.io.Serializable.class, kSerializableStubValue);
+- kSpecialCasesStubValues.put(java.io.Externalizable.class, kExternalizableStubValue);
+- kSpecialCasesStubValues.put(java.rmi.Remote.class, kRemoteStubValue);
+- }
+-
+-
+- private static final Hashtable kSpecialCasesVersions = new Hashtable();
+-
+- static {
+- kSpecialCasesVersions.put(java.lang.String.class, kWStringValueHash);
+- kSpecialCasesVersions.put(java.lang.Class.class, kClassDescValueHash);
+- kSpecialCasesVersions.put(java.lang.Object.class, kObjectValueHash);
+- kSpecialCasesVersions.put(java.io.Serializable.class, kSerializableValueHash);
+- kSpecialCasesVersions.put(java.io.Externalizable.class, kExternalizableValueHash);
+- kSpecialCasesVersions.put(java.rmi.Remote.class, kRemoteValueHash);
+- }
+-
+- private static final Hashtable kSpecialCasesClasses = new Hashtable();
+-
+- static {
+- kSpecialCasesClasses.put(kWStringTypeStr, java.lang.String.class);
+- kSpecialCasesClasses.put(kClassDescTypeStr, java.lang.Class.class);
+- kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class);
+-
+- kSpecialCasesClasses.put("org.omg.CORBA.WStringValue", java.lang.String.class);
+- kSpecialCasesClasses.put("javax.rmi.CORBA.ClassDesc", java.lang.Class.class);
+- //kSpecialCasesClasses.put(kRemoteTypeStr, java.rmi.Remote.class);
+- }
+-
+- private static final Hashtable kSpecialCasesArrayPrefix = new Hashtable();
+-
+- static {
+- kSpecialCasesArrayPrefix.put(java.lang.String.class, kValuePrefix + kSequencePrefix + kCORBAPrefix);
+- kSpecialCasesArrayPrefix.put(java.lang.Class.class, kValuePrefix + kSequencePrefix + "javax/rmi/CORBA/");
+- kSpecialCasesArrayPrefix.put(java.lang.Object.class, kValuePrefix + kSequencePrefix + "java/lang/");
+- kSpecialCasesArrayPrefix.put(java.io.Serializable.class, kValuePrefix + kSequencePrefix + "java/io/");
+- kSpecialCasesArrayPrefix.put(java.io.Externalizable.class, kValuePrefix + kSequencePrefix + "java/io/");
+- kSpecialCasesArrayPrefix.put(java.rmi.Remote.class, kValuePrefix + kSequencePrefix + kCORBAPrefix);
+- }
+-
+- private static final Hashtable kSpecialPrimitives = new Hashtable();
+-
+- static {
+- kSpecialPrimitives.put("int","long");
+- kSpecialPrimitives.put("long","longlong");
+- kSpecialPrimitives.put("byte","octet");
+- }
+-
+- /**
+- * Used to convert ascii to hex.
+- */
+- private static final byte ASCII_HEX[] = {
+- (byte)'0',
+- (byte)'1',
+- (byte)'2',
+- (byte)'3',
+- (byte)'4',
+- (byte)'5',
+- (byte)'6',
+- (byte)'7',
+- (byte)'8',
+- (byte)'9',
+- (byte)'A',
+- (byte)'B',
+- (byte)'C',
+- (byte)'D',
+- (byte)'E',
+- (byte)'F',
+- };
+-
+-
+- // bug fix for 4328952; to eliminate possibility of overriding this
+- // in a subclass.
+- public static final RepositoryIdCache_1_3_1 cache = new RepositoryIdCache_1_3_1();
+-
+- // Interface Rep ID Strings
+- public static final String kjava_rmi_Remote = createForAnyType(java.rmi.Remote.class);
+- public static final String korg_omg_CORBA_Object = createForAnyType(org.omg.CORBA.Object.class);
+-
+- // Dummy arguments for getIdFromHelper method
+- public static final Class kNoParamTypes[] ={};
+- public static final Object kNoArgs[] = {};
+-
+-
+- // To create a RepositoryID, use code similar to the following:
+- // RepositoryId.cache.getId( id );
+-
+- RepositoryId_1_3_1(){}
+-
+- RepositoryId_1_3_1(String aRepId){
+- init(aRepId);
+- }
+-
+- RepositoryId_1_3_1 init(String aRepId){
+-
+- this.repId = aRepId;
+-
+- // Special case for remote
+- if (aRepId.length() == 0) {
+- clazz = java.rmi.Remote.class;
+- typeString = "";
+- isRMIValueType = true;
+- suid = kInterfaceOnlyHashStr;
+- return this;
+- }
+- else if (aRepId.equals(kWStringValueRepID)) {
+- clazz = java.lang.String.class;
+- typeString = kWStringTypeStr;
+- isIDLType = true;
+- // fix where Attempting to obtain a FullValueDescription
+- // for an RMI value type with a String field causes an exception.
+- completeClassName = "java.lang.String";
+- versionString = kWStringValueVersion;
+- return this;
+- }
+- else {
+-
+- String repId = convertFromISOLatin1(aRepId);
+-
+- versionString = repId.substring(repId.indexOf(':', repId.indexOf(':')+1));
+- if (repId.startsWith(kIDLPrefix)) {
+- typeString =
+- repId.substring(kIDLPrefixLength, repId.indexOf(':', kIDLPrefixLength));
+- isIDLType = true;
+- if (typeString.startsWith(kIDLNamePrefix))
+- completeClassName = kIDLClassnamePrefix +
+- typeString.substring(kIDLNamePrefix.length()).replace('/','.');
+- else completeClassName = typeString.replace('/','.');
+-
+- }
+- else if (repId.startsWith(kValuePrefix)) {
+- typeString =
+- repId.substring(kValuePrefixLength, repId.indexOf(':', kValuePrefixLength));
+- isRMIValueType = true;
+-
+- if (versionString.indexOf('.') == -1) {
+- actualSuid = versionString.substring(1);
+- suid = actualSuid; // default if not explicitly specified
+-
+- if (actualSuid.indexOf(':') != -1){
+- // we have a declared hash also
+- int pos = actualSuid.indexOf(':')+1;
+- // actualSuid = suid.substring(pos);
+- // suid = suid.substring(0, pos-1);
+- suid = actualSuid.substring(pos);
+- actualSuid = actualSuid.substring(0, pos-1);
+- }
+-
+- }
+- else {
+- // _REVISIT_ : Special case version failure ?
+- }
+- }
+- else isSupportedFormat = false;
+-
+- if (typeString.startsWith(kSequencePrefix)) {
+- isSequence = true;
+- }
+-
+-
+- return this;
+- }
+- }
+-
+- public final String getUnqualifiedName() {
+- if (unqualifiedName == null){
+- String className = getClassName();
+- int index = className.lastIndexOf('.');
+- if (index == -1){
+- unqualifiedName = className;
+- definedInId = "IDL::1.0";
+- }
+- else {
+- unqualifiedName = className.substring(index);
+- definedInId = "IDL:" + className.substring(0, index).replace('.','/') + ":1.0";
+- }
+- }
+-
+- return unqualifiedName;
+- }
+-
+- public final String getDefinedInId() {
+- if (definedInId == null){
+- getUnqualifiedName();
+- }
+-
+- return definedInId;
+- }
+-
+- public final String getTypeString() {
+- return typeString;
+- }
+-
+- public final String getVersionString() {
+- return versionString;
+- }
+-
+- public final String getSerialVersionUID() {
+- return suid;
+- }
+-
+- public final String getActualSerialVersionUID() {
+- return actualSuid;
+- }
+- public final long getSerialVersionUIDAsLong() {
+- return suidLong;
+- }
+-
+- public final long getActualSerialVersionUIDAsLong() {
+- return actualSuidLong;
+- }
+-
+- public final boolean isRMIValueType() {
+- return isRMIValueType;
+- }
+-
+- public final boolean isIDLType() {
+- return isIDLType;
+- }
+-
+- public final String getRepositoryId() {
+- return repId;
+- }
+-
+- public static byte[] getByteArray(String repStr) {
+- synchronized (repStrToByteArray){
+- return (byte[]) repStrToByteArray.get(repStr);
+- }
+- }
+-
+- public static void setByteArray(String repStr, byte[] repStrBytes) {
+- synchronized (repStrToByteArray){
+- repStrToByteArray.put(repStr, repStrBytes);
+- }
+- }
+-
+- public final boolean isSequence() {
+- return isSequence;
+- }
+-
+- public final boolean isSupportedFormat() {
+- return isSupportedFormat;
+- }
+-
+-
+- // This method will return the classname from the typestring OR if the classname turns out to be
+- // a special class "pseudo" name, then the matching real classname is returned.
+- public final String getClassName() {
+-
+- if (isRMIValueType)
+- return typeString;
+- else if (isIDLType)
+- return completeClassName;
+- else return null;
+-
+- }
+-
+- // This method calls getClazzFromType() and falls back to the repStrToClass
+- // cache if no class was found. It's used where any class matching the
+- // given repid is an acceptable result.
+- public final Class getAnyClassFromType() throws ClassNotFoundException {
+- try {
+- return getClassFromType();
+- } catch (ClassNotFoundException cnfe) {
+- Class clz = (Class)repStrToClass.get(repId);
+- if (clz != null)
+- return clz;
+- else
+- throw cnfe;
+- }
+- }
+-
+- public final Class getClassFromType()
+- throws ClassNotFoundException {
+- if (clazz != null)
+- return clazz;
+-
+- Class specialCase = (Class)kSpecialCasesClasses.get(getClassName());
+-
+- if (specialCase != null){
+- clazz = specialCase;
+- return specialCase;
+- }
+- else
+- {
+- try{
+- return Util.loadClass(getClassName(), null, null);
+- }
+- catch(ClassNotFoundException cnfe){
+- if (defaultServerURL != null) {
+- try{
+- return getClassFromType(defaultServerURL);
+- }
+- catch(MalformedURLException mue){
+- throw cnfe;
+- }
+- }
+- else throw cnfe;
+- }
+- }
+-
+- }
+-
+- public final Class getClassFromType(Class expectedType, String codebase)
+- throws ClassNotFoundException {
+- if (clazz != null)
+- return clazz;
+-
+- Class specialCase = (Class)kSpecialCasesClasses.get(getClassName());
+-
+- if (specialCase != null){
+- clazz = specialCase;
+- return specialCase;
+- } else {
+- ClassLoader expectedTypeClassLoader = (expectedType == null ? null : expectedType.getClassLoader());
+- return loadClassOfType(getClassName(),
+- codebase,
+- expectedTypeClassLoader,
+- expectedType,
+- expectedTypeClassLoader);
+- }
+-
+- }
+-
+- public final Class getClassFromType(String url)
+- throws ClassNotFoundException, MalformedURLException {
+- return Util.loadClass(getClassName(), url, null);
+- }
+-
+- public final String toString() {
+- return repId;
+- }
+-
+- /**
+- * Checks to see if the FullValueDescription should be retrieved.
+- * @exception Throws IOException if suids do not match or if the repositoryID
+- * is not an RMIValueType
+- */
+- public static boolean useFullValueDescription(Class clazz, String repositoryID)
+- throws IOException{
+-
+- String clazzRepIDStr = createForAnyType(clazz);
+-
+- if (clazzRepIDStr.equals(repositoryID))
+- return false;
+-
+- RepositoryId_1_3_1 targetRepid;
+- RepositoryId_1_3_1 clazzRepid;
+-
+- synchronized(cache) {
+- // to avoid race condition where multiple threads could be
+- // accessing this method, and their access to the cache may
+- // be interleaved giving unexpected results
+-
+- targetRepid = cache.getId(repositoryID);
+- clazzRepid = cache.getId(clazzRepIDStr);
+- }
+- //ObjectStreamClass osc = ObjectStreamClass.lookup(clazz);
+-
+- if ((targetRepid.isRMIValueType()) && (clazzRepid.isRMIValueType())){
+- if (!targetRepid.getSerialVersionUID().equals(clazzRepid.getSerialVersionUID())) {
+-
+- String mssg = "Mismatched serialization UIDs : Source (Rep. ID" +
+- clazzRepid + ") = " +
+- clazzRepid.getSerialVersionUID() + " whereas Target (Rep. ID " + repositoryID +
+- ") = " + targetRepid.getSerialVersionUID();
+- //com.sun.corba.se.impl.io.ValueUtility.log("RepositoryId",mssg);
+- throw new IOException(mssg);
+- }
+- else {
+- return true;
+- }
+- }
+- else {
+-
+- throw new IOException("The repository ID is not of an RMI value type (Expected ID = " + clazzRepIDStr + "; Received ID = " + repositoryID +")");
+- }
+- }
+-
+- private static String createHashString(java.io.Serializable ser) {
+-
+- return createHashString(ser.getClass());
+- }
+-
+- private static String createHashString(java.lang.Class clazz) {
+-
+- if (clazz.isInterface() || !java.io.Serializable.class.isAssignableFrom(clazz))
+- return kInterfaceHashCode;
+-
+- //ObjectStreamClass osc = ObjectStreamClass.lookup(clazz);
+-
+- long actualLong = ObjectStreamClass_1_3_1.getActualSerialVersionUID(clazz);
+- String hash = null;
+- if (actualLong == 0)
+- hash = kInterfaceOnlyHashStr;
+- else if (actualLong == 1)
+- hash = kExternalizableHashStr;
+- else
+- hash = Long.toHexString(actualLong).toUpperCase();
+- while(hash.length() < 16){
+- hash = "0" + hash;
+- }
+-
+- long declaredLong = ObjectStreamClass_1_3_1.getSerialVersionUID(clazz);
+- String declared = null;
+- if (declaredLong == 0)
+- declared = kInterfaceOnlyHashStr;
+- else if (declaredLong == 1)
+- declared = kExternalizableHashStr;
+- else
+- declared = Long.toHexString(declaredLong).toUpperCase();
+- while (declared.length() < 16){
+- declared = "0" + declared;
+- }
+- hash = hash + ":" + declared;
+-
+- return ":" + hash;
+- }
+-
+- /**
+- * Creates a repository ID for a sequence. This is for expert users only as
+- * this method assumes the object passed is an array. If passed an object
+- * that is not an array, it will produce a rep id for a sequence of zero
+- * length. This would be an error.
+- * @param ser The Java object to create a repository ID for
+- **/
+- public static String createSequenceRepID(java.lang.Object ser){
+- return createSequenceRepID(ser.getClass());
+- }
+-
+- /**
+- * Creates a repository ID for a sequence. This is for expert users only as
+- * this method assumes the object passed is an array. If passed an object
+- * that is not an array, it will produce a malformed rep id.
+- * @param clazz The Java class to create a repository ID for
+- **/
+- public static String createSequenceRepID(java.lang.Class clazz){
+- synchronized (classSeqToRepStr){
+-
+- String repid = (String)classSeqToRepStr.get(clazz);
+- if (repid != null)
+- return repid;
+-
+- Class originalClazz = clazz;
+-
+- Class type = null;
+- int numOfDims = 0;
+-
+- while ((type = clazz.getComponentType()) != null) {
+- numOfDims++;
+- clazz = type;
+- }
+-
+- if (clazz.isPrimitive())
+- repid = kValuePrefix + originalClazz.getName() + kPrimitiveSequenceValueHash;
+- else {
+- StringBuffer buf = new StringBuffer();
+- buf.append(kValuePrefix);
+- while(numOfDims-- > 0) {
+- buf.append("[");
+- }
+- buf.append("L");
+- buf.append(convertToISOLatin1(clazz.getName()));
+- buf.append(";");
+- buf.append(createHashString(clazz));
+- repid = buf.toString();
+- }
+- classSeqToRepStr.put(originalClazz,repid);
+- return repid;
+- }
+-
+- }
+-
+-
+- public static String createForSpecialCase(java.lang.Class clazz){
+- if (clazz.isArray()){
+- return createSequenceRepID(clazz);
+- }
+- else {
+- return (String)kSpecialCasesRepIDs.get(clazz);
+- }
+- }
+-
+- public static String createForSpecialCase(java.io.Serializable ser){
+- Class clazz = ser.getClass();
+- if (clazz.isArray()){
+- return createSequenceRepID(ser);
+- }
+- else
+- return createForSpecialCase(clazz);
+- }
+-
+- /**
+- * Creates a repository ID for a normal Java Type.
+- * @param ser The Java object to create a repository ID for
+- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the
+- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
+- **/
+- public static String createForJavaType(java.io.Serializable ser)
+- throws com.sun.corba.se.impl.io.TypeMismatchException
+- {
+- synchronized (classToRepStr) {
+- String repid = createForSpecialCase(ser);
+- if (repid != null)
+- return repid;
+- Class clazz = ser.getClass();
+- repid = (String)classToRepStr.get(clazz);
+-
+- if (repid != null)
+- return repid;
+-
+- repid = kValuePrefix + convertToISOLatin1(clazz.getName()) +
+- createHashString(clazz);
+-
+- classToRepStr.put(clazz, repid);
+- repStrToClass.put(repid, clazz);
+- return repid;
+- }
+- }
+-
+- /**
+- * Creates a repository ID for a normal Java Type.
+- * @param clz The Java class to create a repository ID for
+- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser implements the
+- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
+- **/
+- public static String createForJavaType(Class clz)
+- throws com.sun.corba.se.impl.io.TypeMismatchException
+- {
+- synchronized (classToRepStr){
+- String repid = createForSpecialCase(clz);
+- if (repid != null)
+- return repid;
+-
+- repid = (String)classToRepStr.get(clz);
+- if (repid != null)
+- return repid;
+-
+- repid = kValuePrefix + convertToISOLatin1(clz.getName()) +
+- createHashString(clz);
+-
+- classToRepStr.put(clz, repid);
+- repStrToClass.put(repid, clz);
+- return repid;
+- }
+- }
+-
+- /**
+- * Creates a repository ID for an IDL Java Type.
+- * @param ser The IDL Value object to create a repository ID for
+- * @param major The major version number
+- * @param minor The minor version number
+- * @exception com.sun.corba.se.impl.io.TypeMismatchException if ser does not implement the
+- * org.omg.CORBA.portable.IDLEntity interface which indicates it is an IDL Value type.
+- **/
+- public static String createForIDLType(Class ser, int major, int minor)
+- throws com.sun.corba.se.impl.io.TypeMismatchException
+- {
+- synchronized (classIDLToRepStr){
+- String repid = (String)classIDLToRepStr.get(ser);
+- if (repid != null)
+- return repid;
+-
+- repid = kIDLPrefix + convertToISOLatin1(ser.getName()).replace('.','/') +
+- ":" + major + "." + minor;
+- classIDLToRepStr.put(ser, repid);
+- return repid;
+- }
+- }
+-
+- private static String getIdFromHelper(Class clazz){
+- try {
+- Class helperClazz = Utility.loadClassForClass(clazz.getName()+"Helper", null,
+- clazz.getClassLoader(), clazz, clazz.getClassLoader());
+- Method idMethod = helperClazz.getDeclaredMethod("id", kNoParamTypes);
+- return (String)idMethod.invoke(null, kNoArgs);
+- }
+- catch(java.lang.ClassNotFoundException cnfe)
+- {
+- throw new org.omg.CORBA.MARSHAL(cnfe.toString());
+- }
+- catch(java.lang.NoSuchMethodException nsme)
+- {
+- throw new org.omg.CORBA.MARSHAL(nsme.toString());
+- }
+- catch(java.lang.reflect.InvocationTargetException ite)
+- {
+- throw new org.omg.CORBA.MARSHAL(ite.toString());
+- }
+- catch(java.lang.IllegalAccessException iae)
+- {
+- throw new org.omg.CORBA.MARSHAL(iae.toString());
+- }
+- }
+-
+- /**
+- * Createa a repository ID for the type if it is either a java type
+- * or an IDL type.
+- * @param type The type to create rep. id for
+- * @return The rep. id.
+- **/
+- public static String createForAnyType(Class type) {
+- try{
+- if (type.isArray())
+- return createSequenceRepID(type);
+- else if (IDLEntity.class.isAssignableFrom(type))
+- {
+- try{
+- return getIdFromHelper(type);
+- }
+- catch(Throwable t) {
+- return createForIDLType(type, 1, 0);
+- }
+- }
+- else return createForJavaType(type);
+- }
+- catch(com.sun.corba.se.impl.io.TypeMismatchException e){
+- return null;
+- }
+-
+- }
+-
+- public static boolean isAbstractBase(Class clazz) {
+- return (clazz.isInterface() &&
+- IDLEntity.class.isAssignableFrom(clazz) &&
+- (!ValueBase.class.isAssignableFrom(clazz)) &&
+- (!org.omg.CORBA.Object.class.isAssignableFrom(clazz)));
+-
+- }
+-
+- public static boolean isAnyRequired(Class clazz) {
+- return ((clazz == java.lang.Object.class) ||
+- (clazz == java.io.Serializable.class) ||
+- (clazz == java.io.Externalizable.class));
+- }
+-
+- public static long fromHex(String hexNumber) {
+- if (hexNumber.startsWith("0x"))
+- return Long.valueOf(hexNumber.substring(2), 16).longValue();
+- else return Long.valueOf(hexNumber, 16).longValue();
+- }
+-
+- /**
+- * Convert strings with illegal IDL identifier characters.
+- * <p>
+- * Section 5.5.7 of OBV spec.
+- */
+- private static String convertToISOLatin1 (String name) {
+-
+- int length = name.length();
+- if (length == 0) {
+- return name;
+- }
+- StringBuffer buffer = null;
+-
+- for (int i = 0; i < length; i++) {
+-
+- char c = name.charAt(i);
+-
+- if (c > 255 || IDL_IDENTIFIER_CHARS[c] == 0) {
+-
+- // We gotta convert. Have we already started?
+-
+- if (buffer == null) {
+-
+- // No, so get set up...
+-
+- buffer = new StringBuffer(name.substring(0,i));
+- }
+-
+- // Convert the character into the IDL escape syntax...
+- buffer.append(
+- "\\U" +
+- (char)ASCII_HEX[(c & 0xF000) >>> 12] +
+- (char)ASCII_HEX[(c & 0x0F00) >>> 8] +
+- (char)ASCII_HEX[(c & 0x00F0) >>> 4] +
+- (char)ASCII_HEX[(c & 0x000F)]);
+-
+- } else {
+- if (buffer != null) {
+- buffer.append(c);
+- }
+- }
+- }
+-
+- if (buffer != null) {
+- name = buffer.toString();
+- }
+-
+- return name;
+- }
+-
+- /**
+- * Convert strings with ISO Latin 1 escape sequences back to original strings.
+- * <p>
+- * Section 5.5.7 of OBV spec.
+- */
+- private static String convertFromISOLatin1 (String name) {
+-
+- int index = -1;
+- StringBuffer buf = new StringBuffer(name);
+-
+- while ((index = buf.toString().indexOf("\\U")) != -1){
+- String str = "0000" + buf.toString().substring(index+2, index+6);
+-
+- // Convert Hexadecimal
+- byte[] buffer = new byte[(str.length() - 4) / 2];
+- for (int i=4, j=0; i < str.length(); i +=2, j++) {
+- buffer[j] = (byte)((ORBUtility.hexOf(str.charAt(i)) << 4) & 0xF0);
+- buffer[j] |= (byte)((ORBUtility.hexOf(str.charAt(i+1)) << 0) & 0x0F);
+- }
+- buf = new StringBuffer(delete(buf.toString(), index, index+6));
+- buf.insert(index, (char)buffer[1]);
+- }
+-
+- return buf.toString();
+-
+-
+- }
+-
+- private static String delete(String str, int from, int to)
+- {
+- return str.substring(0, from) + str.substring(to, str.length());
+- }
+-
+- private static String replace(String target, String arg, String source)
+- {
+- int i = 0;
+- i = target.indexOf(arg);
+-
+- while(i != -1)
+- {
+- String left = target.substring(0, i);
+- String right = target.substring(i+arg.length());
+- target = new String(left+source+right);
+- i = target.indexOf(arg);
+- }
+- return target;
+- }
+-
+- public static int computeValueTag(boolean codeBasePresent, int typeInfo, boolean chunkedEncoding){
+- int value_tag = kInitialValueTag;
+-
+- if (codeBasePresent)
+- value_tag = value_tag | 0x00000001;
+-
+- value_tag = value_tag | typeInfo;
+-
+- if (chunkedEncoding)
+- value_tag = value_tag | kChunkedMask;
+-
+- return value_tag;
+- }
+-
+- public static boolean isCodeBasePresent(int value_tag){
+- return ((value_tag & 0x00000001) == 1);
+- }
+-
+- public static int getTypeInfo(int value_tag){
+- return (value_tag & 0x00000006);
+- }
+-
+- public static boolean isChunkedEncoding(int value_tag){
+- return ((value_tag & kChunkedMask) != 0);
+- }
+-
+- public static String getServerURL(){
+- return defaultServerURL;
+- }
+-
+- /*
+- * Load a class and check that it is assignable to a given type.
+- * @param className the class name.
+- * @param remoteCodebase the codebase to use. May be null.
+- * @param loader the class loader of last resort. May be null.
+- * @param expectedType the expected type. May be null.
+- * @return the loaded class.
+- */
+- private Class loadClassOfType (String className,
+- String remoteCodebase,
+- ClassLoader loader,
+- Class expectedType,
+- ClassLoader expectedTypeClassLoader)
+- throws ClassNotFoundException {
+-
+- Class loadedClass = null;
+-
+- try {
+- //Sequence finding of the stubs according to spec
+- try{
+- //If-else is put here for speed up of J2EE.
+- //According to the OMG spec, the if clause is not dead code.
+- //It can occur if some compiler has allowed generation
+- //into org.omg.stub hierarchy for non-offending
+- //classes. This will encourage people to
+- //produce non-offending class stubs in their own hierarchy.
+- if(!PackagePrefixChecker
+- .hasOffendingPrefix(PackagePrefixChecker
+- .withoutPackagePrefix(className))){
+- loadedClass = Util.loadClass
+- (PackagePrefixChecker.withoutPackagePrefix(className),
+- remoteCodebase,
+- loader);
+- } else {
+- loadedClass = Util.loadClass
+- (className,
+- remoteCodebase,
+- loader);
+- }
+- } catch (ClassNotFoundException cnfe) {
+- loadedClass = Util.loadClass
+- (className,
+- remoteCodebase,
+- loader);
+- }
+- if (expectedType == null)
+- return loadedClass;
+- } catch (ClassNotFoundException cnfe) {
+- if (expectedType == null)
+- throw cnfe;
+- }
+-
+- // If no class was not loaded, or if the loaded class is not of the
+- // correct type, make a further attempt to load the correct class
+- // using the classloader of the expected type.
+- // _REVISIT_ Is this step necessary, or should the Util,loadClass
+- // algorithm always produce a valid class if the setup is correct?
+- // Does the OMG standard algorithm need to be changed to include
+- // this step?
+- if (loadedClass == null || !expectedType.isAssignableFrom(loadedClass)) {
+- if (expectedType.getClassLoader() != expectedTypeClassLoader)
+- throw new IllegalArgumentException("expectedTypeClassLoader not class loader of expectedType.");
+-
+- if (expectedTypeClassLoader != null)
+- loadedClass = expectedTypeClassLoader.loadClass(className);
+- else
+- loadedClass = Class.forName(className);
+- }
+-
+- return loadedClass;
+- }
+-}
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3.java b/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3.java
++++ /dev/null
+@@ -1,251 +0,0 @@
+-/*
+- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-/*
+- * Licensed Materials - Property of IBM
+- * RMI-IIOP v1.0
+- * Copyright IBM Corp. 1998 1999 All Rights Reserved
+- *
+- */
+-
+-package com.sun.corba.se.impl.orbutil;
+-
+-import javax.rmi.CORBA.Util;
+-import javax.rmi.PortableRemoteObject;
+-
+-import java.util.Hashtable;
+-import java.util.Stack;
+-import java.io.IOException;
+-import java.util.EmptyStackException;
+-
+-import com.sun.corba.se.impl.util.Utility;
+-import com.sun.corba.se.impl.io.IIOPInputStream;
+-import com.sun.corba.se.impl.io.IIOPOutputStream;
+-import com.sun.corba.se.impl.util.RepositoryId;
+-import com.sun.corba.se.impl.util.Utility;
+-
+-import org.omg.CORBA.TCKind;
+-import org.omg.CORBA.MARSHAL;
+-import org.omg.CORBA.CompletionStatus;
+-import org.omg.CORBA.portable.IndirectionException;
+-import com.sun.org.omg.SendingContext.CodeBase;
+-
+-import java.security.AccessController;
+-import java.security.PrivilegedAction;
+-
+-/**
+- * This class overrides behavior of our current ValueHandlerImpl to
+- * provide backwards compatibility with JDK 1.3.0.
+- */
+-public class ValueHandlerImpl_1_3 extends com.sun.corba.se.impl.io.ValueHandlerImpl {
+-
+- public ValueHandlerImpl_1_3(){
+- super();
+- }
+-
+- public ValueHandlerImpl_1_3(boolean isInputStream) {
+- super(isInputStream);
+- }
+-
+- /**
+- * Writes the value to the stream using java semantics.
+- * @param out The stream to write the value to
+- * @param value The value to be written to the stream
+- **/
+- public void writeValue(org.omg.CORBA.portable.OutputStream _out, java.io.Serializable value) {
+- super.writeValue(_out, value);
+- }
+-
+- /**
+- * Reads a value from the stream using java semantics.
+- * @param in The stream to read the value from
+- * @param clazz The type of the value to be read in
+- * @param sender The sending context runtime
+- **/
+- public java.io.Serializable readValue(org.omg.CORBA.portable.InputStream _in,
+- int offset,
+- java.lang.Class clazz,
+- String repositoryID,
+- org.omg.SendingContext.RunTime _sender)
+- {
+- return super.readValue(_in, offset, clazz, repositoryID, _sender);
+- }
+-
+- /**
+- * Returns the repository ID for the given RMI value Class.
+- * @param clz The class to return a repository ID for.
+- * @return the repository ID of the Class.
+- **/
+- public java.lang.String getRMIRepositoryID(java.lang.Class clz) {
+- return RepositoryId_1_3.createForJavaType(clz);
+- }
+-
+- /**
+- * Indicates whether the given Class performs custom or
+- * default marshaling.
+- * @param clz The class to test for custom marshaling.
+- * @return True if the class performs custom marshaling, false
+- * if it does not.
+- **/
+- public boolean isCustomMarshaled(java.lang.Class clz) {
+- return super.isCustomMarshaled(clz);
+- }
+-
+- /**
+- * Returns the CodeBase for this ValueHandler. This is used by
+- * the ORB runtime. The server sends the service context containing
+- * the IOR for this CodeBase on the first GIOP reply. The clients
+- * do the same on the first GIOP request.
+- * @return the SendingContext.CodeBase of this ValueHandler.
+- **/
+- public org.omg.SendingContext.RunTime getRunTimeCodeBase() {
+- return super.getRunTimeCodeBase();
+- }
+-
+- /**
+- * If the value contains a writeReplace method then the result
+- * is returned. Otherwise, the value itself is returned.
+- * @return the true value to marshal on the wire.
+- **/
+- public java.io.Serializable writeReplace(java.io.Serializable value) {
+- return super.writeReplace(value);
+- }
+-
+- // methods supported for backward compatability so that the appropriate
+- // Rep-id calculations take place based on the ORB version
+-
+- /**
+- * Returns a boolean of whether or not RepositoryId indicates
+- * FullValueDescriptor.
+- * used for backward compatability
+- */
+-
+- public boolean useFullValueDescription(Class clazz, String repositoryID)
+- throws IOException
+-
+- {
+- return RepositoryId_1_3.useFullValueDescription(clazz, repositoryID);
+- }
+-
+- public String getClassName(String id)
+- {
+- RepositoryId_1_3 repID = RepositoryId_1_3.cache.getId(id);
+- return repID.getClassName();
+- }
+-
+- public Class getClassFromType(String id)
+- throws ClassNotFoundException
+- {
+- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id);
+- return repId.getClassFromType();
+- }
+-
+- public Class getAnyClassFromType(String id)
+- throws ClassNotFoundException
+- {
+- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id);
+- return repId.getAnyClassFromType();
+- }
+-
+- public String createForAnyType(Class cl)
+- {
+- return RepositoryId_1_3.createForAnyType(cl);
+- }
+-
+- public String getDefinedInId(String id)
+- {
+- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id);
+- return repId.getDefinedInId();
+- }
+-
+- public String getUnqualifiedName(String id)
+- {
+- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id);
+- return repId.getUnqualifiedName();
+- }
+-
+- public String getSerialVersionUID(String id)
+- {
+- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id);
+- return repId.getSerialVersionUID();
+- }
+-
+- public boolean isAbstractBase(Class clazz)
+- {
+- return RepositoryId_1_3.isAbstractBase(clazz);
+- }
+-
+- public boolean isSequence(String id)
+- {
+- RepositoryId_1_3 repId = RepositoryId_1_3.cache.getId(id);
+- return repId.isSequence();
+- }
+-
+- /**
+- * Preserves the incorrect 1.3 behavior which truncates Java chars in
+- * arrays to 8-bit CORBA chars. Bug 4367783. This enables us to
+- * continue interoperating with our legacy ORBs. If this goes into
+- * Ladybird, then Ladybird and Kestrel will interoperate as long as
+- * people don't use chars greater than 8-bits.
+- */
+- protected void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream out,
+- char[] array,
+- int offset,
+- int length)
+- {
+- out.write_char_array(array, offset, length);
+- }
+-
+- /**
+- * Preserves the incorrect 1.3 behavior which truncates Java chars in
+- * arrays to 8-bit CORBA chars. Bug 4367783. This enables us to
+- * continue interoperating with our legacy ORBs. If this goes into
+- * Ladybird, then Ladybird and Kestrel will interoperate as long as
+- * people don't use chars greater than 8-bits.
+- */
+- protected void readCharArray(org.omg.CORBA_2_3.portable.InputStream in,
+- char[] array,
+- int offset,
+- int length)
+- {
+- in.read_char_array(array, offset, length);
+- }
+-
+- protected final String getOutputStreamClassName() {
+- return "com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3";
+- }
+-
+- protected final String getInputStreamClassName() {
+- return "com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3";
+- }
+-
+- /**
+- * Our JDK 1.3 and JDK 1.3.1 behavior subclasses override this.
+- * The correct behavior is for a Java char to map to a CORBA wchar,
+- * but our older code mapped it to a CORBA char.
+- */
+- protected TCKind getJavaCharTCKind() {
+- return TCKind.tk_char;
+- }
+-}
+diff --git a/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3_1.java b/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3_1.java
+deleted file mode 100644
+--- corba/src/share/classes/com/sun/corba/se/impl/orbutil/ValueHandlerImpl_1_3_1.java
++++ /dev/null
+@@ -1,77 +0,0 @@
+-/*
+- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+- *
+- * This code is free software; you can redistribute it and/or modify it
+- * under the terms of the GNU General Public License version 2 only, as
+- * published by the Free Software Foundation. Oracle designates this
+- * particular file as subject to the "Classpath" exception as provided
+- * by Oracle in the LICENSE file that accompanied this code.
+- *
+- * This code 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
+- * version 2 for more details (a copy is included in the LICENSE file that
+- * accompanied this code).
+- *
+- * You should have received a copy of the GNU General Public License version
+- * 2 along with this work; if not, write to the Free Software Foundation,
+- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+- *
+- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+- * or visit www.oracle.com if you need additional information or have any
+- * questions.
+- */
+-package com.sun.corba.se.impl.orbutil;
+-
+-import org.omg.CORBA.TCKind;
+-
+-/**
+- * This class overrides behavior of our current ValueHandlerImpl to
+- * provide backwards compatibility with JDK 1.3.1.
+- */
+-public class ValueHandlerImpl_1_3_1
+- extends com.sun.corba.se.impl.io.ValueHandlerImpl
+-{
+- public ValueHandlerImpl_1_3_1() {}
+-
+- public ValueHandlerImpl_1_3_1(boolean isInputStream) {
+- super(isInputStream);
+- }
+-
+- /**
+- * Our JDK 1.3 and JDK 1.3.1 behavior subclasses override this.
+- * The correct behavior is for a Java char to map to a CORBA wchar,
+- * but our older code mapped it to a CORBA char.
+- */
+- protected TCKind getJavaCharTCKind() {
+- return TCKind.tk_char;
+- }
+-
+- /**
+- * RepositoryId_1_3_1 performs an incorrect repId calculation
+- * when using serialPersistentFields and one of the fields no longer
+- * exists on the class itself.
+- */
+- public boolean useFullValueDescription(Class clazz, String repositoryID)
+- throws java.io.IOException
+- {
+- return RepositoryId_1_3_1.useFullValueDescription(clazz, repositoryID);
+- }
+-
+- /**
+- * Installs the legacy IIOPOutputStream_1_3_1 which does
+- * PutFields/GetFields incorrectly. Bug 4407244.
+- */
+- protected final String getOutputStreamClassName() {
+- return "com.sun.corba.se.impl.orbutil.IIOPOutputStream_1_3_1";
+- }
+-
+- /**
+- * Installs the legacy IIOPInputStream_1_3_1 which does
+- * PutFields/GetFields incorrectly. Bug 4407244.
+- */
+- protected final String getInputStreamClassName() {
+- return "com.sun.corba.se.impl.orbutil.IIOPInputStream_1_3_1";
+- }
+-}
+diff --git a/src/share/classes/sun/corba/JavaCorbaAccess.java b/src/share/classes/sun/corba/JavaCorbaAccess.java
+new file mode 100644
+--- /dev/null
++++ corba/src/share/classes/sun/corba/JavaCorbaAccess.java
+@@ -0,0 +1,32 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.corba;
++
++import com.sun.corba.se.impl.io.ValueHandlerImpl;
++
++public interface JavaCorbaAccess {
++ public ValueHandlerImpl newValueHandlerImpl();
++}
+diff --git a/src/share/classes/sun/corba/SharedSecrets.java b/src/share/classes/sun/corba/SharedSecrets.java
+new file mode 100644
+--- /dev/null
++++ corba/src/share/classes/sun/corba/SharedSecrets.java
+@@ -0,0 +1,60 @@
++/*
++ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ *
++ * This code is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License version 2 only, as
++ * published by the Free Software Foundation. Oracle designates this
++ * particular file as subject to the "Classpath" exception as provided
++ * by Oracle in the LICENSE file that accompanied this code.
++ *
++ * This code 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
++ * version 2 for more details (a copy is included in the LICENSE file that
++ * accompanied this code).
++ *
++ * You should have received a copy of the GNU General Public License version
++ * 2 along with this work; if not, write to the Free Software Foundation,
++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
++ *
++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
++ * or visit www.oracle.com if you need additional information or have any
++ * questions.
++ */
++
++package sun.corba;
++
++import com.sun.corba.se.impl.io.ValueUtility;
++import sun.misc.Unsafe;
++
++import java.security.AccessController;
++
++/** A repository of "shared secrets", which are a mechanism for
++ calling implementation-private methods in another package without
++ using reflection. A package-private class implements a public
++ interface and provides the ability to call package-private methods
++ within that package; the object implementing that interface is
++ provided through a third package to which access is restricted.
++ This framework avoids the primary disadvantage of using reflection
++ for this purpose, namely the loss of compile-time checking. */
++
++// SharedSecrets cloned in corba repo to avoid build issues
++public class SharedSecrets {
++ private static final Unsafe unsafe = Unsafe.getUnsafe();
++ private static JavaCorbaAccess javaCorbaAccess;
++
++ public static JavaCorbaAccess getJavaCorbaAccess() {
++ if (javaCorbaAccess == null) {
++ // Ensure ValueUtility is initialized; we know that that class
++ // provides the shared secret
++ unsafe.ensureClassInitialized(ValueUtility.class);
++ }
++ return javaCorbaAccess;
++ }
++
++ public static void setJavaCorbaAccess(JavaCorbaAccess access) {
++ javaCorbaAccess = access;
++ }
++
++}
diff --git a/java/openjdk6/files/icedtea/security/20130201/8001235.patch b/java/openjdk6/files/icedtea/security/20130201/8001235.patch
new file mode 100644
index 000000000000..73d700c3bc30
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/8001235.patch
@@ -0,0 +1,37 @@
+diff -Nru jaxp.old/build.properties jaxp/build.properties
+--- jaxp.old/build.properties 2013-02-01 21:59:17.360429006 +0000
++++ jaxp/build.properties 2013-02-01 22:04:56.349681812 +0000
+@@ -77,6 +77,9 @@
+ # Where patches to drop bundle sources live
+ patches.dir=patches
+
++# Patches to apply
++jaxp_src.patch.list=8001235.patch
++
+ # Sanity information
+ sanity.info= Sanity Settings:${line.separator}\
+ ant.home=${ant.home}${line.separator}\
+diff -Nru jaxp.old/patches/jaxp_src/8001235.patch jaxp/patches/jaxp_src/8001235.patch
+--- jaxp.old/patches/jaxp_src/8001235.patch 1970-01-01 01:00:00.000000000 +0100
++++ jaxp/patches/jaxp_src/8001235.patch 2013-02-01 22:04:27.369232768 +0000
+@@ -0,0 +1,20 @@
++# HG changeset patch
++# User joehw
++# Date 1351536837 25200
++# Node ID 5df9207c4378b7f4b24d70b365714c5ee6318982
++# Parent 5449d5396bd8deee90f18f29899343129e3cdc4e
++8001235: Improve JAXP HTTP handling
++Reviewed-by: lancea, skoivu
++
++diff --git a/src/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java b/src/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java
++--- src/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java
+++++ src/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java
++@@ -165,7 +165,7 @@ public class FuncSystemProperty extends
++ * should already be fully qualified as path/filename
++ * @param target The target property bag the file will be placed into.
++ */
++- public void loadPropertyFile(String file, Properties target)
+++ private void loadPropertyFile(String file, Properties target)
++ {
++ try
++ {
diff --git a/java/openjdk6/files/icedtea/security/20130201/8001242.patch b/java/openjdk6/files/icedtea/security/20130201/8001242.patch
new file mode 100644
index 000000000000..5c983c3dc11d
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/8001242.patch
@@ -0,0 +1,61 @@
+# HG changeset patch
+# User dmocek
+# Date 1353367979 28800
+# Node ID 49a37df9e80fae205a7b70d862cd303a62049c2c
+# Parent 2281f5670cc599f0fe97c880cdceb6a7db837dc3
+8001242: Improve RMI HTTP conformance
+Reviewed-by: ahgross, mchung, smarks
+
+diff --git a/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java b/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java
+--- jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java
++++ jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java
+@@ -285,11 +285,14 @@ final class CGIForwardCommand implements
+ "unexpected EOF reading server response");
+
+ if (line.toLowerCase().startsWith(key)) {
+- if (contentLengthFound)
+- ; // what would we want to do in this case??
+- responseContentLength =
+- Integer.parseInt(line.substring(key.length()).trim());
+- contentLengthFound = true;
++ if (contentLengthFound) {
++ throw new CGIServerException(
++ "Multiple Content-length entries found.");
++ } else {
++ responseContentLength =
++ Integer.parseInt(line.substring(key.length()).trim());
++ contentLengthFound = true;
++ }
+ }
+ } while ((line.length() != 0) &&
+ (line.charAt(0) != '\r') && (line.charAt(0) != '\n'));
+diff --git a/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java b/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java
+--- jdk/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java
++++ jdk/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2001, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -70,11 +70,14 @@ class HttpInputStream extends FilterInpu
+ throw new EOFException();
+
+ if (line.toLowerCase().startsWith(key)) {
+- if (contentLengthFound)
+- ; // what would we want to do in this case??
+- bytesLeft =
+- Integer.parseInt(line.substring(key.length()).trim());
+- contentLengthFound = true;
++ if (contentLengthFound) {
++ throw new IOException(
++ "Multiple Content-length entries found.");
++ } else {
++ bytesLeft =
++ Integer.parseInt(line.substring(key.length()).trim());
++ contentLengthFound = true;
++ }
+ }
+
+ // The idea here is to go past the first blank line.
diff --git a/java/openjdk6/files/icedtea/security/20130201/8001307.patch b/java/openjdk6/files/icedtea/security/20130201/8001307.patch
new file mode 100644
index 000000000000..4794f95418a7
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/8001307.patch
@@ -0,0 +1,27 @@
+diff -Nru openjdk.orig/hotspot/src/share/vm/interpreter/linkResolver.cpp openjdk/hotspot/src/share/vm/interpreter/linkResolver.cpp
+--- openjdk.orig/hotspot/src/share/vm/interpreter/linkResolver.cpp 2011-11-14 22:07:35.000000000 +0000
++++ hotspot/src/share/vm/interpreter/linkResolver.cpp 2013-02-01 21:46:24.084475305 +0000
+@@ -695,7 +695,7 @@
+
+ if (check_access &&
+ // a) check if ACC_SUPER flag is set for the current class
+- current_klass->is_super() &&
++ (current_klass->is_super() || !AllowNonVirtualCalls) &&
+ // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
+ current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() &&
+ // c) check if the method is not <init>
+diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/globals.hpp openjdk/hotspot/src/share/vm/runtime/globals.hpp
+--- openjdk.orig/hotspot/src/share/vm/runtime/globals.hpp 2013-02-01 21:44:12.678449777 +0000
++++ hotspot/src/share/vm/runtime/globals.hpp 2013-02-01 21:46:57.300987338 +0000
+@@ -3700,7 +3700,10 @@
+ product(bool, UseVMInterruptibleIO, false, \
+ "(Unstable, Solaris-specific) Thread interrupt before or with " \
+ "EINTR for I/O operations results in OS_INTRPT. The default value"\
+- " of this flag is true for JDK 6 and earliers")
++ " of this flag is true for JDK 6 and earlier") \
++ \
++ product(bool, AllowNonVirtualCalls, false, \
++ "Obey the ACC_SUPER flag and allow invokenonvirtual calls")
+
+ /*
+ * Macros for factoring of globals
diff --git a/java/openjdk6/files/icedtea/security/20130201/8001972.patch b/java/openjdk6/files/icedtea/security/20130201/8001972.patch
new file mode 100644
index 000000000000..b379b7a6b9ec
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/8001972.patch
@@ -0,0 +1,438 @@
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java openjdk/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java
+--- openjdk.orig/jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java 2011-11-14 22:11:59.000000000 +0000
++++ jdk/src/share/classes/sun/awt/image/ByteComponentRaster.java 2013-02-01 21:49:28.911324533 +0000
+@@ -198,7 +198,7 @@
+ }
+ this.bandOffset = this.dataOffsets[0];
+
+- verify(false);
++ verify();
+ }
+
+ /**
+@@ -857,38 +857,68 @@
+ }
+
+ /**
+- * Verify that the layout parameters are consistent with
+- * the data. If strictCheck
+- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
+- * strictCheck is true, this method will check for additional error
+- * conditions such as line wraparound (width of a line greater than
+- * the scanline stride).
+- * @return String Error string, if the layout is incompatible with
+- * the data. Otherwise returns null.
+- */
+- private void verify (boolean strictCheck) {
+- // Make sure data for Raster is in a legal range
+- for (int i=0; i < dataOffsets.length; i++) {
++ * Verify that the layout parameters are consistent with the data.
++ *
++ * The method verifies whether scanline stride and pixel stride do not
++ * cause an integer overflow during calculation of a position of the pixel
++ * in data buffer. It also verifies whether the data buffer has enough data
++ * to correspond the raster layout attributes.
++ *
++ * @throws RasterFormatException if an integer overflow is detected,
++ * or if data buffer has not enough capacity.
++ */
++ protected final void verify() {
++ for (int i = 0; i < dataOffsets.length; i++) {
+ if (dataOffsets[i] < 0) {
+- throw new RasterFormatException("Data offsets for band "+i+
+- "("+dataOffsets[i]+
+- ") must be >= 0");
++ throw new RasterFormatException("Data offsets for band " + i
++ + "(" + dataOffsets[i]
++ + ") must be >= 0");
+ }
+ }
+
+ int maxSize = 0;
+ int size;
+
+- for (int i=0; i < numDataElements; i++) {
+- size = (height-1)*scanlineStride + (width-1)*pixelStride +
+- dataOffsets[i];
++ // we can be sure that width and height are greater than 0
++ if (scanlineStride < 0 ||
++ scanlineStride > (Integer.MAX_VALUE / height))
++ {
++ // integer overflow
++ throw new RasterFormatException("Incorrect scanline stride: "
++ + scanlineStride);
++ }
++ int lastScanOffset = (height - 1) * scanlineStride;
++
++ if (pixelStride < 0 ||
++ pixelStride > (Integer.MAX_VALUE / width))
++ {
++ // integer overflow
++ throw new RasterFormatException("Incorrect pixel stride: "
++ + pixelStride);
++ }
++ int lastPixelOffset = (width - 1) * pixelStride;
++
++ if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
++ // integer overflow
++ throw new RasterFormatException("Incorrect raster attributes");
++ }
++ lastPixelOffset += lastScanOffset;
++
++ for (int i = 0; i < numDataElements; i++) {
++ size = lastPixelOffset + dataOffsets[i];
++ if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
++ throw new RasterFormatException("Incorrect band offset: "
++ + dataOffsets[i]);
++
++ }
++
+ if (size > maxSize) {
+ maxSize = size;
+ }
+ }
+ if (data.length < maxSize) {
+- throw new RasterFormatException("Data array too small (should be "+
+- maxSize+" )");
++ throw new RasterFormatException("Data array too small (should be "
++ + maxSize + " )");
+ }
+ }
+
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java openjdk/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java
+--- openjdk.orig/jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java 2011-11-14 22:11:59.000000000 +0000
++++ jdk/src/share/classes/sun/awt/image/ByteInterleavedRaster.java 2013-02-01 21:49:28.911324533 +0000
+@@ -250,7 +250,7 @@
+ }
+ }
+
+- verify(false);
++ verify();
+ }
+
+ /**
+@@ -1292,33 +1292,6 @@
+ return createCompatibleWritableRaster(width,height);
+ }
+
+- /**
+- * Verify that the layout parameters are consistent with
+- * the data. If strictCheck
+- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
+- * strictCheck is true, this method will check for additional error
+- * conditions such as line wraparound (width of a line greater than
+- * the scanline stride).
+- * @return String Error string, if the layout is incompatible with
+- * the data. Otherwise returns null.
+- */
+- private void verify (boolean strictCheck) {
+- int maxSize = 0;
+- int size;
+-
+- for (int i=0; i < numDataElements; i++) {
+- size = (height-1)*scanlineStride + (width-1)*pixelStride +
+- dataOffsets[i];
+- if (size > maxSize) {
+- maxSize = size;
+- }
+- }
+- if (data.length < maxSize) {
+- throw new RasterFormatException("Data array too small (should be "+
+- maxSize+" )");
+- }
+- }
+-
+ public String toString() {
+ return new String ("ByteInterleavedRaster: width = "+width+" height = "
+ + height
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java openjdk/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java
+--- openjdk.orig/jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java 2011-11-14 22:11:59.000000000 +0000
++++ jdk/src/share/classes/sun/awt/image/ShortComponentRaster.java 2013-02-01 21:49:28.911324533 +0000
+@@ -198,7 +198,7 @@
+ }
+ this.bandOffset = this.dataOffsets[0];
+
+- verify(false);
++ verify();
+ }
+
+ /**
+@@ -791,38 +791,67 @@
+ }
+
+ /**
+- * Verify that the layout parameters are consistent with
+- * the data. If strictCheck
+- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
+- * strictCheck is true, this method will check for additional error
+- * conditions such as line wraparound (width of a line greater than
+- * the scanline stride).
+- * @return String Error string, if the layout is incompatible with
+- * the data. Otherwise returns null.
+- */
+- private void verify (boolean strictCheck) {
+- // Make sure data for Raster is in a legal range
+- for (int i=0; i < dataOffsets.length; i++) {
++ * Verify that the layout parameters are consistent with the data.
++ *
++ * The method verifies whether scanline stride and pixel stride do not
++ * cause an integer overflow during calculation of a position of the pixel
++ * in data buffer. It also verifies whether the data buffer has enough data
++ * to correspond the raster layout attributes.
++ *
++ * @throws RasterFormatException if an integer overflow is detected,
++ * or if data buffer has not enough capacity.
++ */
++ protected final void verify() {
++ for (int i = 0; i < dataOffsets.length; i++) {
+ if (dataOffsets[i] < 0) {
+- throw new RasterFormatException("Data offsets for band "+i+
+- "("+dataOffsets[i]+
+- ") must be >= 0");
++ throw new RasterFormatException("Data offsets for band " + i
++ + "(" + dataOffsets[i]
++ + ") must be >= 0");
+ }
+ }
+
+ int maxSize = 0;
+ int size;
+
+- for (int i=0; i < numDataElements; i++) {
+- size = (height-1)*scanlineStride + (width-1)*pixelStride +
+- dataOffsets[i];
++ // we can be sure that width and height are greater than 0
++ if (scanlineStride < 0 ||
++ scanlineStride > (Integer.MAX_VALUE / height))
++ {
++ // integer overflow
++ throw new RasterFormatException("Incorrect scanline stride: "
++ + scanlineStride);
++ }
++ int lastScanOffset = (height - 1) * scanlineStride;
++
++ if (pixelStride < 0 ||
++ pixelStride > (Integer.MAX_VALUE / width))
++ {
++ // integer overflow
++ throw new RasterFormatException("Incorrect pixel stride: "
++ + pixelStride);
++ }
++ int lastPixelOffset = (width - 1) * pixelStride;
++
++ if (lastPixelOffset > (Integer.MAX_VALUE - lastScanOffset)) {
++ // integer overflow
++ throw new RasterFormatException("Incorrect raster attributes");
++ }
++ lastPixelOffset += lastScanOffset;
++
++ for (int i = 0; i < numDataElements; i++) {
++ size = lastPixelOffset + dataOffsets[i];
++ if (dataOffsets[i] > (Integer.MAX_VALUE - lastPixelOffset)) {
++ throw new RasterFormatException("Incorrect band offset: "
++ + dataOffsets[i]);
++ }
++
+ if (size > maxSize) {
+ maxSize = size;
+ }
+ }
+ if (data.length < maxSize) {
+- throw new RasterFormatException("Data array too small (should be "+
+- maxSize+" )");
++ throw new RasterFormatException("Data array too small (should be "
++ + maxSize + " )");
+ }
+ }
+
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java openjdk/jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java
+--- openjdk.orig/jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java 2011-11-14 22:11:59.000000000 +0000
++++ jdk/src/share/classes/sun/awt/image/ShortInterleavedRaster.java 2013-02-01 21:49:28.911324533 +0000
+@@ -171,7 +171,7 @@
+ sampleModel);
+ }
+ this.bandOffset = this.dataOffsets[0];
+- verify(false);
++ verify();
+ }
+
+ /**
+@@ -762,33 +762,6 @@
+ return createCompatibleWritableRaster(width,height);
+ }
+
+- /**
+- * Verify that the layout parameters are consistent with
+- * the data. If strictCheck
+- * is false, this method will check for ArrayIndexOutOfBounds conditions. If
+- * strictCheck is true, this method will check for additional error
+- * conditions such as line wraparound (width of a line greater than
+- * the scanline stride).
+- * @return String Error string, if the layout is incompatible with
+- * the data. Otherwise returns null.
+- */
+- private void verify (boolean strictCheck) {
+- int maxSize = 0;
+- int size;
+-
+- for (int i=0; i < numDataElements; i++) {
+- size = (height-1)*scanlineStride + (width-1)*pixelStride +
+- dataOffsets[i];
+- if (size > maxSize) {
+- maxSize = size;
+- }
+- }
+- if (data.length < maxSize) {
+- throw new RasterFormatException("Data array too small (should be "+
+- maxSize+" )");
+- }
+- }
+-
+ public String toString() {
+ return new String ("ShortInterleavedRaster: width = "+width
+ +" height = " + height
+diff -Nru openjdk.orig/jdk/src/share/native/sun/awt/image/awt_parseImage.c openjdk/jdk/src/share/native/sun/awt/image/awt_parseImage.c
+--- openjdk.orig/jdk/src/share/native/sun/awt/image/awt_parseImage.c 2011-11-14 22:12:11.000000000 +0000
++++ jdk/src/share/native/sun/awt/image/awt_parseImage.c 2013-02-01 21:54:40.100132273 +0000
+@@ -114,6 +114,62 @@
+ return status;
+ }
+
++/* Verifies whether the channel offsets are sane and correspond to the type of
++ * the raster.
++ *
++ * Return value:
++ * 0: Failure: channel offsets are invalid
++ * 1: Success
++ */
++static int checkChannelOffsets(RasterS_t *rasterP, int dataArrayLength) {
++ int i, lastPixelOffset, lastScanOffset;
++ switch (rasterP->rasterType) {
++ case COMPONENT_RASTER_TYPE:
++ if (!SAFE_TO_MULT(rasterP->height, rasterP->scanlineStride)) {
++ return 0;
++ }
++ if (!SAFE_TO_MULT(rasterP->width, rasterP->pixelStride)) {
++ return 0;
++ }
++
++ lastScanOffset = (rasterP->height - 1) * rasterP->scanlineStride;
++ lastPixelOffset = (rasterP->width - 1) * rasterP->pixelStride;
++
++
++ if (!SAFE_TO_ADD(lastPixelOffset, lastScanOffset)) {
++ return 0;
++ }
++
++ lastPixelOffset += lastScanOffset;
++
++ for (i = 0; i < rasterP->numDataElements; i++) {
++ int off = rasterP->chanOffsets[i];
++ int size = lastPixelOffset + off;
++
++ if (off < 0 || !SAFE_TO_ADD(lastPixelOffset, off)) {
++ return 0;
++ }
++
++ if (size < lastPixelOffset || size >= dataArrayLength) {
++ // an overflow, or insufficient buffer capacity
++ return 0;
++ }
++ }
++ return 1;
++ case BANDED_RASTER_TYPE:
++ // NB:caller does not support the banded rasters yet,
++ // so this branch of the code must be re-defined in
++ // order to provide valid criteria for the data offsets
++ // verification, when/if banded rasters will be supported.
++ // At the moment, we prohibit banded rasters as well.
++ return 0;
++ default:
++ // PACKED_RASTER_TYPE: does not support channel offsets
++ // UNKNOWN_RASTER_TYPE: should not be used, likely indicates an error
++ return 0;
++ }
++}
++
+ /* Parse the raster. All of the raster information is returned in the
+ * rasterP structure.
+ *
+@@ -125,7 +181,6 @@
+ int awt_parseRaster(JNIEnv *env, jobject jraster, RasterS_t *rasterP) {
+ jobject joffs = NULL;
+ /* int status;*/
+- int isDiscrete = TRUE;
+
+ if (JNU_IsNull(env, jraster)) {
+ JNU_ThrowNullPointerException(env, "null Raster object");
+@@ -155,6 +210,9 @@
+ return -1;
+ }
+
++ // make sure that the raster type is initialized
++ rasterP->rasterType = UNKNOWN_RASTER_TYPE;
++
+ if (rasterP->numBands <= 0 ||
+ rasterP->numBands > MAX_NUMBANDS)
+ {
+@@ -254,7 +312,6 @@
+ }
+ rasterP->chanOffsets[0] = (*env)->GetIntField(env, jraster, g_BPRdataBitOffsetID);
+ rasterP->dataType = BYTE_DATA_TYPE;
+- isDiscrete = FALSE;
+ }
+ else {
+ rasterP->type = sun_awt_image_IntegerComponentRaster_TYPE_CUSTOM;
+@@ -265,7 +322,19 @@
+ return 0;
+ }
+
+- if (isDiscrete) {
++ // do basic validation of the raster structure
++ if (rasterP->width <= 0 || rasterP->height <= 0 ||
++ rasterP->pixelStride <= 0 || rasterP->scanlineStride <= 0)
++ {
++ // invalid raster
++ return -1;
++ }
++
++ // channel (data) offsets
++ switch (rasterP->rasterType) {
++ case COMPONENT_RASTER_TYPE:
++ case BANDED_RASTER_TYPE: // note that this routine does not support banded rasters at the moment
++ // get channel (data) offsets
+ rasterP->chanOffsets = NULL;
+ if (SAFE_TO_ALLOC_2(rasterP->numDataElements, sizeof(jint))) {
+ rasterP->chanOffsets =
+@@ -278,6 +347,17 @@
+ }
+ (*env)->GetIntArrayRegion(env, joffs, 0, rasterP->numDataElements,
+ rasterP->chanOffsets);
++ if (rasterP->jdata == NULL) {
++ // unable to verify the raster
++ return -1;
++ }
++ // verify whether channel offsets look sane
++ if (!checkChannelOffsets(rasterP, (*env)->GetArrayLength(env, rasterP->jdata))) {
++ return -1;
++ }
++ break;
++ default:
++ ; // PACKED_RASTER_TYPE does not use the channel offsets.
+ }
+
+ #if 0
+diff -Nru openjdk.orig/jdk/src/share/native/sun/awt/medialib/safe_alloc.h openjdk/jdk/src/share/native/sun/awt/medialib/safe_alloc.h
+--- openjdk.orig/jdk/src/share/native/sun/awt/medialib/safe_alloc.h 2011-11-14 22:12:12.000000000 +0000
++++ jdk/src/share/native/sun/awt/medialib/safe_alloc.h 2013-02-01 21:49:28.911324533 +0000
+@@ -41,5 +41,10 @@
+ (((w) > 0) && ((h) > 0) && ((sz) > 0) && \
+ (((0xffffffffu / ((juint)(w))) / ((juint)(h))) > ((juint)(sz))))
+
++#define SAFE_TO_MULT(a, b) \
++ (((a) > 0) && ((b) >= 0) && ((0x7fffffff / (a)) > (b)))
++
++#define SAFE_TO_ADD(a, b) \
++ (((a) >= 0) && ((b) >= 0) && ((0x7fffffff - (a)) > (b)))
+
+ #endif // __SAFE_ALLOC_H__
diff --git a/java/openjdk6/files/icedtea/security/20130201/8002325.patch b/java/openjdk6/files/icedtea/security/20130201/8002325.patch
new file mode 100644
index 000000000000..9de38623270b
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130201/8002325.patch
@@ -0,0 +1,59 @@
+# HG changeset patch
+# User bae
+# Date 1353162084 -14400
+# Node ID 6081ed9a6461360252572f79713b20c49caa59ad
+# Parent 1e4909147511ffa8f2089c488df2435af4707283
+8002325: Improve management of images
+Reviewed-by: prr, ahgross
+
+diff --git a/src/share/native/sun/awt/image/awt_parseImage.c b/src/share/native/sun/awt/image/awt_parseImage.c
+--- jdk/src/share/native/sun/awt/image/awt_parseImage.c
++++ jdk/src/share/native/sun/awt/image/awt_parseImage.c
+@@ -223,9 +223,14 @@ int awt_parseRaster(JNIEnv *env, jobject
+ return 0;
+ }
+
++ rasterP->sppsm.isUsed = 0;
++
+ if ((*env)->IsInstanceOf(env, rasterP->jsampleModel,
+ (*env)->FindClass(env,"java/awt/image/SinglePixelPackedSampleModel"))) {
+ jobject jmask, joffs, jnbits;
++
++ rasterP->sppsm.isUsed = 1;
++
+ rasterP->sppsm.maxBitSize = (*env)->GetIntField(env,
+ rasterP->jsampleModel,
+ g_SPPSMmaxBitID);
+@@ -711,6 +716,21 @@ setHints(JNIEnv *env, BufImageS_t *image
+ }
+ else if (cmodelP->cmType == DIRECT_CM_TYPE || cmodelP->cmType == PACKED_CM_TYPE) {
+ int i;
++
++ /* do some sanity check first: make sure that
++ * - sample model is SinglePixelPackedSampleModel
++ * - number of bands in the raster corresponds to the number
++ * of color components in the color model
++ */
++ if (!rasterP->sppsm.isUsed ||
++ rasterP->numBands != cmodelP->numComponents)
++ {
++ /* given raster is not compatible with the color model,
++ * so the operation has to be aborted.
++ */
++ return -1;
++ }
++
+ if (cmodelP->maxNbits > 8) {
+ hintP->needToExpand = TRUE;
+ hintP->expandToNbits = cmodelP->maxNbits;
+diff --git a/src/share/native/sun/awt/image/awt_parseImage.h b/src/share/native/sun/awt/image/awt_parseImage.h
+--- jdk/src/share/native/sun/awt/image/awt_parseImage.h
++++ jdk/src/share/native/sun/awt/image/awt_parseImage.h
+@@ -95,6 +95,7 @@ typedef struct {
+ jint offsets[MAX_NUMBANDS];
+ jint nBits[MAX_NUMBANDS];
+ jint maxBitSize;
++ jint isUsed; // flag to indicate whether the raster sample model is SPPSM
+ } SPPSampleModelS_t;
+
+ /* Struct that holds information for the Raster object */
diff --git a/java/openjdk6/files/icedtea/security/20130219/8006446.patch b/java/openjdk6/files/icedtea/security/20130219/8006446.patch
new file mode 100644
index 000000000000..80501ea62890
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130219/8006446.patch
@@ -0,0 +1,395 @@
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java 2011-11-14 22:11:44.000000000 +0000
++++ jdk/src/share/classes/com/sun/jmx/mbeanserver/ClassLoaderRepositorySupport.java 2013-02-15 03:40:40.511587149 +0000
+@@ -36,6 +36,7 @@
+
+ import javax.management.ObjectName;
+ import javax.management.loading.PrivateClassLoader;
++import sun.reflect.misc.ReflectUtil;
+
+ /**
+ * This class keeps the list of Class Loaders registered in the MBean Server.
+@@ -192,6 +193,7 @@
+ final ClassLoader without,
+ final ClassLoader stop)
+ throws ClassNotFoundException {
++ ReflectUtil.checkPackageAccess(className);
+ final int size = list.length;
+ for(int i=0; i<size; i++) {
+ try {
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java 2011-11-14 22:11:44.000000000 +0000
++++ jdk/src/share/classes/com/sun/jmx/mbeanserver/JmxMBeanServer.java 2013-02-15 03:40:40.511587149 +0000
+@@ -57,6 +57,7 @@
+ import javax.management.RuntimeOperationsException;
+ import javax.management.MBeanServer;
+ import javax.management.MBeanServerDelegate;
++import javax.management.MBeanServerPermission;
+ import javax.management.loading.ClassLoaderRepository;
+
+ import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
+@@ -1413,6 +1414,8 @@
+ // Default is true.
+ final boolean fairLock = DEFAULT_FAIR_LOCK_POLICY;
+
++ checkNewMBeanServerPermission();
++
+ // This constructor happens to disregard the value of the interceptors
+ // flag - that is, it always uses the default value - false.
+ // This is admitedly a bug, but we chose not to fix it for now
+@@ -1499,4 +1502,11 @@
+ }
+ }
+
++ private static void checkNewMBeanServerPermission() {
++ SecurityManager sm = System.getSecurityManager();
++ if (sm != null) {
++ Permission perm = new MBeanServerPermission("newMBeanServer");
++ sm.checkPermission(perm);
++ }
++ }
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java 2011-11-14 22:11:44.000000000 +0000
++++ jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java 2013-02-15 03:40:40.511587149 +0000
+@@ -32,11 +32,13 @@
+ import java.io.ObjectInputStream;
+ import java.lang.reflect.Constructor;
+ import java.lang.reflect.InvocationTargetException;
++import java.security.Permission;
+ import java.util.Map;
+ import java.util.logging.Level;
+
+ import javax.management.InstanceNotFoundException;
+ import javax.management.MBeanException;
++import javax.management.MBeanPermission;
+ import javax.management.NotCompliantMBeanException;
+ import javax.management.ObjectName;
+ import javax.management.OperationsException;
+@@ -44,7 +46,7 @@
+ import javax.management.RuntimeErrorException;
+ import javax.management.RuntimeMBeanException;
+ import javax.management.RuntimeOperationsException;
+-
++import sun.reflect.misc.ConstructorUtil;
+ import sun.reflect.misc.ReflectUtil;
+
+ /**
+@@ -56,7 +58,6 @@
+ * @since 1.5
+ */
+ public class MBeanInstantiator {
+-
+ private final ModifiableClassLoaderRepository clr;
+ // private MetaData meta = null;
+
+@@ -88,6 +89,7 @@
+ "Exception occurred during object instantiation");
+ }
+
++ ReflectUtil.checkPackageAccess(className);
+ try {
+ if (clr == null) throw new ClassNotFoundException(className);
+ theClass = clr.loadClass(className);
+@@ -162,6 +164,7 @@
+ continue;
+ }
+
++ ReflectUtil.checkPackageAccess(signature[i]);
+ // Ok we do not have a primitive type ! We need to build
+ // the signature of the method
+ //
+@@ -205,6 +208,9 @@
+ */
+ public Object instantiate(Class theClass)
+ throws ReflectionException, MBeanException {
++
++ checkMBeanPermission(theClass, null, null, "instantiate");
++
+ Object moi = null;
+
+
+@@ -260,6 +266,9 @@
+ public Object instantiate(Class theClass, Object params[],
+ String signature[], ClassLoader loader)
+ throws ReflectionException, MBeanException {
++
++ checkMBeanPermission(theClass, null, null, "instantiate");
++
+ // Instantiate the new object
+
+ // ------------------------------
+@@ -408,6 +417,8 @@
+ throw new RuntimeOperationsException(new
+ IllegalArgumentException(), "Null className passed in parameter");
+ }
++
++ ReflectUtil.checkPackageAccess(className);
+ Class theClass = null;
+ if (loaderName == null) {
+ // Load the class using the agent class loader
+@@ -620,13 +631,13 @@
+ **/
+ static Class loadClass(String className, ClassLoader loader)
+ throws ReflectionException {
+-
+ Class theClass = null;
+ if (className == null) {
+ throw new RuntimeOperationsException(new
+ IllegalArgumentException("The class name cannot be null"),
+ "Exception occurred during object instantiation");
+ }
++ ReflectUtil.checkPackageAccess(className);
+ try {
+ if (loader == null)
+ loader = MBeanInstantiator.class.getClassLoader();
+@@ -677,6 +688,7 @@
+ // We need to load the class through the class
+ // loader of the target object.
+ //
++ ReflectUtil.checkPackageAccess(signature[i]);
+ tab[i] = Class.forName(signature[i], false, aLoader);
+ }
+ } catch (ClassNotFoundException e) {
+@@ -702,7 +714,7 @@
+
+ private Constructor<?> findConstructor(Class<?> c, Class<?>[] params) {
+ try {
+- return c.getConstructor(params);
++ return ConstructorUtil.getConstructor(c, params);
+ } catch (Exception e) {
+ return null;
+ }
+@@ -716,4 +728,18 @@
+ char.class, boolean.class})
+ primitiveClasses.put(c.getName(), c);
+ }
++
++ private static void checkMBeanPermission(Class<?> clazz,
++ String member,
++ ObjectName objectName,
++ String actions) {
++ SecurityManager sm = System.getSecurityManager();
++ if (clazz != null && sm != null) {
++ Permission perm = new MBeanPermission(clazz.getName(),
++ member,
++ objectName,
++ actions);
++ sm.checkPermission(perm);
++ }
++ }
+ }
+diff -Nru openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java openjdk/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java
+--- openjdk.orig/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java 2011-11-14 22:11:44.000000000 +0000
++++ jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java 2013-02-15 03:40:40.511587149 +0000
+@@ -38,6 +38,7 @@
+ import javax.management.NotCompliantMBeanException;
+ import javax.management.ObjectName;
+ import javax.management.ReflectionException;
++import sun.reflect.misc.ReflectUtil;
+
+ /**
+ * Base class for MBeans. There is one instance of this class for
+@@ -131,6 +132,7 @@
+ " is not an instance of " + mbeanInterface.getName();
+ throw new NotCompliantMBeanException(msg);
+ }
++ ReflectUtil.checkPackageAccess(mbeanInterface);
+ this.resource = resource;
+ MBeanIntrospector<M> introspector = getMBeanIntrospector();
+ this.perInterface = introspector.getPerInterface(mbeanInterface);
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/management/LockDataConverter.java openjdk/jdk/src/share/classes/sun/management/LockDataConverter.java
+--- openjdk.orig/jdk/src/share/classes/sun/management/LockDataConverter.java 2011-11-14 22:12:00.000000000 +0000
++++ jdk/src/share/classes/sun/management/LockDataConverter.java 2013-02-15 03:40:40.511587149 +0000
+@@ -27,6 +27,8 @@
+
+ import java.lang.management.LockInfo;
+ import java.lang.management.ThreadInfo;
++import java.security.AccessController;
++import java.security.PrivilegedAction;
+ import javax.management.Attribute;
+ import javax.management.StandardMBean;
+ import javax.management.openmbean.CompositeData;
+@@ -40,13 +42,13 @@
+ private LockInfo lockInfo;
+ private LockInfo[] lockedSyncs;
+
+- LockDataConverter() {
++ private LockDataConverter() {
+ super(LockDataConverterMXBean.class, true);
+ this.lockInfo = null;
+ this.lockedSyncs = null;
+ }
+
+- LockDataConverter(ThreadInfo ti) {
++ private LockDataConverter(ThreadInfo ti) {
+ super(LockDataConverterMXBean.class, true);
+ this.lockInfo = ti.getLockInfo();
+ this.lockedSyncs = ti.getLockedSynchronizers();
+@@ -104,8 +106,24 @@
+ }
+
+ static CompositeData toLockInfoCompositeData(LockInfo l) {
+- LockDataConverter ldc = new LockDataConverter();
++ LockDataConverter ldc = newLockDataConverter();
+ ldc.setLockInfo(l);
+ return ldc.toLockInfoCompositeData();
+ }
++
++ static LockDataConverter newLockDataConverter() {
++ return AccessController.doPrivileged(new PrivilegedAction<LockDataConverter>() {
++ public LockDataConverter run() {
++ return new LockDataConverter();
++ }
++ });
++ }
++
++ static LockDataConverter newLockDataConverter(final ThreadInfo ti) {
++ LockDataConverter result = newLockDataConverter();
++ result.lockInfo = ti.getLockInfo();
++ result.lockedSyncs = ti.getLockedSynchronizers();
++ return result;
++ }
+ }
++
+diff -Nru openjdk.orig/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java openjdk/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java
+--- openjdk.orig/jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java 2011-11-14 22:12:01.000000000 +0000
++++ jdk/src/share/classes/sun/management/ThreadInfoCompositeData.java 2013-02-15 03:40:40.511587149 +0000
+@@ -85,7 +85,7 @@
+ }
+
+ // Convert MonitorInfo[] and LockInfo[] to CompositeData[]
+- LockDataConverter converter = new LockDataConverter(threadInfo);
++ LockDataConverter converter = LockDataConverter.newLockDataConverter(threadInfo);
+ CompositeData lockInfoData = converter.toLockInfoCompositeData();
+ CompositeData[] lockedSyncsData = converter.toLockedSynchronizersCompositeData();
+
+@@ -315,7 +315,7 @@
+
+ // 6.0 new attributes
+ public LockInfo lockInfo() {
+- LockDataConverter converter = new LockDataConverter();
++ LockDataConverter converter = LockDataConverter.newLockDataConverter();
+ CompositeData lockInfoData = (CompositeData) cdata.get(LOCK_INFO);
+ return converter.toLockInfo(lockInfoData);
+ }
+@@ -336,7 +336,7 @@
+ }
+
+ public LockInfo[] lockedSynchronizers() {
+- LockDataConverter converter = new LockDataConverter();
++ LockDataConverter converter = LockDataConverter.newLockDataConverter();
+ CompositeData[] lockedSyncsData =
+ (CompositeData[]) cdata.get(LOCKED_SYNCS);
+
+diff -Nru openjdk.orig/jdk/src/share/lib/security/java.security openjdk/jdk/src/share/lib/security/java.security
+--- openjdk.orig/jdk/src/share/lib/security/java.security 2013-02-15 03:39:56.922892783 +0000
++++ jdk/src/share/lib/security/java.security 2013-02-15 03:40:40.511587149 +0000
+@@ -131,8 +131,7 @@
+ com.sun.xml.internal.,\
+ com.sun.imageio.,\
+ com.sun.istack.internal.,\
+- com.sun.jmx.defaults.,\
+- com.sun.jmx.remote.util.
++ com.sun.jmx.
+
+ #
+ # List of comma-separated packages that start with or equal this string
+@@ -148,8 +147,7 @@
+ com.sun.xml.internal.,\
+ com.sun.imageio.,\
+ com.sun.istack.internal.,\
+- com.sun.jmx.defaults.,\
+- com.sun.jmx.remote.util.
++ com.sun.jmx.
+
+ #
+ # Determines whether this properties file can be appended to
+diff -Nru openjdk.orig/jdk/src/share/lib/security/java.security-solaris openjdk/jdk/src/share/lib/security/java.security-solaris
+--- openjdk.orig/jdk/src/share/lib/security/java.security-solaris 2013-02-15 03:39:56.902892466 +0000
++++ jdk/src/share/lib/security/java.security-solaris 2013-02-15 03:41:36.996489851 +0000
+@@ -131,6 +131,8 @@
+ package.access=sun.,\
+ com.sun.xml.internal.,\
+ com.sun.imageio.
++ com.sun.istack.internal.,\
++ com.sun.jmx.
+
+ #
+ # List of comma-separated packages that start with or equal this string
+@@ -145,6 +147,8 @@
+ package.definition=sun.,\
+ com.sun.xml.internal.,\
+ com.sun.imageio.
++ com.sun.istack.internal.,\
++ com.sun.jmx.
+
+ #
+ # Determines whether this properties file can be appended to
+diff -Nru openjdk.orig/jdk/src/share/lib/security/java.security-windows openjdk/jdk/src/share/lib/security/java.security-windows
+--- openjdk.orig/jdk/src/share/lib/security/java.security-windows 2013-02-15 03:39:56.902892466 +0000
++++ jdk/src/share/lib/security/java.security-windows 2013-02-15 03:42:05.304943135 +0000
+@@ -131,6 +131,8 @@
+ package.access=sun.,\
+ com.sun.xml.internal.,\
+ com.sun.imageio.
++ com.sun.istack.internal.,\
++ com.sun.jmx.
+
+ #
+ # List of comma-separated packages that start with or equal this string
+@@ -145,6 +147,8 @@
+ package.definition=sun.,\
+ com.sun.xml.internal.,\
+ com.sun.imageio.
++ com.sun.istack.internal.,\
++ com.sun.jmx.
+
+ #
+ # Determines whether this properties file can be appended to
+diff -Nru openjdk.orig/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java openjdk/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java
+--- openjdk.orig/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java 2011-11-14 22:12:28.000000000 +0000
++++ jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java 2013-02-15 03:40:40.511587149 +0000
+@@ -119,9 +119,6 @@
+ System.out.println("Create SimpleStandard MBean");
+ SimpleStandard s = new SimpleStandard("monitorRole");
+ mbs.registerMBean(s, new ObjectName("MBeans:type=SimpleStandard"));
+- // Set Security Manager
+- //
+- System.setSecurityManager(new SecurityManager());
+ // Create Properties containing the username/password entries
+ //
+ Properties props = new Properties();
+@@ -132,6 +129,9 @@
+ HashMap env = new HashMap();
+ env.put("jmx.remote.authenticator",
+ new JMXPluggableAuthenticator(props));
++ // Set Security Manager
++ //
++ System.setSecurityManager(new SecurityManager());
+ // Create an RMI connector server
+ //
+ System.out.println("Create an RMI connector server");
+diff -Nru openjdk.orig/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java openjdk/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java
+--- openjdk.orig/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java 2011-11-14 22:12:28.000000000 +0000
++++ jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java 2013-02-15 03:40:40.511587149 +0000
+@@ -120,9 +120,6 @@
+ System.out.println("Create SimpleStandard MBean");
+ SimpleStandard s = new SimpleStandard("delegate");
+ mbs.registerMBean(s, new ObjectName("MBeans:type=SimpleStandard"));
+- // Set Security Manager
+- //
+- System.setSecurityManager(new SecurityManager());
+ // Create Properties containing the username/password entries
+ //
+ Properties props = new Properties();
+@@ -133,6 +130,9 @@
+ HashMap env = new HashMap();
+ env.put("jmx.remote.authenticator",
+ new JMXPluggableAuthenticator(props));
++ // Set Security Manager
++ //
++ System.setSecurityManager(new SecurityManager());
+ // Create an RMI connector server
+ //
+ System.out.println("Create an RMI connector server");
diff --git a/java/openjdk6/files/icedtea/security/20130219/8006777.patch b/java/openjdk6/files/icedtea/security/20130219/8006777.patch
new file mode 100644
index 000000000000..913617accfd5
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130219/8006777.patch
@@ -0,0 +1,1036 @@
+# HG changeset patch
+# User coffeys
+# Date 1360882104 0
+# Node ID 85b3b034fdecdc94f082efa8d74e014366502deb
+# Parent 617e68a3948824283f15c36fcd8cf264c1dd0a99
+8006777: Improve TLS handling of invalid messages
+Reviewed-by: wetmore
+
+diff --git a/src/share/classes/sun/security/ssl/CipherBox.java b/src/share/classes/sun/security/ssl/CipherBox.java
+--- jdk/src/share/classes/sun/security/ssl/CipherBox.java
++++ jdk/src/share/classes/sun/security/ssl/CipherBox.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -244,7 +244,8 @@ final class CipherBox {
+ * Decrypts a block of data, returning the size of the
+ * resulting block if padding was required.
+ */
+- int decrypt(byte[] buf, int offset, int len) throws BadPaddingException {
++ int decrypt(byte[] buf, int offset, int len,
++ int tagLen) throws BadPaddingException {
+ if (cipher == null) {
+ return len;
+ }
+@@ -268,8 +269,8 @@ final class CipherBox {
+ } catch (IOException e) { }
+ }
+ if (blockSize != 0) {
+- newLen = removePadding(buf, offset, newLen,
+- blockSize, protocolVersion);
++ newLen = removePadding(
++ buf, offset, newLen, tagLen, blockSize, protocolVersion);
+ }
+ return newLen;
+ } catch (ShortBufferException e) {
+@@ -285,7 +286,7 @@ final class CipherBox {
+ * limit and new limit may be different, given we may
+ * have stripped off some padding bytes.
+ */
+- int decrypt(ByteBuffer bb) throws BadPaddingException {
++ int decrypt(ByteBuffer bb, int tagLen) throws BadPaddingException {
+
+ int len = bb.remaining();
+
+@@ -309,7 +310,6 @@ final class CipherBox {
+ }
+
+ if (debug != null && Debug.isOn("plaintext")) {
+- bb.position(pos);
+ try {
+ HexDumpEncoder hd = new HexDumpEncoder();
+
+@@ -317,7 +317,8 @@ final class CipherBox {
+ "Padded plaintext after DECRYPTION: len = "
+ + newLen);
+
+- hd.encodeBuffer(bb, System.out);
++ hd.encodeBuffer(
++ (ByteBuffer)bb.duplicate().position(pos), System.out);
+ } catch (IOException e) { }
+ }
+
+@@ -326,7 +327,8 @@ final class CipherBox {
+ */
+ if (blockSize != 0) {
+ bb.position(pos);
+- newLen = removePadding(bb, blockSize, protocolVersion);
++ newLen = removePadding(
++ bb, tagLen, blockSize, protocolVersion);
+ }
+ return newLen;
+ } catch (ShortBufferException e) {
+@@ -400,6 +402,65 @@ final class CipherBox {
+ return newlen;
+ }
+
++ /*
++ * A constant-time check of the padding.
++ *
++ * NOTE that we are checking both the padding and the padLen bytes here.
++ *
++ * The caller MUST ensure that the len parameter is a positive number.
++ */
++ private static int[] checkPadding(
++ byte[] buf, int offset, int len, byte pad) {
++
++ if (len <= 0) {
++ throw new RuntimeException("padding len must be positive");
++ }
++
++ // An array of hits is used to prevent Hotspot optimization for
++ // the purpose of a constant-time check
++ int[] results = {0, 0}; // {missed #, matched #}
++ for (int i = 0; i <= 256;) {
++ for (int j = 0; j < len && i <= 256; j++, i++) { // j <= i
++ if (buf[offset + j] != pad) {
++ results[0]++; // mismatched padding data
++ } else {
++ results[1]++; // matched padding data
++ }
++ }
++ }
++
++ return results;
++ }
++
++ /*
++ * A constant-time check of the padding.
++ *
++ * NOTE that we are checking both the padding and the padLen bytes here.
++ *
++ * The caller MUST ensure that the bb parameter has remaining.
++ */
++ private static int[] checkPadding(ByteBuffer bb, byte pad) {
++
++ if (!bb.hasRemaining()) {
++ throw new RuntimeException("hasRemaining() must be positive");
++ }
++
++ // An array of hits is used to prevent Hotspot optimization for
++ // the purpose of a constant-time check.
++ int[] results = {0, 0}; // {missed #, matched #}
++ bb.mark();
++ for (int i = 0; i <= 256; bb.reset()) {
++ for (; bb.hasRemaining() && i <= 256; i++) {
++ if (bb.get() != pad) {
++ results[0]++; // mismatched padding data
++ } else {
++ results[1]++; // matched padding data
++ }
++ }
++ }
++
++ return results;
++ }
+
+ /*
+ * Typical TLS padding format for a 64 bit block cipher is as follows:
+@@ -412,86 +473,95 @@ final class CipherBox {
+ * as it makes the data a multiple of the block size
+ */
+ private static int removePadding(byte[] buf, int offset, int len,
+- int blockSize, ProtocolVersion protocolVersion)
+- throws BadPaddingException {
++ int tagLen, int blockSize,
++ ProtocolVersion protocolVersion) throws BadPaddingException {
++
+ // last byte is length byte (i.e. actual padding length - 1)
+ int padOffset = offset + len - 1;
+- int pad = buf[padOffset] & 0x0ff;
++ int padLen = buf[padOffset] & 0xFF;
+
+- int newlen = len - (pad + 1);
+- if (newlen < 0) {
+- throw new BadPaddingException("Padding length invalid: " + pad);
++ int newLen = len - (padLen + 1);
++ if ((newLen - tagLen) < 0) {
++ // If the buffer is not long enough to contain the padding plus
++ // a MAC tag, do a dummy constant-time padding check.
++ //
++ // Note that it is a dummy check, so we won't care about what is
++ // the actual padding data.
++ checkPadding(buf, offset, len, (byte)(padLen & 0xFF));
++
++ throw new BadPaddingException("Invalid Padding length: " + padLen);
+ }
+
++ // The padding data should be filled with the padding length value.
++ int[] results = checkPadding(buf, offset + newLen,
++ padLen + 1, (byte)(padLen & 0xFF));
+ if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
+- for (int i = 1; i <= pad; i++) {
+- int val = buf[padOffset - i] & 0xff;
+- if (val != pad) {
+- throw new BadPaddingException
+- ("Invalid TLS padding: " + val);
+- }
++ if (results[0] != 0) { // padding data has invalid bytes
++ throw new BadPaddingException("Invalid TLS padding data");
+ }
+ } else { // SSLv3
+ // SSLv3 requires 0 <= length byte < block size
+ // some implementations do 1 <= length byte <= block size,
+ // so accept that as well
+ // v3 does not require any particular value for the other bytes
+- if (pad > blockSize) {
+- throw new BadPaddingException("Invalid SSLv3 padding: " + pad);
++ if (padLen > blockSize) {
++ throw new BadPaddingException("Invalid SSLv3 padding");
+ }
+ }
+- return newlen;
++ return newLen;
+ }
+
+ /*
+ * Position/limit is equal the removed padding.
+ */
+ private static int removePadding(ByteBuffer bb,
+- int blockSize, ProtocolVersion protocolVersion)
+- throws BadPaddingException {
++ int tagLen, int blockSize,
++ ProtocolVersion protocolVersion) throws BadPaddingException {
+
+ int len = bb.remaining();
+ int offset = bb.position();
+
+ // last byte is length byte (i.e. actual padding length - 1)
+ int padOffset = offset + len - 1;
+- int pad = bb.get(padOffset) & 0x0ff;
++ int padLen = bb.get(padOffset) & 0xFF;
+
+- int newlen = len - (pad + 1);
+- if (newlen < 0) {
+- throw new BadPaddingException("Padding length invalid: " + pad);
++ int newLen = len - (padLen + 1);
++ if ((newLen - tagLen) < 0) {
++ // If the buffer is not long enough to contain the padding plus
++ // a MAC tag, do a dummy constant-time padding check.
++ //
++ // Note that it is a dummy check, so we won't care about what is
++ // the actual padding data.
++ checkPadding(bb.duplicate(), (byte)(padLen & 0xFF));
++
++ throw new BadPaddingException("Invalid Padding length: " + padLen);
+ }
+
+- /*
+- * We could zero the padding area, but not much useful
+- * information there.
+- */
++ // The padding data should be filled with the padding length value.
++ int[] results = checkPadding(
++ (ByteBuffer)bb.duplicate().position(offset + newLen),
++ (byte)(padLen & 0xFF));
+ if (protocolVersion.v >= ProtocolVersion.TLS10.v) {
+- bb.put(padOffset, (byte)0); // zero the padding.
+- for (int i = 1; i <= pad; i++) {
+- int val = bb.get(padOffset - i) & 0xff;
+- if (val != pad) {
+- throw new BadPaddingException
+- ("Invalid TLS padding: " + val);
+- }
++ if (results[0] != 0) { // padding data has invalid bytes
++ throw new BadPaddingException("Invalid TLS padding data");
+ }
+ } else { // SSLv3
+ // SSLv3 requires 0 <= length byte < block size
+ // some implementations do 1 <= length byte <= block size,
+ // so accept that as well
+ // v3 does not require any particular value for the other bytes
+- if (pad > blockSize) {
+- throw new BadPaddingException("Invalid SSLv3 padding: " + pad);
++ if (padLen > blockSize) {
++ throw new BadPaddingException("Invalid SSLv3 padding");
+ }
+ }
+
+ /*
+ * Reset buffer limit to remove padding.
+ */
+- bb.position(offset + newlen);
+- bb.limit(offset + newlen);
++ bb.position(offset + newLen);
++ bb.limit(offset + newLen);
+
+- return newlen;
++ return newLen;
+ }
+
+ /*
+@@ -502,4 +572,40 @@ final class CipherBox {
+ boolean isCBCMode() {
+ return isCBCMode;
+ }
++
++ /**
++ * Is the cipher null?
++ *
++ * @return true if the cipher is null, false otherwise.
++ */
++ boolean isNullCipher() {
++ return cipher == null;
++ }
++
++ /**
++ * Sanity check the length of a fragment before decryption.
++ *
++ * In CBC mode, check that the fragment length is one or multiple times
++ * of the block size of the cipher suite, and is at least one (one is the
++ * smallest size of padding in CBC mode) bigger than the tag size of the
++ * MAC algorithm.
++ *
++ * In non-CBC mode, check that the fragment length is not less than the
++ * tag size of the MAC algorithm.
++ *
++ * @return true if the length of a fragment matches above requirements
++ */
++ boolean sanityCheck(int tagLen, int fragmentLen) {
++ if (!isCBCMode) {
++ return fragmentLen >= tagLen;
++ }
++
++ if ((fragmentLen % blockSize) == 0) {
++ int minimal = tagLen + 1;
++ minimal = (minimal >= blockSize) ? minimal : blockSize;
++ return (fragmentLen >= minimal);
++ }
++
++ return false;
++ }
+ }
+diff --git a/src/share/classes/sun/security/ssl/CipherSuite.java b/src/share/classes/sun/security/ssl/CipherSuite.java
+--- jdk/src/share/classes/sun/security/ssl/CipherSuite.java
++++ jdk/src/share/classes/sun/security/ssl/CipherSuite.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -451,9 +451,18 @@ final class CipherSuite implements Compa
+ // size of the MAC value (and MAC key) in bytes
+ final int size;
+
+- MacAlg(String name, int size) {
++ // block size of the underlying hash algorithm
++ final int hashBlockSize;
++
++ // minimal padding size of the underlying hash algorithm
++ final int minimalPaddingSize;
++
++ MacAlg(String name, int size,
++ int hashBlockSize, int minimalPaddingSize) {
+ this.name = name;
+ this.size = size;
++ this.hashBlockSize = hashBlockSize;
++ this.minimalPaddingSize = minimalPaddingSize;
+ }
+
+ /**
+@@ -497,9 +506,9 @@ final class CipherSuite implements Compa
+ new BulkCipher(CIPHER_AES, 32, 16, true);
+
+ // MACs
+- final static MacAlg M_NULL = new MacAlg("NULL", 0);
+- final static MacAlg M_MD5 = new MacAlg("MD5", 16);
+- final static MacAlg M_SHA = new MacAlg("SHA", 20);
++ final static MacAlg M_NULL = new MacAlg("NULL", 0, 0, 0);
++ final static MacAlg M_MD5 = new MacAlg("MD5", 16, 64, 9);
++ final static MacAlg M_SHA = new MacAlg("SHA", 20, 64, 9);
+
+ static {
+ idMap = new HashMap<Integer,CipherSuite>();
+diff --git a/src/share/classes/sun/security/ssl/EngineInputRecord.java b/src/share/classes/sun/security/ssl/EngineInputRecord.java
+--- jdk/src/share/classes/sun/security/ssl/EngineInputRecord.java
++++ jdk/src/share/classes/sun/security/ssl/EngineInputRecord.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -177,71 +177,6 @@ final class EngineInputRecord extends In
+ }
+
+ /*
+- * Verifies and removes the MAC value. Returns true if
+- * the MAC checks out OK.
+- *
+- * On entry:
+- * position = beginning of app/MAC data
+- * limit = end of MAC data.
+- *
+- * On return:
+- * position = beginning of app data
+- * limit = end of app data
+- */
+- boolean checkMAC(MAC signer, ByteBuffer bb) {
+- if (internalData) {
+- return checkMAC(signer);
+- }
+-
+- int len = signer.MAClen();
+- if (len == 0) { // no mac
+- return true;
+- }
+-
+- /*
+- * Grab the original limit
+- */
+- int lim = bb.limit();
+-
+- /*
+- * Delineate the area to apply a MAC on.
+- */
+- int macData = lim - len;
+- bb.limit(macData);
+-
+- byte[] mac = signer.compute(contentType(), bb);
+-
+- if (len != mac.length) {
+- throw new RuntimeException("Internal MAC error");
+- }
+-
+- /*
+- * Delineate the MAC values, position was already set
+- * by doing the compute above.
+- *
+- * We could zero the MAC area, but not much useful information
+- * there anyway.
+- */
+- bb.position(macData);
+- bb.limit(lim);
+-
+- try {
+- for (int i = 0; i < len; i++) {
+- if (bb.get() != mac[i]) { // No BB.equals(byte []); !
+- return false;
+- }
+- }
+- return true;
+- } finally {
+- /*
+- * Position to the data.
+- */
+- bb.rewind();
+- bb.limit(macData);
+- }
+- }
+-
+- /*
+ * Pass the data down if it's internally cached, otherwise
+ * do it here.
+ *
+@@ -250,18 +185,161 @@ final class EngineInputRecord extends In
+ * If external data(app), return a new ByteBuffer with data to
+ * process.
+ */
+- ByteBuffer decrypt(CipherBox box, ByteBuffer bb)
+- throws BadPaddingException {
++ ByteBuffer decrypt(MAC signer,
++ CipherBox box, ByteBuffer bb) throws BadPaddingException {
+
+ if (internalData) {
+- decrypt(box);
++ decrypt(signer, box); // MAC is checked during decryption
+ return tmpBB;
+ }
+
+- box.decrypt(bb);
+- bb.rewind();
++ BadPaddingException reservedBPE = null;
++ int tagLen = signer.MAClen();
++ int cipheredLength = bb.remaining();
++
++ if (!box.isNullCipher()) {
++ // sanity check length of the ciphertext
++ if (!box.sanityCheck(tagLen, cipheredLength)) {
++ throw new BadPaddingException(
++ "ciphertext sanity check failed");
++ }
++
++ try {
++ // Note that the CipherBox.decrypt() does not change
++ // the capacity of the buffer.
++ box.decrypt(bb, tagLen);
++ } catch (BadPaddingException bpe) {
++ // RFC 2246 states that decryption_failed should be used
++ // for this purpose. However, that allows certain attacks,
++ // so we just send bad record MAC. We also need to make
++ // sure to always check the MAC to avoid a timing attack
++ // for the same issue. See paper by Vaudenay et al and the
++ // update in RFC 4346/5246.
++ //
++ // Failover to message authentication code checking.
++ reservedBPE = bpe;
++ } finally {
++ bb.rewind();
++ }
++ }
++
++ if (tagLen != 0) {
++ int macOffset = bb.limit() - tagLen;
++
++ // Note that although it is not necessary, we run the same MAC
++ // computation and comparison on the payload for both stream
++ // cipher and CBC block cipher.
++ if (bb.remaining() < tagLen) {
++ // negative data length, something is wrong
++ if (reservedBPE == null) {
++ reservedBPE = new BadPaddingException("bad record");
++ }
++
++ // set offset of the dummy MAC
++ macOffset = cipheredLength - tagLen;
++ bb.limit(cipheredLength);
++ }
++
++ // Run MAC computation and comparison on the payload.
++ if (checkMacTags(contentType(), bb, signer, false)) {
++ if (reservedBPE == null) {
++ reservedBPE = new BadPaddingException("bad record MAC");
++ }
++ }
++
++ // Run MAC computation and comparison on the remainder.
++ //
++ // It is only necessary for CBC block cipher. It is used to get a
++ // constant time of MAC computation and comparison on each record.
++ if (box.isCBCMode()) {
++ int remainingLen = calculateRemainingLen(
++ signer, cipheredLength, macOffset);
++
++ // NOTE: here we use the InputRecord.buf because I did not find
++ // an effective way to work on ByteBuffer when its capacity is
++ // less than remainingLen.
++
++ // NOTE: remainingLen may be bigger (less than 1 block of the
++ // hash algorithm of the MAC) than the cipheredLength. However,
++ // We won't need to worry about it because we always use a
++ // maximum buffer for every record. We need a change here if
++ // we use small buffer size in the future.
++ if (remainingLen > buf.length) {
++ // unlikely to happen, just a placehold
++ throw new RuntimeException(
++ "Internal buffer capacity error");
++ }
++
++ // Won't need to worry about the result on the remainder. And
++ // then we won't need to worry about what's actual data to
++ // check MAC tag on. We start the check from the header of the
++ // buffer so that we don't need to construct a new byte buffer.
++ checkMacTags(contentType(), buf, 0, remainingLen, signer, true);
++ }
++
++ bb.limit(macOffset);
++ }
++
++ // Is it a failover?
++ if (reservedBPE != null) {
++ throw reservedBPE;
++ }
+
+ return bb.slice();
++ }
++
++ /*
++ * Run MAC computation and comparison
++ *
++ * Please DON'T change the content of the ByteBuffer parameter!
++ */
++ private static boolean checkMacTags(byte contentType, ByteBuffer bb,
++ MAC signer, boolean isSimulated) {
++
++ int tagLen = signer.MAClen();
++ int lim = bb.limit();
++ int macData = lim - tagLen;
++
++ bb.limit(macData);
++ byte[] hash = signer.compute(contentType, bb, isSimulated);
++ if (hash == null || tagLen != hash.length) {
++ // Something is wrong with MAC implementation.
++ throw new RuntimeException("Internal MAC error");
++ }
++
++ bb.position(macData);
++ bb.limit(lim);
++ try {
++ int[] results = compareMacTags(bb, hash);
++ return (results[0] != 0);
++ } finally {
++ bb.rewind();
++ bb.limit(macData);
++ }
++ }
++
++ /*
++ * A constant-time comparison of the MAC tags.
++ *
++ * Please DON'T change the content of the ByteBuffer parameter!
++ */
++ private static int[] compareMacTags(ByteBuffer bb, byte[] tag) {
++
++ // An array of hits is used to prevent Hotspot optimization for
++ // the purpose of a constant-time check.
++ int[] results = {0, 0}; // {missed #, matched #}
++
++ // The caller ensures there are enough bytes available in the buffer.
++ // So we won't need to check the remaining of the buffer.
++ for (int i = 0; i < tag.length; i++) {
++ if (bb.get() != tag[i]) {
++ results[0]++; // mismatched bytes
++ } else {
++ results[1]++; // matched bytes
++ }
++ }
++
++ return results;
+ }
+
+ /*
+diff --git a/src/share/classes/sun/security/ssl/EngineOutputRecord.java b/src/share/classes/sun/security/ssl/EngineOutputRecord.java
+--- jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java
++++ jdk/src/share/classes/sun/security/ssl/EngineOutputRecord.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -120,7 +120,7 @@ final class EngineOutputRecord extends O
+ throws IOException {
+
+ if (signer.MAClen() != 0) {
+- byte[] hash = signer.compute(contentType(), bb);
++ byte[] hash = signer.compute(contentType(), bb, false);
+
+ /*
+ * position was advanced to limit in compute above.
+diff --git a/src/share/classes/sun/security/ssl/InputRecord.java b/src/share/classes/sun/security/ssl/InputRecord.java
+--- jdk/src/share/classes/sun/security/ssl/InputRecord.java
++++ jdk/src/share/classes/sun/security/ssl/InputRecord.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -135,43 +135,173 @@ class InputRecord extends ByteArrayInput
+ return handshakeHash;
+ }
+
+- /*
+- * Verify and remove the MAC ... used for all records.
+- */
+- boolean checkMAC(MAC signer) {
+- int len = signer.MAClen();
+- if (len == 0) { // no mac
+- return true;
++ void decrypt(MAC signer, CipherBox box) throws BadPaddingException {
++
++ BadPaddingException reservedBPE = null;
++ int tagLen = signer.MAClen();
++ int cipheredLength = count - headerSize;
++
++ if (!box.isNullCipher()) {
++ // sanity check length of the ciphertext
++ if (!box.sanityCheck(tagLen, cipheredLength)) {
++ throw new BadPaddingException(
++ "ciphertext sanity check failed");
++ }
++
++ try {
++ // Note that the CipherBox.decrypt() does not change
++ // the capacity of the buffer.
++ count = headerSize +
++ box.decrypt(buf, headerSize, cipheredLength, tagLen);
++ } catch (BadPaddingException bpe) {
++ // RFC 2246 states that decryption_failed should be used
++ // for this purpose. However, that allows certain attacks,
++ // so we just send bad record MAC. We also need to make
++ // sure to always check the MAC to avoid a timing attack
++ // for the same issue. See paper by Vaudenay et al and the
++ // update in RFC 4346/5246.
++ //
++ // Failover to message authentication code checking.
++ reservedBPE = bpe;
++ }
+ }
+
+- int offset = count - len;
++ if (tagLen != 0) {
++ int macOffset = count - tagLen;
++ int contentLen = macOffset - headerSize;
+
+- if (offset < headerSize) {
+- // data length would be negative, something is wrong
+- return false;
++ // Note that although it is not necessary, we run the same MAC
++ // computation and comparison on the payload for both stream
++ // cipher and CBC block cipher.
++ if (contentLen < 0) {
++ // negative data length, something is wrong
++ if (reservedBPE == null) {
++ reservedBPE = new BadPaddingException("bad record");
++ }
++
++ // set offset of the dummy MAC
++ macOffset = headerSize + cipheredLength - tagLen;
++ contentLen = macOffset - headerSize;
++ }
++
++ count -= tagLen; // Set the count before any MAC checking
++ // exception occurs, so that the following
++ // process can read the actual decrypted
++ // content (minus the MAC) in the fragment
++ // if necessary.
++
++ // Run MAC computation and comparison on the payload.
++ if (checkMacTags(contentType(),
++ buf, headerSize, contentLen, signer, false)) {
++ if (reservedBPE == null) {
++ reservedBPE = new BadPaddingException("bad record MAC");
++ }
++ }
++
++ // Run MAC computation and comparison on the remainder.
++ //
++ // It is only necessary for CBC block cipher. It is used to get a
++ // constant time of MAC computation and comparison on each record.
++ if (box.isCBCMode()) {
++ int remainingLen = calculateRemainingLen(
++ signer, cipheredLength, contentLen);
++
++ // NOTE: remainingLen may be bigger (less than 1 block of the
++ // hash algorithm of the MAC) than the cipheredLength. However,
++ // We won't need to worry about it because we always use a
++ // maximum buffer for every record. We need a change here if
++ // we use small buffer size in the future.
++ if (remainingLen > buf.length) {
++ // unlikely to happen, just a placehold
++ throw new RuntimeException(
++ "Internal buffer capacity error");
++ }
++
++ // Won't need to worry about the result on the remainder. And
++ // then we won't need to worry about what's actual data to
++ // check MAC tag on. We start the check from the header of the
++ // buffer so that we don't need to construct a new byte buffer.
++ checkMacTags(contentType(), buf, 0, remainingLen, signer, true);
++ }
+ }
+
+- byte[] mac = signer.compute(contentType(), buf,
+- headerSize, offset - headerSize);
++ // Is it a failover?
++ if (reservedBPE != null) {
++ throw reservedBPE;
++ }
++ }
+
+- if (len != mac.length) {
++ /*
++ * Run MAC computation and comparison
++ *
++ * Please DON'T change the content of the byte buffer parameter!
++ */
++ static boolean checkMacTags(byte contentType, byte[] buffer,
++ int offset, int contentLen, MAC signer, boolean isSimulated) {
++
++ int tagLen = signer.MAClen();
++ byte[] hash = signer.compute(
++ contentType, buffer, offset, contentLen, isSimulated);
++ if (hash == null || tagLen != hash.length) {
++ // Something is wrong with MAC implementation.
+ throw new RuntimeException("Internal MAC error");
+ }
+
+- for (int i = 0; i < len; i++) {
+- if (buf[offset + i] != mac[i]) {
+- return false;
++ int[] results = compareMacTags(buffer, offset + contentLen, hash);
++ return (results[0] != 0);
++ }
++
++ /*
++ * A constant-time comparison of the MAC tags.
++ *
++ * Please DON'T change the content of the byte buffer parameter!
++ */
++ private static int[] compareMacTags(
++ byte[] buffer, int offset, byte[] tag) {
++
++ // An array of hits is used to prevent Hotspot optimization for
++ // the purpose of a constant-time check.
++ int[] results = {0, 0}; // {missed #, matched #}
++
++ // The caller ensures there are enough bytes available in the buffer.
++ // So we won't need to check the length of the buffer.
++ for (int i = 0; i < tag.length; i++) {
++ if (buffer[offset + i] != tag[i]) {
++ results[0]++; // mismatched bytes
++ } else {
++ results[1]++; // matched bytes
+ }
+ }
+- count -= len;
+- return true;
++
++ return results;
+ }
+
+- void decrypt(CipherBox box) throws BadPaddingException {
+- int len = count - headerSize;
+- count = headerSize + box.decrypt(buf, headerSize, len);
++ /*
++ * Calculate the length of a dummy buffer to run MAC computation
++ * and comparison on the remainder.
++ *
++ * The caller MUST ensure that the fullLen is not less than usedLen.
++ */
++ static int calculateRemainingLen(
++ MAC signer, int fullLen, int usedLen) {
++
++ int blockLen = signer.hashBlockLen();
++ int minimalPaddingLen = signer.minimalPaddingLen();
++
++ // (blockLen - minimalPaddingLen) is the maximum message size of
++ // the last block of hash function operation. See FIPS 180-4, or
++ // MD5 specification.
++ fullLen += 13 - (blockLen - minimalPaddingLen);
++ usedLen += 13 - (blockLen - minimalPaddingLen);
++
++ // Note: fullLen is always not less than usedLen, and blockLen
++ // is always bigger than minimalPaddingLen, so we don't worry
++ // about negative values. 0x01 is added to the result to ensure
++ // that the return value is positive. The extra one byte does
++ // not impact the overall MAC compression function evaluations.
++ return 0x01 + (int)(Math.ceil(fullLen/(1.0d * blockLen)) -
++ Math.ceil(usedLen/(1.0d * blockLen))) * signer.hashBlockLen();
+ }
+-
+
+ /*
+ * Well ... hello_request messages are _never_ hashed since we can't
+diff --git a/src/share/classes/sun/security/ssl/MAC.java b/src/share/classes/sun/security/ssl/MAC.java
+--- jdk/src/share/classes/sun/security/ssl/MAC.java
++++ jdk/src/share/classes/sun/security/ssl/MAC.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2007, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -44,7 +44,8 @@ import static sun.security.ssl.CipherSui
+ * one of several keyed hashes, as associated with the cipher suite and
+ * protocol version. (SSL v3.0 uses one construct, TLS uses another.)
+ *
+- * <P>NOTE: MAC computation is the only place in the SSL protocol that the
++ * <P>
++ * NOTE: MAC computation is the only place in the SSL protocol that the
+ * sequence number is used. It's also reset to zero with each change of
+ * a cipher spec, so this is the only place this state is needed.
+ *
+@@ -129,15 +130,31 @@ final class MAC {
+ }
+
+ /**
++ * Returns the hash function block length of the MAC alorithm.
++ */
++ int hashBlockLen() {
++ return macAlg.hashBlockSize;
++ }
++
++ /**
++ * Returns the hash function minimal padding length of the MAC alorithm.
++ */
++ int minimalPaddingLen() {
++ return macAlg.minimalPaddingSize;
++ }
++
++ /**
+ * Computes and returns the MAC for the data in this byte array.
+ *
+ * @param type record type
+ * @param buf compressed record on which the MAC is computed
+ * @param offset start of compressed record data
+ * @param len the size of the compressed record
++ * @param isSimulated if true, simulate the the MAC computation
+ */
+- final byte[] compute(byte type, byte buf[], int offset, int len) {
+- return compute(type, null, buf, offset, len);
++ final byte[] compute(byte type, byte buf[],
++ int offset, int len, boolean isSimulated) {
++ return compute(type, null, buf, offset, len, isSimulated);
+ }
+
+ /**
+@@ -150,9 +167,10 @@ final class MAC {
+ * @param type record type
+ * @param bb a ByteBuffer in which the position and limit
+ * demarcate the data to be MAC'd.
++ * @param isSimulated if true, simulate the the MAC computation
+ */
+- final byte[] compute(byte type, ByteBuffer bb) {
+- return compute(type, bb, null, 0, bb.remaining());
++ final byte[] compute(byte type, ByteBuffer bb, boolean isSimulated) {
++ return compute(type, bb, null, 0, bb.remaining(), isSimulated);
+ }
+
+ // increment the sequence number in the block array
+@@ -168,18 +186,22 @@ final class MAC {
+ * Compute based on either buffer type, either bb.position/limit
+ * or buf/offset/len.
+ */
+- private byte[] compute(byte type, ByteBuffer bb, byte[] buf, int offset, int len) {
++ private byte[] compute(byte type, ByteBuffer bb, byte[] buf,
++ int offset, int len, boolean isSimulated) {
+
+ if (macSize == 0) {
+ return nullMAC;
+ }
+
+- block[BLOCK_OFFSET_TYPE] = type;
+- block[block.length - 2] = (byte)(len >> 8);
+- block[block.length - 1] = (byte)(len );
++ // MUST NOT increase the sequence number for a simulated computation.
++ if (!isSimulated) {
++ block[BLOCK_OFFSET_TYPE] = type;
++ block[block.length - 2] = (byte)(len >> 8);
++ block[block.length - 1] = (byte)(len );
+
+- mac.update(block);
+- incrementSequenceNumber();
++ mac.update(block);
++ incrementSequenceNumber();
++ }
+
+ // content
+ if (bb != null) {
+diff --git a/src/share/classes/sun/security/ssl/OutputRecord.java b/src/share/classes/sun/security/ssl/OutputRecord.java
+--- jdk/src/share/classes/sun/security/ssl/OutputRecord.java
++++ jdk/src/share/classes/sun/security/ssl/OutputRecord.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -204,7 +204,7 @@ class OutputRecord extends ByteArrayOutp
+ }
+ if (signer.MAClen() != 0) {
+ byte[] hash = signer.compute(contentType, buf,
+- headerSize, count - headerSize);
++ headerSize, count - headerSize, false);
+ write(hash);
+ }
+ }
+diff --git a/src/share/classes/sun/security/ssl/SSLEngineImpl.java b/src/share/classes/sun/security/ssl/SSLEngineImpl.java
+--- jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
++++ jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -919,34 +919,13 @@ final public class SSLEngineImpl extends
+ * throw a fatal alert if the integrity check fails.
+ */
+ try {
+- decryptedBB = inputRecord.decrypt(readCipher, readBB);
++ decryptedBB = inputRecord.decrypt(readMAC, readCipher, readBB);
+ } catch (BadPaddingException e) {
+- // RFC 2246 states that decryption_failed should be used
+- // for this purpose. However, that allows certain attacks,
+- // so we just send bad record MAC. We also need to make
+- // sure to always check the MAC to avoid a timing attack
+- // for the same issue. See paper by Vaudenay et al.
+- //
+- // rewind the BB if necessary.
+- readBB.rewind();
+-
+- inputRecord.checkMAC(readMAC, readBB);
+-
+- // use the same alert types as for MAC failure below
+ byte alertType = (inputRecord.contentType() ==
+ Record.ct_handshake) ?
+ Alerts.alert_handshake_failure :
+ Alerts.alert_bad_record_mac;
+- fatal(alertType, "Invalid padding", e);
+- }
+-
+- if (!inputRecord.checkMAC(readMAC, decryptedBB)) {
+- if (inputRecord.contentType() == Record.ct_handshake) {
+- fatal(Alerts.alert_handshake_failure,
+- "bad handshake record MAC");
+- } else {
+- fatal(Alerts.alert_bad_record_mac, "bad record MAC");
+- }
++ fatal(alertType, e.getMessage(), e);
+ }
+
+ // if (!inputRecord.decompress(c))
+diff --git a/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/src/share/classes/sun/security/ssl/SSLSocketImpl.java
+--- jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
++++ jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -922,27 +922,12 @@ final public class SSLSocketImpl extends
+ * throw a fatal alert if the integrity check fails.
+ */
+ try {
+- r.decrypt(readCipher);
++ r.decrypt(readMAC, readCipher);
+ } catch (BadPaddingException e) {
+- // RFC 2246 states that decryption_failed should be used
+- // for this purpose. However, that allows certain attacks,
+- // so we just send bad record MAC. We also need to make
+- // sure to always check the MAC to avoid a timing attack
+- // for the same issue. See paper by Vaudenay et al.
+- r.checkMAC(readMAC);
+- // use the same alert types as for MAC failure below
+ byte alertType = (r.contentType() == Record.ct_handshake)
+ ? Alerts.alert_handshake_failure
+ : Alerts.alert_bad_record_mac;
+- fatal(alertType, "Invalid padding", e);
+- }
+- if (!r.checkMAC(readMAC)) {
+- if (r.contentType() == Record.ct_handshake) {
+- fatal(Alerts.alert_handshake_failure,
+- "bad handshake record MAC");
+- } else {
+- fatal(Alerts.alert_bad_record_mac, "bad record MAC");
+- }
++ fatal(alertType, e.getMessage(), e);
+ }
+
+ // if (!r.decompress(c))
diff --git a/java/openjdk6/files/icedtea/security/20130219/8007688.patch b/java/openjdk6/files/icedtea/security/20130219/8007688.patch
new file mode 100644
index 000000000000..bc13a982ab4f
--- /dev/null
+++ b/java/openjdk6/files/icedtea/security/20130219/8007688.patch
@@ -0,0 +1,130 @@
+# HG changeset patch
+# User coffeys
+# Date 1360873966 0
+# Node ID 617e68a3948824283f15c36fcd8cf264c1dd0a99
+# Parent 25e83b78298b71abb46eb5a337ed7bddef418ca4
+8007688: Blacklist known bad certificate
+Reviewed-by: mullan
+
+diff --git a/src/share/classes/sun/security/util/UntrustedCertificates.java b/src/share/classes/sun/security/util/UntrustedCertificates.java
+--- jdk/src/share/classes/sun/security/util/UntrustedCertificates.java
++++ jdk/src/share/classes/sun/security/util/UntrustedCertificates.java
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
++ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+@@ -739,5 +739,111 @@ public final class UntrustedCertificates
+ "B8WfedLHjFW/TMcnXlEWKz4=\n" +
+ "-----END CERTIFICATE-----");
+
++ //
++ // Revoked DigiCert code signing certificates used to sign malware
++ //
++
++ // Subject: CN=Buster Paper Comercial Ltda,
++ // O=Buster Paper Comercial Ltda,
++ // L=S?o Jos? Dos Campos,
++ // ST=S?o Paulo,
++ // C=BR
++ // Issuer: CN=DigiCert Assured ID Code Signing CA-1,
++ // OU=www.digicert.com,
++ // O=DigiCert Inc,
++ // C=US
++ // Serial: 07:b4:4c:db:ff:fb:78:de:05:f4:26:16:72:a6:73:12
++ add("buster-paper-comercial-ltda-72A67312",
++ "-----BEGIN CERTIFICATE-----\n" +
++ "MIIGwzCCBaugAwIBAgIQB7RM2//7eN4F9CYWcqZzEjANBgkqhkiG9w0BAQUFADBv\n" +
++ "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" +
++ "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" +
++ "ZGUgU2lnbmluZyBDQS0xMB4XDTEzMDExNzAwMDAwMFoXDTE0MDEyMjEyMDAwMFow\n" +
++ "gY4xCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMR4wHAYDVQQHDBVT\n" +
++ "w6NvIEpvc8OpIERvcyBDYW1wb3MxJDAiBgNVBAoTG0J1c3RlciBQYXBlciBDb21l\n" +
++ "cmNpYWwgTHRkYTEkMCIGA1UEAxMbQnVzdGVyIFBhcGVyIENvbWVyY2lhbCBMdGRh\n" +
++ "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzO0l6jWIpEfO2oUpVHpL\n" +
++ "HETj5lzivNb0S9jKHgGJax917czh81PnGTxwxFXd6gLJuy/XFHvmiSi8g8jzlymn\n" +
++ "2Ji5zQ3CPaz7nomJokSUDlMVJ2qYWtctw4jrdjuI4qtn+koXXUFkWjkf8h8251I4\n" +
++ "tUs7S49HE2Go5owCYP3byajj7fsFAYR/Xb7TdVtndkZsUB/YgOjHovyACjouaNCi\n" +
++ "mDiRyQ6zLLjZGiyeD65Yiseuhp5b8/BL5h1p7w76QYMYMVQNAdtDKut2R8MBpuWf\n" +
++ "Ny7Eoi0x/gm1p9X5Rcl5aN7K0G4UtTAJKbkuUfXddsyFoM0Nx8uo8SgNQ8Y/X5Jx\n" +
++ "BwIDAQABo4IDOTCCAzUwHwYDVR0jBBgwFoAUe2jOKarAF75JeuHlP9an90WPNTIw\n" +
++ "HQYDVR0OBBYEFFLZ3n5nt/Eer7n1bvtOqMb1qKO5MA4GA1UdDwEB/wQEAwIHgDAT\n" +
++ "BgNVHSUEDDAKBggrBgEFBQcDAzBzBgNVHR8EbDBqMDOgMaAvhi1odHRwOi8vY3Js\n" +
++ "My5kaWdpY2VydC5jb20vYXNzdXJlZC1jcy0yMDExYS5jcmwwM6AxoC+GLWh0dHA6\n" +
++ "Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9hc3N1cmVkLWNzLTIwMTFhLmNybDCCAcQGA1Ud\n" +
++ "IASCAbswggG3MIIBswYJYIZIAYb9bAMBMIIBpDA6BggrBgEFBQcCARYuaHR0cDov\n" +
++ "L3d3dy5kaWdpY2VydC5jb20vc3NsLWNwcy1yZXBvc2l0b3J5Lmh0bTCCAWQGCCsG\n" +
++ "AQUFBwICMIIBVh6CAVIAQQBuAHkAIAB1AHMAZQAgAG8AZgAgAHQAaABpAHMAIABD\n" +
++ "AGUAcgB0AGkAZgBpAGMAYQB0AGUAIABjAG8AbgBzAHQAaQB0AHUAdABlAHMAIABh\n" +
++ "AGMAYwBlAHAAdABhAG4AYwBlACAAbwBmACAAdABoAGUAIABEAGkAZwBpAEMAZQBy\n" +
++ "AHQAIABDAFAALwBDAFAAUwAgAGEAbgBkACAAdABoAGUAIABSAGUAbAB5AGkAbgBn\n" +
++ "ACAAUABhAHIAdAB5ACAAQQBnAHIAZQBlAG0AZQBuAHQAIAB3AGgAaQBjAGgAIABs\n" +
++ "AGkAbQBpAHQAIABsAGkAYQBiAGkAbABpAHQAeQAgAGEAbgBkACAAYQByAGUAIABp\n" +
++ "AG4AYwBvAHIAcABvAHIAYQB0AGUAZAAgAGgAZQByAGUAaQBuACAAYgB5ACAAcgBl\n" +
++ "AGYAZQByAGUAbgBjAGUALjCBggYIKwYBBQUHAQEEdjB0MCQGCCsGAQUFBzABhhho\n" +
++ "dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTAYIKwYBBQUHMAKGQGh0dHA6Ly9jYWNl\n" +
++ "cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRENvZGVTaWduaW5nQ0Et\n" +
++ "MS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQUFAAOCAQEAPTTQvpOIikXI\n" +
++ "hTLnNbajaFRR5GhQpTzUNgBfF9VYSlNw/wMjpGsrh5RxaJCip52jbehmTgjMRhft\n" +
++ "jRYyml44PAVsCcR9uEoDpCZYpI1fHI1R+F8jd1C9rqprbSwwOG4xlg4SmvTHYs6e\n" +
++ "gBItQ/1p9XY+Sf4Wv1qOuOFL1qvV/5VyR2zdlOQCmKCeMgxt6a/tHLBDiAA67D44\n" +
++ "/vfdoNJl0CU2It0PO60jdCPFNWIRcxL+OSDqAoePeUC7xQ+JsTEIxuUE8+d6w6fc\n" +
++ "BV2mYb1flh22t46GLjh4gyo7xw3aL6L0L0jzlTT6IcEw6NIbaPbIKj/npQnHobYj\n" +
++ "XMuKLxbh7g==\n" +
++ "-----END CERTIFICATE-----");
++
++ // Subject: CN=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME,
++ // O=BUSTER ASSISTENCIA TECNICA ELETRONICA LTDA - ME,
++ // L=S?o Paulo,
++ // ST=S?o Paulo,
++ // C=BR
++ // Issuer: CN=DigiCert Assured ID Code Signing CA-1,
++ // OU=www.digicert.com,
++ // O=DigiCert Inc,
++ // C=US
++ // Serial: 0a:38:9b:95:ee:73:6d:d1:3b:c0:ed:74:3f:d7:4d:2f
++ add("buster-assistencia-tecnica-electronica-ltda-3FD74D2F",
++ "-----BEGIN CERTIFICATE-----\n" +
++ "MIIG4DCCBcigAwIBAgIQCjible5zbdE7wO10P9dNLzANBgkqhkiG9w0BAQUFADBv\n" +
++ "MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n" +
++ "d3cuZGlnaWNlcnQuY29tMS4wLAYDVQQDEyVEaWdpQ2VydCBBc3N1cmVkIElEIENv\n" +
++ "ZGUgU2lnbmluZyBDQS0xMB4XDTEyMTEwOTAwMDAwMFoXDTEzMTExNDEyMDAwMFow\n" +
++ "gasxCzAJBgNVBAYTAkJSMRMwEQYDVQQIDApTw6NvIFBhdWxvMRMwEQYDVQQHDApT\n" +
++ "w6NvIFBhdWxvMTgwNgYDVQQKEy9CVVNURVIgQVNTSVNURU5DSUEgVEVDTklDQSBF\n" +
++ "TEVUUk9OSUNBIExUREEgLSBNRTE4MDYGA1UEAxMvQlVTVEVSIEFTU0lTVEVOQ0lB\n" +
++ "IFRFQ05JQ0EgRUxFVFJPTklDQSBMVERBIC0gTUUwggEiMA0GCSqGSIb3DQEBAQUA\n" +
++ "A4IBDwAwggEKAoIBAQDAqNeEs5/B2CTXGjTOkUIdu6jV6qulOZwdw4sefHWYj1UR\n" +
++ "4z6zPk9kjpUgbnb402RFq88QtfInwddZ/wXn9OxMtDd/3TnC7HrhNS7ga79ZFL2V\n" +
++ "JnmzKHum2Yvh0q82QEJ9tHBR2X9VdKpUIH08Zs3k6cWWM1H0YX0cxA/HohhesQJW\n" +
++ "kwJ3urOIJiH/HeByDk8a1NS8safcCxk5vxvW4WvCg43iT09LeHY5Aa8abKw8lqVb\n" +
++ "0tD5ZSIjdmdj3TT1U37iAHLLRM2DXbxfdbhouUX1c5U1ZHAMA67HwjKiseOiDaHj\n" +
++ "NUGbC37C+cgbc9VVM/cURD8WvS0Kj6fQv7F2QtJDAgMBAAGjggM5MIIDNTAfBgNV\n" +
++ "HSMEGDAWgBR7aM4pqsAXvkl64eU/1qf3RY81MjAdBgNVHQ4EFgQU88EXKAyDsh30\n" +
++ "o9+Gu9a4xUy+FSMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD\n" +
++ "MHMGA1UdHwRsMGowM6AxoC+GLWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9hc3N1\n" +
++ "cmVkLWNzLTIwMTFhLmNybDAzoDGgL4YtaHR0cDovL2NybDQuZGlnaWNlcnQuY29t\n" +
++ "L2Fzc3VyZWQtY3MtMjAxMWEuY3JsMIIBxAYDVR0gBIIBuzCCAbcwggGzBglghkgB\n" +
++ "hv1sAwEwggGkMDoGCCsGAQUFBwIBFi5odHRwOi8vd3d3LmRpZ2ljZXJ0LmNvbS9z\n" +
++ "c2wtY3BzLXJlcG9zaXRvcnkuaHRtMIIBZAYIKwYBBQUHAgIwggFWHoIBUgBBAG4A\n" +
++ "eQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMAZQByAHQAaQBmAGkAYwBhAHQA\n" +
++ "ZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEAYwBjAGUAcAB0AGEAbgBjAGUA\n" +
++ "IABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIAdAAgAEMAUAAvAEMAUABTACAA\n" +
++ "YQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcAIABQAGEAcgB0AHkAIABBAGcA\n" +
++ "cgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwAaQBtAGkAdAAgAGwAaQBhAGIA\n" +
++ "aQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkAbgBjAG8AcgBwAG8AcgBhAHQA\n" +
++ "ZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUAZgBlAHIAZQBuAGMAZQAuMIGC\n" +
++ "BggrBgEFBQcBAQR2MHQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0\n" +
++ "LmNvbTBMBggrBgEFBQcwAoZAaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0Rp\n" +
++ "Z2lDZXJ0QXNzdXJlZElEQ29kZVNpZ25pbmdDQS0xLmNydDAMBgNVHRMBAf8EAjAA\n" +
++ "MA0GCSqGSIb3DQEBBQUAA4IBAQAei1QmiXepje8OIfo/WonD4MIXgpPr2dfRaquQ\n" +
++ "A8q63OpTRSveyqdQDCSPpDRF/nvO1Y30yksZvIH1tNBsW5LBdxAKN3lFdBlqBwtE\n" +
++ "Q3jHc0KVVYRJ0FBaGE/PJHmRajscdAhYIcMPhTga0u0tDK+wOHEq3993dfl6yHjA\n" +
++ "XHU2iW5pnk75ZoE39zALD5eKXT8ZXrET5c3XUFJKWA+XuGmdmyzqo0Au49PanBv9\n" +
++ "UlZnabYfqoMArqMS0tGSX4cGgi9/2E+pHG9BX4sFW+ZDumroOA2pxyMWEKjxePEL\n" +
++ "zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" +
++ "-----END CERTIFICATE-----");
++
+ }
+ }
diff --git a/java/openjdk6/files/patch-set b/java/openjdk6/files/patch-set
index ae59dafe8471..0fabe80c09e8 100644
--- a/java/openjdk6/files/patch-set
+++ b/java/openjdk6/files/patch-set
@@ -11233,9 +11233,9 @@
typedef unsigned long uLong;
#endif
+#endif
- #ifdef _MSC_VER
- typedef LONGLONG jlong;
- typedef DWORDLONG julong;
+ #ifdef _MSC_VER
+ typedef LONGLONG jlong;
+ typedef DWORDLONG julong;
--- jdk/src/share/native/com/sun/java/util/jar/pack/main.cpp
+++ jdk/src/share/native/com/sun/java/util/jar/pack/main.cpp
@@ -33,9 +33,14 @@