changeset 6040:d4bf5c15837c jdk7u14-b22

Merge
author lana
date Thu, 18 Apr 2013 14:38:37 -0700
parents 87c6c2882d3f 360347165596
children d3fef82a86bb 39a85b6373fa
files .hgtags
diffstat 268 files changed, 8415 insertions(+), 1521 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Wed Apr 17 12:13:43 2013 -0700
+++ b/.hgtags	Thu Apr 18 14:38:37 2013 -0700
@@ -213,6 +213,8 @@
 901c290c9c8b495a2696f10a87523363239d001b jdk7u9-b02
 7302c386ca9c6cd20c27d0a2adb0b142f679d6b3 jdk7u9-b04
 ffad06d7009576c3098705e05452ebc309a59e56 jdk7u9-b05
+3b1a395f1948c7063d342a0c3e26c8450c6e7acb jdk7u9-b31
+77f7e5f13763fed11afb6e12840d78bd55c2d979 jdk7u9-b32
 c1efb11d7db509dafd7882811b2562ba593f6431 jdk7u10-b10
 0243e41000c6f76654725cac31ffdc95633c63e7 jdk7u10-b11
 c86a49dd4a0dca3a56f00429cfcffb2ad5f2a224 jdk7u10-b12
@@ -223,8 +225,11 @@
 a1c5bac982a6d4aa58f551cb46cde53f526aca48 jdk7u10-b17
 115d1e4365293846bbc911cf312886c471e37fbd jdk7u10-b18
 84218dff5e4c7bc00fd9266769c0d12bdde866f5 jdk7u10-b30
+3515fd583ede49b125a0b5f72ac403b3984d199b jdk7u10-b31
 ecc14534318c80dc7612c8b1d328a67849c5b07f jdk7u11-b20
 d9969a953f693f5760b1d2759f11a2cb222e4f20 jdk7u11-b21
+c7282a85c6bcc717b7099a03db028ecb77b41098 jdk7u11-b32
+8fd5e105c6a288b01f8809a6c84a5a64a63f39be jdk7u11-b33
 84da14fbd3ac12a3c6734fa4b6a366cfde1426af jdk7u11-b03
 932ef74edbf984299a68c126c70bbe04ffbde9b5 jdk7u11-b04
 fb35fb91f6478f8076993bcc4112746bcd9a2985 jdk7u11-b05
@@ -262,9 +267,23 @@
 835448d525a10bb826f4f7ebe272fc410bdb0f5d jdk7u15-b01
 0443fe2d8023111b52f4c8db32e038f4a5a9f373 jdk7u15-b02
 70b0f967c0649c501fb14a27bb06daeccbff823a jdk7u15-b30
+9f20468265071696b4d2ece286bc228a4d5a302a jdk7u15-b31
+3ef25219292f57ea56ac0ef338ceadf5fd098bdf jdk7u15-b33
 87e45d30e24db726ea03b20d861f0a025e437641 jdk7u15-b03
 b5ae6fb92e71df1833221026efe50863593bf682 jdk7u17-b01
 b130c8cfecfc552614047b3244d5d94439827fcd jdk7u17-b02
+a474615061bf610105a426780a7ac4c95bd76456 jdk7u17-b30
+1ad6f413e250bd2671b4908e232bd0d244c917a7 jdk7u17-b31
+8261e56b7f91c7553e8485b206bdc9030a3546e4 jdk7u21-b01
+af6be9d7aed7c323858932c908b049f4bcdb6a3e jdk7u21-b05
+ffc1454e644a39265cd6d80ef4b4c12c5dbf35c9 jdk7u21-b06
+b453d9be6b3f5496aa217ade7478d3b7fa32b13b jdk7u21-b07
+de4e41c5c549136209a68154d847cf126e563b88 jdk7u21-b08
+622aedcdda610a148a082558a0c25d8b3b735d07 jdk7u21-b09
+f447c3bbf074439ece0ce9fea82c857f93817801 jdk7u21-b10
+f9323b9d020ce8d313af2d2e2682e2b6cabcc40d jdk7u21-b11
+08ed0bfc9668f04ce4e3803f16aad92f6e50f885 jdk7u21-b30
+f3cf02a53684b9fbefabb212c80dfbea0c27f113 jdk7u21-b12
 555ea0c4e9567294d37793777d521902d43f1a39 jdk7u14-b16
 950fa827c2ec8a3a1ceba755994ae59016daa621 jdk7u14-b17
 e7ba683c15009b166127c3437fe9fbaf4eee6efe jdk7u14-b18
--- a/make/common/Release.gmk	Wed Apr 17 12:13:43 2013 -0700
+++ b/make/common/Release.gmk	Thu Apr 18 14:38:37 2013 -0700
@@ -244,7 +244,7 @@
 trim-image-jre trim-image-jdk \
 identify-image-jre identify-image-jdk \
 process-image-jre process-image-jdk \
-compare-image \
+compare-image  \
 sec-files sec-files-win jgss-files server-jdk-image ::
 	@$(ECHO) ">>>Making "$@" @ `$(DATE)` ..."
 
@@ -254,9 +254,9 @@
 images:: sanity-images post-sanity-images  \
 	 $(INITIAL_IMAGE_JRE) $(EXTRA_JRE_TARGETS) $(INITIAL_IMAGE_JDK) \
 	 trim-image-jre trim-image-jdk \
-	identify-image-jre identify-image-jdk \
+	 identify-image-jre identify-image-jdk \
 	 process-image-jre process-image-jdk sec-files sec-files-win \
-	 jgss-files $(EXTRA_IMAGE_TARGETS) server-jdk-image
+	jgss-files $(EXTRA_IMAGE_TARGETS) server-jdk-image 
 else
 
 images:: sanity-images post-sanity-images  \
@@ -940,7 +940,7 @@
 	done
 	$(RM) $(JRE_BIN_LIST)
 
-# Duplicate current j2re-image contents to server-j2re-image
+# Duplicate current j2re-image contents to server-j2re-image 
 # for the server version of jre, before deploy build
 server-jdk-image::
 ifeq ($(PLATFORM), macosx)
--- a/make/sun/font/FILES_c.gmk	Wed Apr 17 12:13:43 2013 -0700
+++ b/make/sun/font/FILES_c.gmk	Thu Apr 18 14:38:37 2013 -0700
@@ -106,7 +106,21 @@
         OpenTypeLayoutEngine.cpp \
         ThaiLayoutEngine.cpp \
         ScriptAndLanguageTags.cpp \
-        FontInstanceAdapter.cpp
+        FontInstanceAdapter.cpp \
+        ContextualGlyphInsertionProc2.cpp \
+        ContextualGlyphSubstProc2.cpp \
+        GXLayoutEngine2.cpp \
+        IndicRearrangementProcessor2.cpp \
+        LigatureSubstProc2.cpp \
+        MorphTables2.cpp \
+        NonContextualGlyphSubstProc2.cpp \
+        SegmentArrayProcessor2.cpp \
+        SegmentSingleProcessor2.cpp \
+        SimpleArrayProcessor2.cpp \
+        SingleTableProcessor2.cpp \
+        StateTableProcessor2.cpp \
+        SubtableProcessor2.cpp \
+        TrimmedArrayProcessor2.cpp
 
 
 ifeq ($(PLATFORM),windows)
--- a/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/macosx/classes/sun/lwawt/LWWindowPeer.java	Thu Apr 18 14:38:37 2013 -0700
@@ -175,7 +175,7 @@
             setTitle(((Dialog) getTarget()).getTitle());
         }
 
-        setAlwaysOnTop(getTarget().isAlwaysOnTop());
+        updateAlwaysOnTopState();
         updateMinimumSize();
 
         final Shape shape = getTarget().getShape();
@@ -422,8 +422,8 @@
     }
 
     @Override
-    public void setAlwaysOnTop(boolean value) {
-        platformWindow.setAlwaysOnTop(value);
+    public void updateAlwaysOnTopState() {
+        platformWindow.setAlwaysOnTop(getTarget().isAlwaysOnTop());
     }
 
     @Override
--- a/src/macosx/classes/sun/lwawt/macosx/CClipboard.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CClipboard.java	Thu Apr 18 14:38:37 2013 -0700
@@ -110,4 +110,12 @@
 
     public native void declareTypes(long[] formats, SunClipboard newOwner);
     public native void setData(byte[] data, long format);
+
+    /**
+     * Invokes native check whether a change count on the general pasteboard is different
+     * than when we set it. The different count value means the current owner lost
+     * pasteboard ownership and someone else put data on the clipboard.
+     * @since 1.7
+     */
+    public native void checkPasteboard();
 }
--- a/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CEmbeddedFrame.java	Thu Apr 18 14:38:37 2013 -0700
@@ -112,6 +112,14 @@
 
     public void handleFocusEvent(boolean focused) {
         this.focused = focused;
+        if (focused) {
+            // see bug 8010925
+            // we can't put this to handleWindowFocusEvent because
+            // it won't be invoced if focuse is moved to a html element
+            // on the same page.
+            CClipboard clipboard = (CClipboard) Toolkit.getDefaultToolkit().getSystemClipboard();
+            clipboard.checkPasteboard();
+        }
         if (parentWindowActive) {
             responder.handleWindowFocusEvent(focused);
         }
--- a/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -180,7 +180,7 @@
     }
 
     @Override
-    public void setAlwaysOnTop(boolean alwaysOnTop) {
+    public void updateAlwaysOnTopState() {
     }
 
     @Override
--- a/src/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -87,7 +87,7 @@
     }
 
     // 1.6 peer method
-    public void setAlwaysOnTop(boolean value) {
+    public void updateAlwaysOnTopState() {
         // no-op, since we just show the native print dialog
     }
 
--- a/src/macosx/native/sun/awt/CClipboard.m	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/macosx/native/sun/awt/CClipboard.m	Thu Apr 18 14:38:37 2013 -0700
@@ -193,18 +193,18 @@
 
 - (void) checkPasteboard:(id)application {
     AWT_ASSERT_APPKIT_THREAD;
-
+    
     //NSLog(@"CClipboard checkPasteboard oldCount %d newCount %d newTypes %@", fChangeCount, [[NSPasteboard generalPasteboard] changeCount], [[NSPasteboard generalPasteboard] types]);
-
+    
     // This is called via NSApplicationDidBecomeActiveNotification.
-
+    
     // If the change count on the general pasteboard is different than when we set it
     // someone else put data on the clipboard.  That means the current owner lost ownership.
     NSInteger newChangeCount = [[NSPasteboard generalPasteboard] changeCount];
-
+    
     if (fChangeCount != newChangeCount) {
         fChangeCount = newChangeCount;
-
+        
         [self pasteboardChangedOwner:[NSPasteboard generalPasteboard]];
     }
 }
@@ -375,4 +375,21 @@
     return returnValue;
 }
 
+/*
+ * Class:     sun_lwawt_macosx_CClipboard
+ * Method:    checkPasteboard
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CClipboard_checkPasteboard
+(JNIEnv *env, jobject inObject )
+{
+    JNF_COCOA_ENTER(env);
 
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+        [[CClipboard sharedClipboard] checkPasteboard:nil];
+    }];
+        
+    JNF_COCOA_EXIT(env);
+}
+
+
--- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java	Thu Apr 18 14:38:37 2013 -0700
@@ -238,12 +238,17 @@
      * sending warnings to listeners.
      */
     protected void warningOccurred(int code) {
-        if ((code < 0) || (code > MAX_WARNING)){
-            throw new InternalError("Invalid warning index");
+        cbLock.lock();
+        try {
+            if ((code < 0) || (code > MAX_WARNING)){
+                throw new InternalError("Invalid warning index");
+            }
+            processWarningOccurred
+                ("com.sun.imageio.plugins.jpeg.JPEGImageReaderResources",
+                 Integer.toString(code));
+        } finally {
+            cbLock.unlock();
         }
-        processWarningOccurred
-            ("com.sun.imageio.plugins.jpeg.JPEGImageReaderResources",
-             Integer.toString(code));
     }
 
     /**
@@ -260,7 +265,12 @@
      * library warnings from being printed to stderr.
      */
     protected void warningWithMessage(String msg) {
-        processWarningOccurred(msg);
+        cbLock.lock();
+        try {
+            processWarningOccurred(msg);
+        } finally {
+            cbLock.unlock();
+        }
     }
 
     public void setInput(Object input,
@@ -269,18 +279,55 @@
     {
         setThreadLock();
         try {
+            cbLock.check();
+
             super.setInput(input, seekForwardOnly, ignoreMetadata);
             this.ignoreMetadata = ignoreMetadata;
             resetInternalState();
             iis = (ImageInputStream) input; // Always works
-            setSource(structPointer, iis);
+            setSource(structPointer);
         } finally {
             clearThreadLock();
         }
     }
 
-    private native void setSource(long structPointer,
-                                  ImageInputStream source);
+    /**
+     * This method is called from native code in order to fill
+     * native input buffer.
+     *
+     * We block any attempt to change the reading state during this
+     * method, in order to prevent a corruption of the native decoder
+     * state.
+     *
+     * @return number of bytes read from the stream.
+     */
+    private int readInputData(byte[] buf, int off, int len) throws IOException {
+        cbLock.lock();
+        try {
+            return iis.read(buf, off, len);
+        } finally {
+            cbLock.unlock();
+        }
+    }
+
+    /**
+     * This method is called from the native code in order to
+     * skip requested number of bytes in the input stream.
+     *
+     * @param n
+     * @return
+     * @throws IOException
+     */
+    private long skipInputBytes(long n) throws IOException {
+        cbLock.lock();
+        try {
+            return iis.skipBytes(n);
+        } finally {
+            cbLock.unlock();
+        }
+    }
+
+    private native void setSource(long structPointer);
 
     private void checkTablesOnly() throws IOException {
         if (debug) {
@@ -332,6 +379,8 @@
     public int getNumImages(boolean allowSearch) throws IOException {
         setThreadLock();
         try { // locked thread
+            cbLock.check();
+
             return getNumImagesOnThread(allowSearch);
         } finally {
             clearThreadLock();
@@ -531,8 +580,13 @@
         if (debug) {
             System.out.println("pushing back " + num + " bytes");
         }
-        iis.seek(iis.getStreamPosition()-num);
-        // The buffer is clear after this, so no need to set haveSeeked.
+        cbLock.lock();
+        try {
+            iis.seek(iis.getStreamPosition()-num);
+            // The buffer is clear after this, so no need to set haveSeeked.
+        } finally {
+            cbLock.unlock();
+        }
     }
 
     /**
@@ -639,7 +693,12 @@
                  * Ignore this profile.
                  */
                 iccCS = null;
-                warningOccurred(WARNING_IGNORE_INVALID_ICC);
+                cbLock.lock();
+                try {
+                    warningOccurred(WARNING_IGNORE_INVALID_ICC);
+                } finally {
+                    cbLock.unlock();
+                }
             }
         }
     }
@@ -648,6 +707,7 @@
         setThreadLock();
         try {
             if (currentImage != imageIndex) {
+                cbLock.check();
                 readHeader(imageIndex, true);
             }
             return width;
@@ -660,6 +720,7 @@
         setThreadLock();
         try {
             if (currentImage != imageIndex) {
+                cbLock.check();
                 readHeader(imageIndex, true);
             }
             return height;
@@ -688,6 +749,8 @@
         setThreadLock();
         try {
             if (currentImage != imageIndex) {
+                cbLock.check();
+
                 readHeader(imageIndex, true);
             }
 
@@ -711,6 +774,7 @@
     private Iterator getImageTypesOnThread(int imageIndex)
         throws IOException {
         if (currentImage != imageIndex) {
+            cbLock.check();
             readHeader(imageIndex, true);
         }
 
@@ -926,6 +990,7 @@
         setThreadLock();
         try {
             if (!tablesOnlyChecked) {
+                cbLock.check();
                 checkTablesOnly();
             }
             return streamMetadata;
@@ -946,6 +1011,8 @@
                 return imageMetadata;
             }
 
+            cbLock.check();
+
             gotoImage(imageIndex);
 
             imageMetadata = new JPEGMetadata(false, false, iis, this);
@@ -962,6 +1029,7 @@
         throws IOException {
         setThreadLock();
         try {
+            cbLock.check();
             try {
                 readInternal(imageIndex, param, false);
             } catch (RuntimeException e) {
@@ -1191,58 +1259,63 @@
         }
         target.setRect(destROI.x, destROI.y + y, raster);
 
-        processImageUpdate(image,
-                           destROI.x, destROI.y+y,
-                           raster.getWidth(), 1,
-                           1, 1,
-                           destinationBands);
-        if ((y > 0) && (y%progInterval == 0)) {
-            int height = target.getHeight()-1;
-            float percentOfPass = ((float)y)/height;
-            if (progressive) {
-                if (knownPassCount != UNKNOWN) {
-                    processImageProgress((pass + percentOfPass)*100.0F
-                                         / knownPassCount);
-                } else if (maxProgressivePass != Integer.MAX_VALUE) {
-                    // Use the range of allowed progressive passes
-                    processImageProgress((pass + percentOfPass)*100.0F
-                        / (maxProgressivePass - minProgressivePass + 1));
+        cbLock.lock();
+        try {
+            processImageUpdate(image,
+                               destROI.x, destROI.y+y,
+                               raster.getWidth(), 1,
+                               1, 1,
+                               destinationBands);
+            if ((y > 0) && (y%progInterval == 0)) {
+                int height = target.getHeight()-1;
+                float percentOfPass = ((float)y)/height;
+                if (progressive) {
+                    if (knownPassCount != UNKNOWN) {
+                        processImageProgress((pass + percentOfPass)*100.0F
+                                             / knownPassCount);
+                    } else if (maxProgressivePass != Integer.MAX_VALUE) {
+                        // Use the range of allowed progressive passes
+                        processImageProgress((pass + percentOfPass)*100.0F
+                                             / (maxProgressivePass - minProgressivePass + 1));
+                    } else {
+                        // Assume there are a minimum of MIN_ESTIMATED_PASSES
+                        // and that there is always one more pass
+                        // Compute the percentage as the percentage at the end
+                        // of the previous pass, plus the percentage of this
+                        // pass scaled to be the percentage of the total remaining,
+                        // assuming a minimum of MIN_ESTIMATED_PASSES passes and
+                        // that there is always one more pass.  This is monotonic
+                        // and asymptotic to 1.0, which is what we need.
+                        int remainingPasses = // including this one
+                            Math.max(2, MIN_ESTIMATED_PASSES-pass);
+                        int totalPasses = pass + remainingPasses-1;
+                        progInterval = Math.max(height/20*totalPasses,
+                                                totalPasses);
+                        if (y%progInterval == 0) {
+                            percentToDate = previousPassPercentage +
+                                (1.0F - previousPassPercentage)
+                                * (percentOfPass)/remainingPasses;
+                            if (debug) {
+                                System.out.print("pass= " + pass);
+                                System.out.print(", y= " + y);
+                                System.out.print(", progInt= " + progInterval);
+                                System.out.print(", % of pass: " + percentOfPass);
+                                System.out.print(", rem. passes: "
+                                                 + remainingPasses);
+                                System.out.print(", prev%: "
+                                                 + previousPassPercentage);
+                                System.out.print(", %ToDate: " + percentToDate);
+                                System.out.print(" ");
+                            }
+                            processImageProgress(percentToDate*100.0F);
+                        }
+                    }
                 } else {
-                    // Assume there are a minimum of MIN_ESTIMATED_PASSES
-                    // and that there is always one more pass
-                    // Compute the percentage as the percentage at the end
-                    // of the previous pass, plus the percentage of this
-                    // pass scaled to be the percentage of the total remaining,
-                    // assuming a minimum of MIN_ESTIMATED_PASSES passes and
-                    // that there is always one more pass.  This is monotonic
-                    // and asymptotic to 1.0, which is what we need.
-                    int remainingPasses = // including this one
-                        Math.max(2, MIN_ESTIMATED_PASSES-pass);
-                    int totalPasses = pass + remainingPasses-1;
-                    progInterval = Math.max(height/20*totalPasses,
-                                            totalPasses);
-                    if (y%progInterval == 0) {
-                        percentToDate = previousPassPercentage +
-                            (1.0F - previousPassPercentage)
-                            * (percentOfPass)/remainingPasses;
-                        if (debug) {
-                            System.out.print("pass= " + pass);
-                            System.out.print(", y= " + y);
-                            System.out.print(", progInt= " + progInterval);
-                            System.out.print(", % of pass: " + percentOfPass);
-                            System.out.print(", rem. passes: "
-                                             + remainingPasses);
-                            System.out.print(", prev%: "
-                                             + previousPassPercentage);
-                            System.out.print(", %ToDate: " + percentToDate);
-                            System.out.print(" ");
-                        }
-                        processImageProgress(percentToDate*100.0F);
-                    }
+                    processImageProgress(percentOfPass * 100.0F);
                 }
-            } else {
-                processImageProgress(percentOfPass * 100.0F);
             }
+        } finally {
+            cbLock.unlock();
         }
     }
 
@@ -1255,33 +1328,58 @@
     }
 
     private void passStarted (int pass) {
-        this.pass = pass;
-        previousPassPercentage = percentToDate;
-        processPassStarted(image,
-                           pass,
-                           minProgressivePass,
-                           maxProgressivePass,
-                           0, 0,
-                           1,1,
-                           destinationBands);
+        cbLock.lock();
+        try {
+            this.pass = pass;
+            previousPassPercentage = percentToDate;
+            processPassStarted(image,
+                               pass,
+                               minProgressivePass,
+                               maxProgressivePass,
+                               0, 0,
+                               1,1,
+                               destinationBands);
+        } finally {
+            cbLock.unlock();
+        }
     }
 
     private void passComplete () {
-        processPassComplete(image);
+        cbLock.lock();
+        try {
+            processPassComplete(image);
+        } finally {
+            cbLock.unlock();
+        }
     }
 
     void thumbnailStarted(int thumbnailIndex) {
-        processThumbnailStarted(currentImage, thumbnailIndex);
+        cbLock.lock();
+        try {
+            processThumbnailStarted(currentImage, thumbnailIndex);
+        } finally {
+            cbLock.unlock();
+        }
     }
 
     // Provide access to protected superclass method
     void thumbnailProgress(float percentageDone) {
-        processThumbnailProgress(percentageDone);
+        cbLock.lock();
+        try {
+            processThumbnailProgress(percentageDone);
+        } finally {
+            cbLock.unlock();
+        }
     }
 
     // Provide access to protected superclass method
     void thumbnailComplete() {
-        processThumbnailComplete();
+        cbLock.lock();
+        try {
+            processThumbnailComplete();
+        } finally {
+            cbLock.unlock();
+        }
     }
 
     /**
@@ -1305,6 +1403,11 @@
     public void abort() {
         setThreadLock();
         try {
+            /**
+             * NB: we do not check the call back lock here,
+             * we allow to abort the reader any time.
+             */
+
             super.abort();
             abortRead(structPointer);
         } finally {
@@ -1327,6 +1430,7 @@
         setThreadLock();
         Raster retval = null;
         try {
+            cbLock.check();
             /*
              * This could be further optimized by not resetting the dest.
              * offset and creating a translated raster in readInternal()
@@ -1366,6 +1470,8 @@
     public int getNumThumbnails(int imageIndex) throws IOException {
         setThreadLock();
         try {
+            cbLock.check();
+
             getImageMetadata(imageIndex);  // checks iis state for us
             // Now check the jfif segments
             JFIFMarkerSegment jfif =
@@ -1386,6 +1492,8 @@
         throws IOException {
         setThreadLock();
         try {
+            cbLock.check();
+
             if ((thumbnailIndex < 0)
                 || (thumbnailIndex >= getNumThumbnails(imageIndex))) {
                 throw new IndexOutOfBoundsException("No such thumbnail");
@@ -1404,6 +1512,8 @@
         throws IOException {
         setThreadLock();
         try {
+            cbLock.check();
+
             if ((thumbnailIndex < 0)
                 || (thumbnailIndex >= getNumThumbnails(imageIndex))) {
                 throw new IndexOutOfBoundsException("No such thumbnail");
@@ -1423,6 +1533,8 @@
         throws IOException {
         setThreadLock();
         try {
+            cbLock.check();
+
             if ((thumbnailIndex < 0)
                 || (thumbnailIndex >= getNumThumbnails(imageIndex))) {
                 throw new IndexOutOfBoundsException("No such thumbnail");
@@ -1463,6 +1575,7 @@
     public void reset() {
         setThreadLock();
         try {
+            cbLock.check();
             super.reset();
         } finally {
             clearThreadLock();
@@ -1474,6 +1587,8 @@
     public void dispose() {
         setThreadLock();
         try {
+            cbLock.check();
+
             if (structPointer != 0) {
                 disposerRecord.dispose();
                 structPointer = 0;
@@ -1535,6 +1650,36 @@
             theThread = null;
         }
     }
+
+    private CallBackLock cbLock = new CallBackLock();
+
+    private static class CallBackLock {
+
+        private State lockState;
+
+        CallBackLock() {
+            lockState = State.Unlocked;
+        }
+
+        void check() {
+            if (lockState != State.Unlocked) {
+                throw new IllegalStateException("Access to the reader is not allowed");
+            }
+        }
+
+        private void lock() {
+            lockState = State.Locked;
+        }
+
+        private void unlock() {
+            lockState = State.Unlocked;
+        }
+
+        private static enum State {
+            Unlocked,
+            Locked
+        }
+    }
 }
 
 /**
--- a/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java	Thu Apr 18 14:38:37 2013 -0700
@@ -178,8 +178,7 @@
     static {
         java.security.AccessController.doPrivileged(
             new sun.security.action.LoadLibraryAction("jpeg"));
-        initWriterIDs(ImageOutputStream.class,
-                      JPEGQTable.class,
+        initWriterIDs(JPEGQTable.class,
                       JPEGHuffmanTable.class);
     }
 
@@ -195,11 +194,13 @@
     public void setOutput(Object output) {
         setThreadLock();
         try {
+            cbLock.check();
+
             super.setOutput(output); // validates output
             resetInternalState();
             ios = (ImageOutputStream) output; // so this will always work
             // Set the native destination
-            setDest(structPointer, ios);
+            setDest(structPointer);
         } finally {
             clearThreadLock();
         }
@@ -354,6 +355,8 @@
                       ImageWriteParam param) throws IOException {
         setThreadLock();
         try {
+            cbLock.check();
+
             writeOnThread(streamMetadata, image, param);
         } finally {
             clearThreadLock();
@@ -1077,13 +1080,18 @@
                              haveMetadata,
                              restartInterval);
 
-        if (aborted) {
-            processWriteAborted();
-        } else {
-            processImageComplete();
+        cbLock.lock();
+        try {
+            if (aborted) {
+                processWriteAborted();
+            } else {
+                processImageComplete();
+            }
+
+            ios.flush();
+        } finally {
+            cbLock.unlock();
         }
-
-        ios.flush();
         currentImage++;  // After a successful write
     }
 
@@ -1091,6 +1099,8 @@
         throws IOException {
         setThreadLock();
         try {
+            cbLock.check();
+
             prepareWriteSequenceOnThread(streamMetadata);
         } finally {
             clearThreadLock();
@@ -1170,6 +1180,8 @@
         throws IOException {
         setThreadLock();
         try {
+            cbLock.check();
+
             if (sequencePrepared == false) {
                 throw new IllegalStateException("sequencePrepared not called!");
             }
@@ -1183,6 +1195,8 @@
     public void endWriteSequence() throws IOException {
         setThreadLock();
         try {
+            cbLock.check();
+
             if (sequencePrepared == false) {
                 throw new IllegalStateException("sequencePrepared not called!");
             }
@@ -1195,6 +1209,10 @@
     public synchronized void abort() {
         setThreadLock();
         try {
+            /**
+             * NB: we do not check the call back lock here, we allow to abort
+             * the reader any time.
+             */
             super.abort();
             abortWrite(structPointer);
         } finally {
@@ -1218,6 +1236,8 @@
     public void reset() {
         setThreadLock();
         try {
+            cbLock.check();
+
             super.reset();
         } finally {
             clearThreadLock();
@@ -1227,6 +1247,8 @@
     public void dispose() {
         setThreadLock();
         try {
+            cbLock.check();
+
             if (structPointer != 0) {
                 disposerRecord.dispose();
                 structPointer = 0;
@@ -1246,13 +1268,18 @@
      * sending warnings to listeners.
      */
     void warningOccurred(int code) {
-        if ((code < 0) || (code > MAX_WARNING)){
-            throw new InternalError("Invalid warning index");
+        cbLock.lock();
+        try {
+            if ((code < 0) || (code > MAX_WARNING)){
+                throw new InternalError("Invalid warning index");
+            }
+            processWarningOccurred
+                (currentImage,
+                 "com.sun.imageio.plugins.jpeg.JPEGImageWriterResources",
+                Integer.toString(code));
+        } finally {
+            cbLock.unlock();
         }
-        processWarningOccurred
-            (currentImage,
-             "com.sun.imageio.plugins.jpeg.JPEGImageWriterResources",
-             Integer.toString(code));
     }
 
     /**
@@ -1269,21 +1296,41 @@
      * library warnings from being printed to stderr.
      */
     void warningWithMessage(String msg) {
-        processWarningOccurred(currentImage, msg);
+        cbLock.lock();
+        try {
+            processWarningOccurred(currentImage, msg);
+        } finally {
+            cbLock.unlock();
+        }
     }
 
     void thumbnailStarted(int thumbnailIndex) {
-        processThumbnailStarted(currentImage, thumbnailIndex);
+        cbLock.lock();
+        try {
+            processThumbnailStarted(currentImage, thumbnailIndex);
+        } finally {
+            cbLock.unlock();
+        }
     }
 
     // Provide access to protected superclass method
     void thumbnailProgress(float percentageDone) {
-        processThumbnailProgress(percentageDone);
+        cbLock.lock();
+        try {
+            processThumbnailProgress(percentageDone);
+        } finally {
+            cbLock.unlock();
+        }
     }
 
     // Provide access to protected superclass method
     void thumbnailComplete() {
-        processThumbnailComplete();
+        cbLock.lock();
+        try {
+            processThumbnailComplete();
+        } finally {
+            cbLock.unlock();
+        }
     }
 
     ///////// End of Package-access API
@@ -1610,16 +1657,14 @@
     ////////////// Native methods and callbacks
 
     /** Sets up static native structures. */
-    private static native void initWriterIDs(Class iosClass,
-                                             Class qTableClass,
+    private static native void initWriterIDs(Class qTableClass,
                                              Class huffClass);
 
     /** Sets up per-writer native structure and returns a pointer to it. */
     private native long initJPEGImageWriter();
 
     /** Sets up native structures for output stream */
-    private native void setDest(long structPointer,
-                                ImageOutputStream ios);
+    private native void setDest(long structPointer);
 
     /**
      * Returns <code>true</code> if the write was aborted.
@@ -1744,7 +1789,12 @@
         }
         raster.setRect(sourceLine);
         if ((y > 7) && (y%8 == 0)) {  // Every 8 scanlines
-            processImageProgress((float) y / (float) sourceHeight * 100.0F);
+            cbLock.lock();
+            try {
+                processImageProgress((float) y / (float) sourceHeight * 100.0F);
+            } finally {
+                cbLock.unlock();
+            }
         }
     }
 
@@ -1772,6 +1822,25 @@
         }
     }
 
+    /**
+     * This method is called from native code in order to write encoder
+     * output to the destination.
+     *
+     * We block any attempt to change the writer state during this
+     * method, in order to prevent a corruption of the native encoder
+     * state.
+     */
+    private void writeOutputData(byte[] data, int offset, int len)
+            throws IOException
+    {
+        cbLock.lock();
+        try {
+            ios.write(data, offset, len);
+        } finally {
+            cbLock.unlock();
+        }
+    }
+
     private Thread theThread = null;
     private int theLockCount = 0;
 
@@ -1806,4 +1875,34 @@
             theThread = null;
         }
     }
+
+    private CallBackLock cbLock = new CallBackLock();
+
+    private static class CallBackLock {
+
+        private State lockState;
+
+        CallBackLock() {
+            lockState = State.Unlocked;
+        }
+
+        void check() {
+            if (lockState != State.Unlocked) {
+                throw new IllegalStateException("Access to the writer is not allowed");
+            }
+        }
+
+        private void lock() {
+            lockState = State.Locked;
+        }
+
+        private void unlock() {
+            lockState = State.Unlocked;
+        }
+
+        private static enum State {
+            Unlocked,
+            Locked
+        }
+    }
 }
--- a/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/com/sun/jmx/mbeanserver/MBeanInstantiator.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -32,6 +32,7 @@
 import java.io.ObjectInputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
 import java.security.Permission;
 import java.util.Map;
 import java.util.logging.Level;
@@ -213,7 +214,6 @@
 
         Object moi;
 
-
         // ------------------------------
         // ------------------------------
         Constructor<?> cons = findConstructor(theClass, null);
@@ -224,6 +224,7 @@
         // Instantiate the new object
         try {
             ReflectUtil.checkPackageAccess(theClass);
+            ensureClassAccess(theClass);
             moi= cons.newInstance();
         } catch (InvocationTargetException e) {
             // Wrap the exception.
@@ -270,7 +271,6 @@
         checkMBeanPermission(theClass, null, null, "instantiate");
 
         // Instantiate the new object
-
         // ------------------------------
         // ------------------------------
         final Class<?>[] tab;
@@ -300,6 +300,7 @@
         }
         try {
             ReflectUtil.checkPackageAccess(theClass);
+            ensureClassAccess(theClass);
             moi = cons.newInstance(params);
         }
         catch (NoSuchMethodError error) {
@@ -741,4 +742,13 @@
             sm.checkPermission(perm);
         }
     }
+
+    private static void ensureClassAccess(Class clazz)
+            throws IllegalAccessException
+    {
+        int mod = clazz.getModifiers();
+        if (!Modifier.isPublic(mod)) {
+            throw new IllegalAccessException("Class is not public and can't be instantiated");
+        }
+    }
 }
--- a/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/com/sun/media/sound/AbstractMidiDevice.java	Thu Apr 18 14:38:37 2013 -0700
@@ -56,7 +56,7 @@
     // from simultaneous creation and destruction
     // reduces possibility of deadlock, compared to
     // synchronizing to the class instance
-    private Object traRecLock = new Object();
+    private final Object traRecLock = new Object();
 
     // DEVICE ATTRIBUTES
 
@@ -474,7 +474,7 @@
         This is necessary for Receivers retrieved via MidiSystem.getReceiver()
         (which opens the device implicitely).
      */
-    protected abstract class AbstractReceiver implements MidiDeviceReceiver {
+    abstract class AbstractReceiver implements MidiDeviceReceiver {
         private boolean open = true;
 
 
@@ -483,24 +483,24 @@
             Receiver. Therefore, subclasses should not override this method.
             Instead, they should implement implSend().
         */
-        public synchronized void send(MidiMessage message, long timeStamp) {
-            if (open) {
-                implSend(message, timeStamp);
-            } else {
+        @Override
+        public final synchronized void send(final MidiMessage message,
+                                            final long timeStamp) {
+            if (!open) {
                 throw new IllegalStateException("Receiver is not open");
             }
+            implSend(message, timeStamp);
         }
 
-
-        protected abstract void implSend(MidiMessage message, long timeStamp);
-
+        abstract void implSend(MidiMessage message, long timeStamp);
 
         /** Close the Receiver.
          * Here, the call to the magic method closeInternal() takes place.
          * Therefore, subclasses that override this method must call
          * 'super.close()'.
          */
-        public void close() {
+        @Override
+        public final void close() {
             open = false;
             synchronized (AbstractMidiDevice.this.traRecLock) {
                 AbstractMidiDevice.this.getReceiverList().remove(this);
@@ -508,11 +508,12 @@
             AbstractMidiDevice.this.closeInternal(this);
         }
 
-        public MidiDevice getMidiDevice() {
+        @Override
+        public final MidiDevice getMidiDevice() {
             return AbstractMidiDevice.this;
         }
 
-        protected boolean isOpen() {
+        final boolean isOpen() {
             return open;
         }
 
--- a/src/share/classes/com/sun/media/sound/FastShortMessage.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/com/sun/media/sound/FastShortMessage.java	Thu Apr 18 14:38:37 2013 -0700
@@ -32,7 +32,7 @@
  *
  * @author Florian Bomers
  */
-class FastShortMessage extends ShortMessage {
+final class FastShortMessage extends ShortMessage {
     private int packedMsg;
 
     public FastShortMessage(int packedMsg) throws InvalidMidiDataException {
--- a/src/share/classes/com/sun/media/sound/FastSysexMessage.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/com/sun/media/sound/FastSysexMessage.java	Thu Apr 18 14:38:37 2013 -0700
@@ -32,7 +32,7 @@
  *
  * @author Florian Bomers
  */
-class FastSysexMessage extends SysexMessage {
+final class FastSysexMessage extends SysexMessage {
 
     FastSysexMessage(byte[] data) throws InvalidMidiDataException {
         super(data);
--- a/src/share/classes/com/sun/media/sound/MidiOutDevice.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/com/sun/media/sound/MidiOutDevice.java	Thu Apr 18 14:38:37 2013 -0700
@@ -103,9 +103,9 @@
 
     class MidiOutReceiver extends AbstractReceiver {
 
-        protected void implSend(MidiMessage message, long timeStamp) {
-            int length = message.getLength();
-            int status = message.getStatus();
+        void implSend(final MidiMessage message, final long timeStamp) {
+            final int length = message.getLength();
+            final int status = message.getStatus();
             if (length <= 3 && status != 0xF0 && status != 0xF7) {
                 int packedMsg;
                 if (message instanceof ShortMessage) {
@@ -140,11 +140,15 @@
                 }
                 nSendShortMessage(id, packedMsg, timeStamp);
             } else {
+                final byte[] data;
                 if (message instanceof FastSysexMessage) {
-                    nSendLongMessage(id, ((FastSysexMessage) message).getReadOnlyMessage(),
-                                     length, timeStamp);
+                    data = ((FastSysexMessage) message).getReadOnlyMessage();
                 } else {
-                    nSendLongMessage(id, message.getMessage(), length, timeStamp);
+                    data = message.getMessage();
+                }
+                final int dataLength = Math.min(length, data.length);
+                if (dataLength > 0) {
+                    nSendLongMessage(id, data, dataLength, timeStamp);
                 }
             }
         }
--- a/src/share/classes/com/sun/media/sound/RealTimeSequencer.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/com/sun/media/sound/RealTimeSequencer.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1026,7 +1026,7 @@
 
     class SequencerReceiver extends AbstractReceiver {
 
-        protected void implSend(MidiMessage message, long timeStamp) {
+        void implSend(MidiMessage message, long timeStamp) {
             if (recording) {
                 long tickPos = 0;
 
--- a/src/share/classes/java/awt/Window.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/awt/Window.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -2234,7 +2234,7 @@
                 WindowPeer peer = (WindowPeer)this.peer;
                 synchronized(getTreeLock()) {
                     if (peer != null) {
-                        peer.setAlwaysOnTop(alwaysOnTop);
+                        peer.updateAlwaysOnTopState();
                     }
                 }
             }
--- a/src/share/classes/java/awt/peer/WindowPeer.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/awt/peer/WindowPeer.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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
@@ -55,15 +55,14 @@
     void toBack();
 
     /**
-     * Sets if the window should always stay on top of all other windows or
-     * not.
+     * Updates the window's always-on-top state.
+     * Sets if the window should always stay
+     * on top of all other windows or not.
      *
-     * @param alwaysOnTop if the window should always stay on top of all other
-     *        windows or not
-     *
+     * @see Window#getAlwaysOnTop()
      * @see Window#setAlwaysOnTop(boolean)
      */
-    void setAlwaysOnTop(boolean alwaysOnTop);
+    void updateAlwaysOnTopState();
 
     /**
      * Updates the window's focusable state.
--- a/src/share/classes/java/beans/ThreadGroupContext.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/beans/ThreadGroupContext.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -29,7 +29,6 @@
 import com.sun.beans.finder.PropertyEditorFinder;
 
 import java.awt.GraphicsEnvironment;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.WeakHashMap;
 
@@ -42,7 +41,7 @@
  */
 final class ThreadGroupContext {
 
-    private static final Map<ThreadGroup, ThreadGroupContext> contexts = new WeakHashMap<>();
+    private static final WeakIdentityMap<ThreadGroupContext> contexts = new WeakIdentityMap<>();
 
     /**
      * Returns the appropriate {@code AppContext} for the caller,
@@ -69,6 +68,8 @@
     private BeanInfoFinder beanInfoFinder;
     private PropertyEditorFinder propertyEditorFinder;
 
+    private ThreadGroupContext() {
+    }
 
     boolean isDesignTime() {
         return this.isDesignTime;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/classes/java/beans/WeakIdentityMap.java	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 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
+ * 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 java.beans;
+
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.WeakReference;
+
+/**
+ * Hash table based mapping, which uses weak references to store keys
+ * and reference-equality in place of object-equality to compare them.
+ * An entry will automatically be removed when its key is no longer
+ * in ordinary use.  Both null values and the null key are supported.
+ *
+ * @see java.util.IdentityHashMap
+ * @see java.util.WeakHashMap
+ */
+final class WeakIdentityMap<T> {
+
+    private static final int MAXIMUM_CAPACITY = 1 << 30; // it MUST be a power of two
+    private static final Object NULL = new Object(); // special object for null key
+
+    private final ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
+
+    private Entry<T>[] table = newTable(1<<3); // table's length MUST be a power of two
+    private int threshold = 6; // the next size value at which to resize
+    private int size = 0; // the number of key-value mappings
+
+    public T get(Object key) {
+        removeStaleEntries();
+        if (key == null) {
+            key = NULL;
+        }
+        int hash = key.hashCode();
+        int index = getIndex(this.table, hash);
+        for (Entry<T> entry = this.table[index]; entry != null; entry = entry.next) {
+            if (entry.isMatched(key, hash)) {
+                return entry.value;
+            }
+        }
+        return null;
+    }
+
+    public T put(Object key, T value) {
+        removeStaleEntries();
+        if (key == null) {
+            key = NULL;
+        }
+        int hash = key.hashCode();
+        int index = getIndex(this.table, hash);
+        for (Entry<T> entry = this.table[index]; entry != null; entry = entry.next) {
+            if (entry.isMatched(key, hash)) {
+                T oldValue = entry.value;
+                entry.value = value;
+                return oldValue;
+            }
+        }
+        this.table[index] = new Entry<T>(key, hash, value, this.queue, this.table[index]);
+        if (++this.size >= this.threshold) {
+            if (this.table.length == MAXIMUM_CAPACITY) {
+                this.threshold = Integer.MAX_VALUE;
+            }
+            else {
+                removeStaleEntries();
+                Entry<T>[] table = newTable(this.table.length * 2);
+                transfer(this.table, table);
+
+                // If ignoring null elements and processing ref queue caused massive
+                // shrinkage, then restore old table.  This should be rare, but avoids
+                // unbounded expansion of garbage-filled tables.
+                if (this.size >= this.threshold / 2) {
+                    this.table = table;
+                    this.threshold *= 2;
+                }
+                else {
+                    transfer(table, this.table);
+                }
+            }
+        }
+        return null;
+    }
+
+    private void removeStaleEntries() {
+        for (Object ref = this.queue.poll(); ref != null; ref = this.queue.poll()) {
+            @SuppressWarnings("unchecked")
+            Entry<T> entry = (Entry<T>) ref;
+            int index = getIndex(this.table, entry.hash);
+
+            Entry<T> prev = this.table[index];
+            Entry<T> current = prev;
+            while (current != null) {
+                Entry<T> next = current.next;
+                if (current == entry) {
+                    if (prev == entry) {
+                        this.table[index] = next;
+                    }
+                    else {
+                        prev.next = next;
+                    }
+                    entry.value = null; // Help GC
+                    entry.next = null; // Help GC
+                    this.size--;
+                    break;
+                }
+                prev = current;
+                current = next;
+            }
+        }
+    }
+
+    private void transfer(Entry<T>[] oldTable, Entry<T>[] newTable) {
+        for (int i = 0; i < oldTable.length; i++) {
+            Entry<T> entry = oldTable[i];
+            oldTable[i] = null;
+            while (entry != null) {
+                Entry<T> next = entry.next;
+                Object key = entry.get();
+                if (key == null) {
+                    entry.value = null; // Help GC
+                    entry.next = null; // Help GC
+                    this.size--;
+                }
+                else {
+                    int index = getIndex(newTable, entry.hash);
+                    entry.next = newTable[index];
+                    newTable[index] = entry;
+                }
+                entry = next;
+            }
+        }
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private Entry<T>[] newTable(int length) {
+        return (Entry<T>[]) new Entry<?>[length];
+    }
+
+    private static int getIndex(Entry<?>[] table, int hash) {
+        return hash & (table.length - 1);
+    }
+
+    private static class Entry<T> extends WeakReference<Object> {
+        private final int hash;
+        private T value;
+        private Entry<T> next;
+
+        Entry(Object key, int hash, T value, ReferenceQueue<Object> queue, Entry<T> next) {
+            super(key, queue);
+            this.hash = hash;
+            this.value = value;
+            this.next  = next;
+        }
+
+        boolean isMatched(Object key, int hash) {
+            return (this.hash == hash) && (key == get());
+        }
+    }
+}
--- a/src/share/classes/java/io/ObjectInputStream.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/io/ObjectInputStream.java	Thu Apr 18 14:38:37 2013 -0700
@@ -41,6 +41,7 @@
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import static java.io.ObjectStreamClass.processQueue;
+import sun.reflect.misc.ReflectUtil;
 
 /**
  * An ObjectInputStream deserializes primitive data and objects previously
@@ -1519,6 +1520,12 @@
         }
     }
 
+    private boolean isCustomSubclass() {
+        // Return true if this class is a custom subclass of ObjectInputStream
+        return getClass().getClassLoader()
+                    != ObjectInputStream.class.getClassLoader();
+    }
+
     /**
      * Reads in and returns class descriptor for a dynamic proxy class.  Sets
      * passHandle to proxy class descriptor's assigned handle.  If proxy class
@@ -1548,6 +1555,15 @@
         try {
             if ((cl = resolveProxyClass(ifaces)) == null) {
                 resolveEx = new ClassNotFoundException("null class");
+            } else if (!Proxy.isProxyClass(cl)) {
+                throw new InvalidClassException("Not a proxy");
+            } else {
+                // ReflectUtil.checkProxyPackageAccess makes a test
+                // equivalent to isCustomSubclass so there's no need
+                // to condition this call to isCustomSubclass == true here.
+                ReflectUtil.checkProxyPackageAccess(
+                        getClass().getClassLoader(),
+                        cl.getInterfaces());
             }
         } catch (ClassNotFoundException ex) {
             resolveEx = ex;
@@ -1589,9 +1605,12 @@
         Class cl = null;
         ClassNotFoundException resolveEx = null;
         bin.setBlockDataMode(true);
+        final boolean checksRequired = isCustomSubclass();
         try {
             if ((cl = resolveClass(readDesc)) == null) {
                 resolveEx = new ClassNotFoundException("null class");
+            } else if (checksRequired) {
+                ReflectUtil.checkPackageAccess(cl);
             }
         } catch (ClassNotFoundException ex) {
             resolveEx = ex;
--- a/src/share/classes/java/lang/Integer.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/lang/Integer.java	Thu Apr 18 14:38:37 2013 -0700
@@ -607,7 +607,7 @@
                 int i = parseInt(integerCacheHighPropValue);
                 i = Math.max(i, 127);
                 // Maximum array size is Integer.MAX_VALUE
-                h = Math.min(i, Integer.MAX_VALUE - (-low));
+                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
             }
             high = h;
 
--- a/src/share/classes/java/lang/ProcessBuilder.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/lang/ProcessBuilder.java	Thu Apr 18 14:38:37 2013 -0700
@@ -30,6 +30,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.FileOutputStream;
+import java.security.AccessControlException;
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
@@ -1012,8 +1013,9 @@
         String prog = cmdarray[0];
 
         SecurityManager security = System.getSecurityManager();
-        if (security != null)
+        if (security != null) {
             security.checkExec(prog);
+        }
 
         String dir = directory == null ? null : directory.toString();
 
@@ -1024,13 +1026,24 @@
                                      redirects,
                                      redirectErrorStream);
         } catch (IOException e) {
+            String exceptionInfo = ": " + e.getMessage();
+            Throwable cause = e;
+            if (security != null) {
+                // Can not disclose the fail reason for read-protected files.
+                try {
+                    security.checkRead(prog);
+                } catch (AccessControlException ace) {
+                    exceptionInfo = "";
+                    cause = ace;
+                }
+            }
             // It's much easier for us to create a high-quality error
             // message than the low-level C code which found the problem.
             throw new IOException(
                 "Cannot run program \"" + prog + "\""
                 + (dir == null ? "" : " (in directory \"" + dir + "\")")
-                + ": " + e.getMessage(),
-                e);
+                + exceptionInfo,
+                cause);
         }
     }
 }
--- a/src/share/classes/java/lang/invoke/MethodHandles.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/lang/invoke/MethodHandles.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1236,6 +1236,30 @@
             checkMethod(refKind, refc, method);
             if (method.isMethodHandleInvoke())
                 return fakeMethodHandleInvoke(method);
+
+            Class<?> refcAsSuper;
+            if (refKind == REF_invokeSpecial &&
+                refc != lookupClass() &&
+                refc != (refcAsSuper = lookupClass().getSuperclass()) &&
+                refc.isAssignableFrom(lookupClass())) {
+                assert(!method.getName().equals("<init>"));  // not this code path
+                // Per JVMS 6.5, desc. of invokespecial instruction:
+                // If the method is in a superclass of the LC,
+                // and if our original search was above LC.super,
+                // repeat the search (symbolic lookup) from LC.super.
+                // FIXME: MemberName.resolve should handle this instead.
+                MemberName m2 = new MemberName(refcAsSuper,
+                                               method.getName(),
+                                               method.getMethodType(),
+                                               REF_invokeSpecial);
+                m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
+                if (m2 == null)  throw new InternalError(method.toString());
+                method = m2;
+                refc = refcAsSuper;
+                // redo basic checks
+                checkMethod(refKind, refc, method);
+            }
+
             MethodHandle mh = DirectMethodHandle.make(refc, method);
             mh = maybeBindCaller(method, mh, callerClass);
             mh = mh.setVarargs(method);
--- a/src/share/classes/java/lang/ref/Finalizer.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/lang/ref/Finalizer.java	Thu Apr 18 14:38:37 2013 -0700
@@ -38,9 +38,9 @@
      */
     static native void invokeFinalizeMethod(Object o) throws Throwable;
 
-    static private ReferenceQueue queue = new ReferenceQueue();
-    static private Finalizer unfinalized = null;
-    static private Object lock = new Object();
+    private static ReferenceQueue queue = new ReferenceQueue();
+    private static Finalizer unfinalized = null;
+    private static final Object lock = new Object();
 
     private Finalizer
         next = null,
@@ -142,7 +142,11 @@
     /* Called by Runtime.runFinalization() */
     static void runFinalization() {
         forkSecondaryFinalizer(new Runnable() {
+            private volatile boolean running;
             public void run() {
+                if (running)
+                    return;
+                running = true;
                 for (;;) {
                     Finalizer f = (Finalizer)queue.poll();
                     if (f == null) break;
@@ -155,7 +159,11 @@
     /* Invoked by java.lang.Shutdown */
     static void runAllFinalizers() {
         forkSecondaryFinalizer(new Runnable() {
+            private volatile boolean running;
             public void run() {
+                if (running)
+                    return;
+                running = true;
                 for (;;) {
                     Finalizer f;
                     synchronized (lock) {
@@ -168,10 +176,14 @@
     }
 
     private static class FinalizerThread extends Thread {
+        private volatile boolean running;
         FinalizerThread(ThreadGroup g) {
             super(g, "Finalizer");
         }
         public void run() {
+            if (running)
+                return;
+            running = true;
             for (;;) {
                 try {
                     Finalizer f = (Finalizer)queue.remove();
--- a/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/net/AbstractPlainDatagramSocketImpl.java	Thu Apr 18 14:38:37 2013 -0700
@@ -124,7 +124,7 @@
      * not connected already.
      */
     protected void disconnect() {
-        disconnect0(connectedAddress.family);
+        disconnect0(connectedAddress.holder().getFamily());
         connected = false;
         connectedAddress = null;
         connectedPort = -1;
--- a/src/share/classes/java/net/Inet4Address.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/net/Inet4Address.java	Thu Apr 18 14:38:37 2013 -0700
@@ -102,27 +102,28 @@
 
     Inet4Address() {
         super();
-        hostName = null;
-        address = 0;
-        family = IPv4;
+        holder().hostName = null;
+        holder().address = 0;
+        holder().family = IPv4;
     }
 
     Inet4Address(String hostName, byte addr[]) {
-        this.hostName = hostName;
-        this.family = IPv4;
+        holder().hostName = hostName;
+        holder().family = IPv4;
         if (addr != null) {
             if (addr.length == INADDRSZ) {
-                address  = addr[3] & 0xFF;
+                int address  = addr[3] & 0xFF;
                 address |= ((addr[2] << 8) & 0xFF00);
                 address |= ((addr[1] << 16) & 0xFF0000);
                 address |= ((addr[0] << 24) & 0xFF000000);
+                holder().address = address;
             }
         }
     }
     Inet4Address(String hostName, int address) {
-        this.hostName = hostName;
-        this.family = IPv4;
-        this.address = address;
+        holder().hostName = hostName;
+        holder().family = IPv4;
+        holder().address = address;
     }
 
     /**
@@ -136,8 +137,8 @@
     private Object writeReplace() throws ObjectStreamException {
         // will replace the to be serialized 'this' object
         InetAddress inet = new InetAddress();
-        inet.hostName = this.hostName;
-        inet.address = this.address;
+        inet.holder().hostName = holder().getHostName();
+        inet.holder().address = holder().getAddress();
 
         /**
          * Prior to 1.4 an InetAddress was created with a family
@@ -145,7 +146,7 @@
          * For compatibility reasons we must therefore write the
          * the InetAddress with this family.
          */
-        inet.family = 2;
+        inet.holder().family = 2;
 
         return inet;
     }
@@ -159,7 +160,7 @@
      * @since   JDK1.1
      */
     public boolean isMulticastAddress() {
-        return ((address & 0xf0000000) == 0xe0000000);
+        return ((holder().getAddress() & 0xf0000000) == 0xe0000000);
     }
 
     /**
@@ -169,7 +170,7 @@
      * @since 1.4
      */
     public boolean isAnyLocalAddress() {
-        return address == 0;
+        return holder().getAddress() == 0;
     }
 
     /**
@@ -198,6 +199,7 @@
         // defined in "Documenting Special Use IPv4 Address Blocks
         // that have been Registered with IANA" by Bill Manning
         // draft-manning-dsua-06.txt
+        int address = holder().getAddress();
         return (((address >>> 24) & 0xFF) == 169)
             && (((address >>> 16) & 0xFF) == 254);
     }
@@ -214,6 +216,7 @@
         // 10/8 prefix
         // 172.16/12 prefix
         // 192.168/16 prefix
+        int address = holder().getAddress();
         return (((address >>> 24) & 0xFF) == 10)
             || ((((address >>> 24) & 0xFF) == 172)
                 && (((address >>> 16) & 0xF0) == 16))
@@ -260,6 +263,7 @@
      */
     public boolean isMCLinkLocal() {
         // 224.0.0/24 prefix and ttl == 1
+        int address = holder().getAddress();
         return (((address >>> 24) & 0xFF) == 224)
             && (((address >>> 16) & 0xFF) == 0)
             && (((address >>> 8) & 0xFF) == 0);
@@ -275,6 +279,7 @@
      */
     public boolean isMCSiteLocal() {
         // 239.255/16 prefix or ttl < 32
+        int address = holder().getAddress();
         return (((address >>> 24) & 0xFF) == 239)
             && (((address >>> 16) & 0xFF) == 255);
     }
@@ -290,6 +295,7 @@
      */
     public boolean isMCOrgLocal() {
         // 239.192 - 239.195
+        int address = holder().getAddress();
         return (((address >>> 24) & 0xFF) == 239)
             && (((address >>> 16) & 0xFF) >= 192)
             && (((address >>> 16) & 0xFF) <= 195);
@@ -303,6 +309,7 @@
      * @return  the raw IP address of this object.
      */
     public byte[] getAddress() {
+        int address = holder().getAddress();
         byte[] addr = new byte[INADDRSZ];
 
         addr[0] = (byte) ((address >>> 24) & 0xFF);
@@ -328,7 +335,7 @@
      * @return  a hash code value for this IP address.
      */
     public int hashCode() {
-        return address;
+        return holder().getAddress();
     }
 
     /**
@@ -349,7 +356,7 @@
      */
     public boolean equals(Object obj) {
         return (obj != null) && (obj instanceof Inet4Address) &&
-            (((InetAddress)obj).address == address);
+            (((InetAddress)obj).holder().getAddress() == holder().getAddress());
     }
 
     // Utilities
--- a/src/share/classes/java/net/Inet4AddressImpl.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/net/Inet4AddressImpl.java	Thu Apr 18 14:38:37 2013 -0700
@@ -40,7 +40,7 @@
     public synchronized InetAddress anyLocalAddress() {
         if (anyLocalAddress == null) {
             anyLocalAddress = new Inet4Address(); // {0x00,0x00,0x00,0x00}
-            anyLocalAddress.hostName = "0.0.0.0";
+            anyLocalAddress.holder().hostName = "0.0.0.0";
         }
         return anyLocalAddress;
     }
--- a/src/share/classes/java/net/Inet6Address.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/net/Inet6Address.java	Thu Apr 18 14:38:37 2013 -0700
@@ -213,18 +213,18 @@
 
     Inet6Address() {
         super();
-        hostName = null;
+        holder().hostName = null;
         ipaddress = new byte[INADDRSZ];
-        family = IPv6;
+        holder().family = IPv6;
     }
 
     /* checking of value for scope_id should be done by caller
      * scope_id must be >= 0, or -1 to indicate not being set
      */
     Inet6Address(String hostName, byte addr[], int scope_id) {
-        this.hostName = hostName;
+        holder().hostName = hostName;
         if (addr.length == INADDRSZ) { // normal IPv6 address
-            family = IPv6;
+            holder().family = IPv6;
             ipaddress = addr.clone();
         }
         if (scope_id >= 0) {
@@ -325,9 +325,9 @@
     }
 
     private void initif(String hostName, byte addr[],NetworkInterface nif) throws UnknownHostException {
-        this.hostName = hostName;
+        holder().hostName = hostName;
         if (addr.length == INADDRSZ) { // normal IPv6 address
-            family = IPv6;
+            holder().family = IPv6;
             ipaddress = addr.clone();
         }
         if (nif != null) {
@@ -412,6 +412,11 @@
         throws IOException, ClassNotFoundException {
         scope_ifname = null;
         scope_ifname_set = false;
+
+        if (getClass().getClassLoader() != null) {
+            throw new SecurityException ("invalid address type");
+        }
+
         s.defaultReadObject();
 
         if (ifname != null && !"".equals (ifname)) {
@@ -445,7 +450,7 @@
                                              ipaddress.length);
         }
 
-        if (family != IPv6) {
+        if (holder().getFamily() != IPv6) {
             throw new InvalidObjectException("invalid address family type");
         }
     }
--- a/src/share/classes/java/net/Inet6AddressImpl.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/net/Inet6AddressImpl.java	Thu Apr 18 14:38:37 2013 -0700
@@ -81,7 +81,7 @@
         if (anyLocalAddress == null) {
             if (InetAddress.preferIPv6Address) {
                 anyLocalAddress = new Inet6Address();
-                anyLocalAddress.hostName = "::";
+                anyLocalAddress.holder().hostName = "::";
             } else {
                 anyLocalAddress = (new Inet4AddressImpl()).anyLocalAddress();
             }
--- a/src/share/classes/java/net/InetAddress.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/net/InetAddress.java	Thu Apr 18 14:38:37 2013 -0700
@@ -34,8 +34,12 @@
 import java.util.ArrayList;
 import java.security.AccessController;
 import java.io.ObjectStreamException;
+import java.io.ObjectStreamField;
 import java.io.IOException;
 import java.io.ObjectInputStream;
+import java.io.ObjectInputStream.GetField;
+import java.io.ObjectOutputStream;
+import java.io.ObjectOutputStream.PutField;
 import sun.security.action.*;
 import sun.net.InetAddressCachePolicy;
 import sun.net.util.IPAddressUtil;
@@ -199,25 +203,47 @@
     /* Specify address family preference */
     static transient boolean preferIPv6Address = false;
 
-    /**
-     * @serial
-     */
-    String hostName;
+    static class InetAddressHolder {
 
-    /**
-     * Holds a 32-bit IPv4 address.
-     *
-     * @serial
-     */
-    int address;
+        InetAddressHolder() {}
 
-    /**
-     * Specifies the address family type, for instance, '1' for IPv4
-     * addresses, and '2' for IPv6 addresses.
-     *
-     * @serial
-     */
-    int family;
+        InetAddressHolder(String hostName, int address, int family) {
+            this.hostName = hostName;
+            this.address = address;
+            this.family = family;
+        }
+
+        String hostName;
+
+        String getHostName() {
+            return hostName;
+        }
+
+        /**
+         * Holds a 32-bit IPv4 address.
+         */
+        int address;
+
+        int getAddress() {
+            return address;
+        }
+
+        /**
+         * Specifies the address family type, for instance, '1' for IPv4
+         * addresses, and '2' for IPv6 addresses.
+         */
+        int family;
+
+        int getFamily() {
+            return family;
+        }
+    }
+
+    final transient InetAddressHolder holder;
+
+    InetAddressHolder holder() {
+        return holder;
+    }
 
     /* Used to store the name service provider */
     private static List<NameService> nameServices = null;
@@ -245,6 +271,7 @@
      * put in the address cache, since it is not created by name.
      */
     InetAddress() {
+        holder = new InetAddressHolder();
     }
 
     /**
@@ -257,7 +284,7 @@
      */
     private Object readResolve() throws ObjectStreamException {
         // will replace the deserialized 'this' object
-        return new Inet4Address(this.hostName, this.address);
+        return new Inet4Address(holder().getHostName(), holder().getAddress());
     }
 
     /**
@@ -494,10 +521,10 @@
      * @see SecurityManager#checkConnect
      */
     String getHostName(boolean check) {
-        if (hostName == null) {
-            hostName = InetAddress.getHostFromNameService(this, check);
+        if (holder().getHostName() == null) {
+            holder().hostName = InetAddress.getHostFromNameService(this, check);
         }
-        return hostName;
+        return holder().getHostName();
     }
 
     /**
@@ -660,6 +687,7 @@
      * @return  a string representation of this IP address.
      */
     public String toString() {
+        String hostName = holder().getHostName();
         return ((hostName != null) ? hostName : "")
             + "/" + getHostAddress();
     }
@@ -1515,14 +1543,58 @@
         }
     }
 
+    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(
+                InetAddress.class.getDeclaredField("holder")
+            );
+            UNSAFE = unsafe;
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+    }
+
     private void readObject (ObjectInputStream s) throws
                          IOException, ClassNotFoundException {
-        s.defaultReadObject ();
         if (getClass().getClassLoader() != null) {
-            hostName = null;
-            address = 0;
             throw new SecurityException ("invalid address type");
         }
+        GetField gf = s.readFields();
+        String host = (String)gf.get("hostName", null);
+        int address= gf.get("address", 0);
+        int family= gf.get("family", 0);
+        InetAddressHolder h = new InetAddressHolder(host, address, family);
+        UNSAFE.putObject(this, FIELDS_OFFSET, h);
+    }
+
+    /* needed because the serializable fields no longer exist */
+
+    /**
+     * @serialField hostName String
+     * @serialField address int
+     * @serialField family int
+     */
+    private static final ObjectStreamField[] serialPersistentFields = {
+        new ObjectStreamField("hostName", String.class),
+        new ObjectStreamField("address", int.class),
+        new ObjectStreamField("family", int.class),
+    };
+
+    private void writeObject (ObjectOutputStream s) throws
+                        IOException {
+        if (getClass().getClassLoader() != null) {
+            throw new SecurityException ("invalid address type");
+        }
+        PutField pf = s.putFields();
+        pf.put("hostName", holder().hostName);
+        pf.put("address", holder().address);
+        pf.put("family", holder().family);
+        s.writeFields();
+        s.flush();
     }
 }
 
--- a/src/share/classes/java/net/InetSocketAddress.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/net/InetSocketAddress.java	Thu Apr 18 14:38:37 2013 -0700
@@ -87,8 +87,8 @@
             if (hostname != null)
                 return hostname;
             if (addr != null) {
-                if (addr.hostName != null)
-                    return addr.hostName;
+                if (addr.holder().getHostName() != null)
+                    return addr.holder().getHostName();
                 else
                     return addr.getHostAddress();
             }
--- a/src/share/classes/java/rmi/server/LogStream.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/rmi/server/LogStream.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2004, 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
@@ -120,6 +120,13 @@
      */
     @Deprecated
     public static synchronized void setDefaultStream(PrintStream newDefault) {
+        SecurityManager sm = System.getSecurityManager();
+
+        if (sm != null) {
+            sm.checkPermission(
+                new java.util.logging.LoggingPermission("control", null));
+        }
+
         defaultStream = newDefault;
     }
 
--- a/src/share/classes/java/sql/DriverManager.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/sql/DriverManager.java	Thu Apr 18 14:38:37 2013 -0700
@@ -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
@@ -516,7 +516,7 @@
                  */
                 try{
                     while(driversIterator.hasNext()) {
-                        println(" Loading done by the java.util.ServiceLoader :  "+driversIterator.next());
+                        driversIterator.next();
                     }
                 } catch(Throwable t) {
                 // Do nothing
--- a/src/share/classes/java/util/concurrent/ConcurrentHashMap.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/java/util/concurrent/ConcurrentHashMap.java	Thu Apr 18 14:38:37 2013 -0700
@@ -40,6 +40,7 @@
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
 
 /**
  * A hash table supporting full concurrency of retrievals and
@@ -1535,7 +1536,23 @@
     @SuppressWarnings("unchecked")
     private void readObject(java.io.ObjectInputStream s)
         throws IOException, ClassNotFoundException {
-        s.defaultReadObject();
+        // Don't call defaultReadObject()
+        ObjectInputStream.GetField oisFields = s.readFields();
+        final Segment<K,V>[] oisSegments = (Segment<K,V>[])oisFields.get("segments", null);
+
+        final int ssize = oisSegments.length;
+        if (ssize < 1 || ssize > MAX_SEGMENTS
+            || (ssize & (ssize-1)) != 0 )  // ssize not power of two
+            throw new java.io.InvalidObjectException("Bad number of segments:"
+                                                     + ssize);
+        int sshift = 0, ssizeTmp = ssize;
+        while (ssizeTmp > 1) {
+            ++sshift;
+            ssizeTmp >>>= 1;
+        }
+        UNSAFE.putIntVolatile(this, SEGSHIFT_OFFSET, 32 - sshift);
+        UNSAFE.putIntVolatile(this, SEGMASK_OFFSET, ssize - 1);
+        UNSAFE.putObjectVolatile(this, SEGMENTS_OFFSET, oisSegments);
 
         // set hashMask
         UNSAFE.putIntVolatile(this, HASHSEED_OFFSET, randomHashSeed(this));
@@ -1568,6 +1585,9 @@
     private static final long TBASE;
     private static final int TSHIFT;
     private static final long HASHSEED_OFFSET;
+    private static final long SEGSHIFT_OFFSET;
+    private static final long SEGMASK_OFFSET;
+    private static final long SEGMENTS_OFFSET;
 
     static {
         int ss, ts;
@@ -1581,6 +1601,12 @@
             ss = UNSAFE.arrayIndexScale(sc);
             HASHSEED_OFFSET = UNSAFE.objectFieldOffset(
                 ConcurrentHashMap.class.getDeclaredField("hashSeed"));
+            SEGSHIFT_OFFSET = UNSAFE.objectFieldOffset(
+                ConcurrentHashMap.class.getDeclaredField("segmentShift"));
+            SEGMASK_OFFSET = UNSAFE.objectFieldOffset(
+                ConcurrentHashMap.class.getDeclaredField("segmentMask"));
+            SEGMENTS_OFFSET = UNSAFE.objectFieldOffset(
+                ConcurrentHashMap.class.getDeclaredField("segments"));
         } catch (Exception e) {
             throw new Error(e);
         }
--- a/src/share/classes/sun/awt/EmbeddedFrame.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/awt/EmbeddedFrame.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2010, 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
@@ -532,7 +532,7 @@
         public void toBack() {}
         public void updateFocusableWindowState() {}
         public void updateAlwaysOnTop() {}
-        public void setAlwaysOnTop(boolean alwaysOnTop) {}
+        public void updateAlwaysOnTopState() {}
         public Component getGlobalHeavyweightFocusOwner() { return null; }
         public void setBoundsPrivate(int x, int y, int width, int height) {
             setBounds(x, y, width, height, SET_BOUNDS);
--- a/src/share/classes/sun/awt/datatransfer/TransferableProxy.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/awt/datatransfer/TransferableProxy.java	Thu Apr 18 14:38:37 2013 -0700
@@ -102,11 +102,11 @@
     protected final boolean isLocal;
 }
 
-class ClassLoaderObjectOutputStream extends ObjectOutputStream {
+final class ClassLoaderObjectOutputStream extends ObjectOutputStream {
     private final Map<Set<String>, ClassLoader> map =
         new HashMap<Set<String>, ClassLoader>();
 
-    public ClassLoaderObjectOutputStream(OutputStream os) throws IOException {
+    ClassLoaderObjectOutputStream(OutputStream os) throws IOException {
         super(os);
     }
 
@@ -140,15 +140,15 @@
         map.put(s, classLoader);
     }
 
-    public Map<Set<String>, ClassLoader> getClassLoaderMap() {
+    Map<Set<String>, ClassLoader> getClassLoaderMap() {
         return new HashMap(map);
     }
 }
 
-class ClassLoaderObjectInputStream extends ObjectInputStream {
+final class ClassLoaderObjectInputStream extends ObjectInputStream {
     private final Map<Set<String>, ClassLoader> map;
 
-    public ClassLoaderObjectInputStream(InputStream is,
+    ClassLoaderObjectInputStream(InputStream is,
                                         Map<Set<String>, ClassLoader> map)
       throws IOException {
         super(is);
@@ -166,8 +166,11 @@
         s.add(className);
 
         ClassLoader classLoader = map.get(s);
-
-        return Class.forName(className, false, classLoader);
+        if (classLoader != null) {
+            return Class.forName(className, false, classLoader);
+        } else {
+            return super.resolveClass(classDesc);
+        }
     }
 
     protected Class<?> resolveProxyClass(String[] interfaces)
@@ -179,6 +182,9 @@
         }
 
         ClassLoader classLoader = map.get(s);
+        if (classLoader == null) {
+            return super.resolveProxyClass(interfaces);
+        }
 
         // The code below is mostly copied from the superclass.
         ClassLoader nonPublicLoader = null;
--- a/src/share/classes/sun/awt/image/ImageRepresentation.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/awt/image/ImageRepresentation.java	Thu Apr 18 14:38:37 2013 -0700
@@ -333,10 +333,10 @@
         hints = h;
     }
 
-    private native void setICMpixels(int x, int y, int w, int h, int[] lut,
+    private native boolean setICMpixels(int x, int y, int w, int h, int[] lut,
                                     byte[] pix, int off, int scansize,
                                     IntegerComponentRaster ict);
-    private native int setDiffICM(int x, int y, int w, int h, int[] lut,
+    private native boolean setDiffICM(int x, int y, int w, int h, int[] lut,
                                  int transPix, int numLut, IndexColorModel icm,
                                  byte[] pix, int off, int scansize,
                                  ByteComponentRaster bct, int chanOff);
@@ -426,10 +426,10 @@
                 IndexColorModel icm = (IndexColorModel) model;
                 ByteComponentRaster bct = (ByteComponentRaster) biRaster;
                 int numlut = numSrcLUT;
-                if (setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex,
+                if (!setDiffICM(x, y, w, h, srcLUT, srcLUTtransIndex,
                                numSrcLUT, icm,
                                pix, off, scansize, bct,
-                               bct.getDataOffset(0)) == 0) {
+                               bct.getDataOffset(0))) {
                     convertToRGB();
                 }
                 else {
@@ -470,9 +470,14 @@
                     if (s_useNative) {
                         // Note that setICMpixels modifies the raster directly
                         // so we must mark it as changed afterwards
-                        setICMpixels(x, y, w, h, srcLUT, pix, off, scansize,
-                                     iraster);
-                        iraster.markDirty();
+                        if (setICMpixels(x, y, w, h, srcLUT, pix, off, scansize,
+                                     iraster))
+                        {
+                            iraster.markDirty();
+                        } else {
+                            abort();
+                            return;
+                        }
                     }
                     else {
                         int[] storage = new int[w*h];
--- a/src/share/classes/sun/font/CMap.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/font/CMap.java	Thu Apr 18 14:38:37 2013 -0700
@@ -841,7 +841,6 @@
 
         CMapFormat6(ByteBuffer bbuffer, int offset, char[] xlat) {
 
-             System.err.println("WARNING: CMapFormat8 is untested.");
              bbuffer.position(offset+6);
              CharBuffer buffer = bbuffer.asCharBuffer();
              firstCode = buffer.get();
@@ -884,7 +883,6 @@
 
          CMapFormat8(ByteBuffer bbuffer, int offset, char[] xlat) {
 
-             System.err.println("WARNING: CMapFormat8 is untested.");
              bbuffer.position(12);
              bbuffer.get(is32);
              nGroups = bbuffer.getInt();
@@ -915,7 +913,6 @@
 
          CMapFormat10(ByteBuffer bbuffer, int offset, char[] xlat) {
 
-             System.err.println("WARNING: CMapFormat10 is untested.");
              firstCode = bbuffer.getInt() & INTMASK;
              entryCount = bbuffer.getInt() & INTMASK;
              bbuffer.position(offset+20);
--- a/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java	Thu Apr 18 14:38:37 2013 -0700
@@ -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
@@ -791,10 +791,10 @@
 
         // convert source to IntArgbPre
         SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h,
-                          cachedDst, BufferedImage.TYPE_INT_ARGB_PRE);
+                                            cachedDst, BufferedImage.TYPE_INT_ARGB_PRE);
 
         Blit performop = Blit.getFromCache(src.getSurfaceType(),
-                CompositeType.Any, dstBuffer.getSurfaceType());
+        CompositeType.Any, dstBuffer.getSurfaceType());
 
         performop.Blit(src, dstBuffer, comp, clip,
                        sx, sy, 0, 0, w, h);
@@ -806,9 +806,9 @@
 
         // now blit the buffer back to the destination
         convertdst = Blit.getFromCache(dstBuffer.getSurfaceType(),
-                                            CompositeType.SrcNoEa,
-                                            dst.getSurfaceType());
+                                       CompositeType.SrcNoEa,
+                                       dst.getSurfaceType());
         convertdst.Blit(dstBuffer, dst, AlphaComposite.Src,
-                 clip, 0, 0, dx, dy, w, h);
+                        clip, 0, 0, dx, dy, w, h);
     }
 }
--- a/src/share/classes/sun/java2d/opengl/OGLSurfaceDataProxy.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/java2d/opengl/OGLSurfaceDataProxy.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 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
--- a/src/share/classes/sun/net/ftp/impl/FtpClient.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/net/ftp/impl/FtpClient.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1299,16 +1299,16 @@
      *         <code>null</code> if the command was unsuccessful.
      * @throws IOException if an error occured during the transmission.
      */
-    public OutputStream putFileStream(String name, boolean unique) throws sun.net.ftp.FtpProtocolException, IOException {
+    public OutputStream putFileStream(String name, boolean unique)
+        throws sun.net.ftp.FtpProtocolException, IOException
+    {
         String cmd = unique ? "STOU " : "STOR ";
         Socket s = openDataConnection(cmd + name);
         if (s == null) {
             return null;
         }
-        if (type == TransferType.BINARY) {
-            return s.getOutputStream();
-        }
-        return new sun.net.TelnetOutputStream(s.getOutputStream(), false);
+        boolean bm = (type == TransferType.BINARY);
+        return new sun.net.TelnetOutputStream(s.getOutputStream(), bm);
     }
 
     /**
--- a/src/share/classes/sun/reflect/misc/MethodUtil.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/reflect/misc/MethodUtil.java	Thu Apr 18 14:38:37 2013 -0700
@@ -50,8 +50,28 @@
 
 
 class Trampoline {
+    static {
+        if (Trampoline.class.getClassLoader() == null) {
+            throw new Error(
+                "Trampoline must not be defined by the bootstrap classloader");
+        }
+    }
+
+    private static void ensureInvocableMethod(Method m)
+        throws InvocationTargetException
+    {
+        Class<?> clazz = m.getDeclaringClass();
+        if (clazz.equals(AccessController.class) ||
+            clazz.equals(Method.class) ||
+            clazz.getName().startsWith("java.lang.invoke."))
+            throw new InvocationTargetException(
+                new UnsupportedOperationException("invocation not supported"));
+    }
+
     private static Object invoke(Method m, Object obj, Object[] params)
-        throws InvocationTargetException, IllegalAccessException {
+        throws InvocationTargetException, IllegalAccessException
+    {
+        ensureInvocableMethod(m);
         return m.invoke(obj, params);
     }
 }
@@ -255,16 +275,6 @@
      */
     public static Object invoke(Method m, Object obj, Object[] params)
         throws InvocationTargetException, IllegalAccessException {
-        if (m.getDeclaringClass().equals(AccessController.class) ||
-           (m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.class)
-            && m.getName().equals("lookup")) ||
-           (m.getDeclaringClass().equals(java.lang.invoke.MethodHandles.Lookup.class)
-            && (m.getName().startsWith("find") ||
-                m.getName().startsWith("bind") ||
-                m.getName().startsWith("unreflect"))) ||
-            m.getDeclaringClass().equals(Method.class))
-            throw new InvocationTargetException(
-                new UnsupportedOperationException("invocation not supported"));
         try {
             return bounce.invoke(null, new Object[] {m, obj, params});
         } catch (InvocationTargetException ie) {
@@ -297,10 +307,10 @@
                             Method.class, Object.class, Object[].class
                         };
                         Method b = t.getDeclaredMethod("invoke", types);
-                    ((AccessibleObject)b).setAccessible(true);
-                    return b;
-                }
-            });
+                        b.setAccessible(true);
+                        return b;
+                    }
+                });
         } catch (Exception e) {
             throw new InternalError("bouncer cannot be found");
         }
--- a/src/share/classes/sun/reflect/misc/ReflectUtil.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/reflect/misc/ReflectUtil.java	Thu Apr 18 14:38:37 2013 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
--- a/src/share/classes/sun/rmi/server/MarshalInputStream.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/rmi/server/MarshalInputStream.java	Thu Apr 18 14:38:37 2013 -0700
@@ -55,13 +55,19 @@
 public class MarshalInputStream extends ObjectInputStream {
 
     /**
-     * value of "java.rmi.server.useCodebaseOnly" property,
+     * Value of "java.rmi.server.useCodebaseOnly" property,
      * as cached at class initialization time.
+     *
+     * The default value is true. That is, the value is true
+     * if the property is absent or is not equal to "false".
+     * The value is only false when the property is present
+     * and is equal to "false".
      */
     private static final boolean useCodebaseOnlyProperty =
-        java.security.AccessController.doPrivileged(
-            new sun.security.action.GetBooleanAction(
-                "java.rmi.server.useCodebaseOnly")).booleanValue();
+        ! java.security.AccessController.doPrivileged(
+            new sun.security.action.GetPropertyAction(
+                "java.rmi.server.useCodebaseOnly", "true"))
+            .equalsIgnoreCase("false");
 
     /** table to hold sun classes to which access is explicitly permitted */
     protected static Map<String, Class<?>> permittedSunClasses
--- a/src/share/classes/sun/security/krb5/PrincipalName.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/security/krb5/PrincipalName.java	Thu Apr 18 14:38:37 2013 -0700
@@ -461,7 +461,7 @@
     }
 
     public String[] getNameStrings() {
-        return nameStrings;
+        return nameStrings.clone();
     }
 
     public byte[][] toByteArray() {
--- a/src/share/classes/sun/security/pkcs/PKCS7.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/security/pkcs/PKCS7.java	Thu Apr 18 14:38:37 2013 -0700
@@ -133,7 +133,8 @@
             } catch (IOException ioe1) {
                 ParsingException pe = new ParsingException(
                     ioe1.getMessage());
-                pe.initCause(ioe1);
+                pe.initCause(ioe);
+                pe.addSuppressed(ioe1);
                 throw pe;
             }
         }
@@ -281,19 +282,26 @@
 
             len = certVals.length;
             certificates = new X509Certificate[len];
+            int count = 0;
 
             for (int i = 0; i < len; i++) {
                 ByteArrayInputStream bais = null;
                 try {
-                    if (certfac == null)
-                        certificates[i] = new X509CertImpl(certVals[i]);
-                    else {
-                        byte[] encoded = certVals[i].toByteArray();
-                        bais = new ByteArrayInputStream(encoded);
-                        certificates[i] =
-                            (X509Certificate)certfac.generateCertificate(bais);
-                        bais.close();
-                        bais = null;
+                    byte tag = certVals[i].getTag();
+                    // We only parse the normal certificate. Other types of
+                    // CertificateChoices ignored.
+                    if (tag == DerValue.tag_Sequence) {
+                        if (certfac == null) {
+                            certificates[count] = new X509CertImpl(certVals[i]);
+                        } else {
+                            byte[] encoded = certVals[i].toByteArray();
+                            bais = new ByteArrayInputStream(encoded);
+                            certificates[count] =
+                                (X509Certificate)certfac.generateCertificate(bais);
+                            bais.close();
+                            bais = null;
+                        }
+                        count++;
                     }
                 } catch (CertificateException ce) {
                     ParsingException pe = new ParsingException(ce.getMessage());
@@ -308,6 +316,9 @@
                         bais.close();
                 }
             }
+            if (count != len) {
+                certificates = Arrays.copyOf(certificates, count);
+            }
         }
 
         // check if crls (implicit tag) are provided (crls are OPTIONAL)
--- a/src/share/classes/sun/security/pkcs/PKCS9Attribute.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/security/pkcs/PKCS9Attribute.java	Thu Apr 18 14:38:37 2013 -0700
@@ -42,12 +42,14 @@
 
 /**
  * Class supporting any PKCS9 attributes.
- * Supports DER decoding and access to attribute values, but not
- * DER encoding or setting of values.
+ * Supports DER decoding/encoding and access to attribute values.
  *
  * <a name="classTable"><h3>Type/Class Table</h3></a>
  * The following table shows the correspondence between
  * PKCS9 attribute types and value component classes.
+ * For types not listed here, its name is the OID
+ * in string form, its value is a (single-valued)
+ * byte array that is the SET's encoding.
  *
  * <P>
  * <TABLE BORDER CELLPADDING=8 ALIGN=CENTER>
@@ -185,6 +187,8 @@
      */
     static final ObjectIdentifier[] PKCS9_OIDS = new ObjectIdentifier[18];
 
+    private final static Class<?> BYTE_ARRAY_CLASS;
+
     static {   // static initializer for PKCS9_OIDS
         for (int i = 1; i < PKCS9_OIDS.length - 2; i++) {
             PKCS9_OIDS[i] =
@@ -196,6 +200,12 @@
             ObjectIdentifier.newInternal(new int[]{1,2,840,113549,1,9,16,2,12});
         PKCS9_OIDS[PKCS9_OIDS.length - 1] =
             ObjectIdentifier.newInternal(new int[]{1,2,840,113549,1,9,16,2,14});
+
+        try {
+            BYTE_ARRAY_CLASS = Class.forName("[B");
+        } catch (ClassNotFoundException e) {
+            throw new ExceptionInInitializerError(e.toString());
+        }
     }
 
     // first element [0] not used
@@ -331,7 +341,7 @@
             VALUE_CLASSES[2] = str;   // UnstructuredName
             VALUE_CLASSES[3] =        // ContentType
                 Class.forName("sun.security.util.ObjectIdentifier");
-            VALUE_CLASSES[4] = Class.forName("[B"); // MessageDigest (byte[])
+            VALUE_CLASSES[4] = BYTE_ARRAY_CLASS; // MessageDigest (byte[])
             VALUE_CLASSES[5] = Class.forName("java.util.Date"); // SigningTime
             VALUE_CLASSES[6] =        // Countersignature
                 Class.forName("[Lsun.security.pkcs.SignerInfo;");
@@ -347,7 +357,7 @@
                 Class.forName("sun.security.x509.CertificateExtensions");
             VALUE_CLASSES[15] = null;  // not supported yet
             VALUE_CLASSES[16] = null;  // not supported yet
-            VALUE_CLASSES[17] = Class.forName("[B");  // SignatureTimestampToken
+            VALUE_CLASSES[17] = BYTE_ARRAY_CLASS;  // SignatureTimestampToken
         } catch (ClassNotFoundException e) {
             throw new ExceptionInInitializerError(e.toString());
         }
@@ -379,13 +389,20 @@
     };
 
     /**
-     * The OID of this attribute is <code>PKCS9_OIDS[index]</code>.
+     * The OID of this attribute.
+     */
+    private ObjectIdentifier oid;
+
+    /**
+     * The index of the OID of this attribute in <code>PKCS9_OIDS</code>,
+     * or -1 if it's unknown.
      */
     private int index;
 
     /**
      * Value set of this attribute.  Its class is given by
-     * <code>VALUE_CLASSES[index]</code>.
+     * <code>VALUE_CLASSES[index]</code>. The SET itself
+     * as byte[] if unknown.
      */
     private Object value;
 
@@ -400,6 +417,8 @@
      * <a href=#classTable>table</a> gives the class that <code>value</code>
      * must have for a given attribute.
      *
+     * @exception IllegalArgumentException
+     * if the <code>value</code> has the wrong type.
      */
     public PKCS9Attribute(ObjectIdentifier oid, Object value)
     throws IllegalArgumentException {
@@ -419,7 +438,7 @@
      * attributes are accepted; in particular, case does not matter.
      *
      * @exception IllegalArgumentException
-     * if the <code>name</code> is not recognized of the
+     * if the <code>name</code> is not recognized or the
      * <code>value</code> has the wrong type.
      */
     public PKCS9Attribute(String name, Object value)
@@ -437,21 +456,17 @@
     private void init(ObjectIdentifier oid, Object value)
         throws IllegalArgumentException {
 
+        this.oid = oid;
         index = indexOf(oid, PKCS9_OIDS, 1);
-
-        if (index == -1)
-            throw new IllegalArgumentException(
-                       "Unsupported OID " + oid +
-                       " constructing PKCS9Attribute.");
-
-        if (!VALUE_CLASSES[index].isInstance(value))
+        Class<?> clazz = index == -1 ? BYTE_ARRAY_CLASS: VALUE_CLASSES[index];
+        if (!clazz.isInstance(value)) {
                 throw new IllegalArgumentException(
                            "Wrong value class " +
                            " for attribute " + oid +
                            " constructing PKCS9Attribute; was " +
                            value.getClass().toString() + ", should be " +
-                           VALUE_CLASSES[index].toString());
-
+                           clazz.toString());
+        }
         this.value = value;
     }
 
@@ -475,16 +490,19 @@
             throw new IOException("PKCS9Attribute doesn't have two components");
 
         // get the oid
-        ObjectIdentifier oid = val[0].getOID();
+        oid = val[0].getOID();
+        byte[] content = val[1].toByteArray();
+        DerValue[] elems = new DerInputStream(content).getSet(1);
+
         index = indexOf(oid, PKCS9_OIDS, 1);
         if (index == -1) {
             if (debug != null) {
-                debug.println("ignoring unsupported signer attribute: " + oid);
+                debug.println("Unsupported signer attribute: " + oid);
             }
-            throw new ParsingException("Unsupported PKCS9 attribute: " + oid);
+            value = content;
+            return;
         }
 
-        DerValue[] elems = new DerInputStream(val[1].toByteArray()).getSet(1);
         // check single valued have only one value
         if (SINGLE_VALUED[index] && elems.length > 1)
             throwSingleValuedException();
@@ -584,8 +602,11 @@
      */
     public void derEncode(OutputStream out) throws IOException {
         DerOutputStream temp = new DerOutputStream();
-        temp.putOID(getOID());
+        temp.putOID(oid);
         switch (index) {
+        case -1:    // Unknown
+            temp.write((byte[])value);
+            break;
         case 1:     // email address
         case 2:     // unstructured name
             { // open scope
@@ -704,6 +725,14 @@
     }
 
     /**
+     * Returns if the attribute is known. Unknown attributes can be created
+     * from DER encoding with unknown OIDs.
+     */
+    public boolean isKnown() {
+        return index != -1;
+    }
+
+    /**
      * Get the value of this attribute.  If the attribute is
      * single-valued, return just the one value.  If the attribute is
      * multi-valued, return an array containing all the values.
@@ -721,21 +750,23 @@
      * Show whether this attribute is single-valued.
      */
     public boolean isSingleValued() {
-        return SINGLE_VALUED[index];
+        return index == -1 || SINGLE_VALUED[index];
     }
 
     /**
      *  Return the OID of this attribute.
      */
     public ObjectIdentifier getOID() {
-        return PKCS9_OIDS[index];
+        return oid;
     }
 
     /**
      *  Return the name of this attribute.
      */
     public String getName() {
-        return OID_NAME_TABLE.get(PKCS9_OIDS[index]);
+        return index == -1 ?
+                oid.toString() :
+                OID_NAME_TABLE.get(PKCS9_OIDS[index]);
     }
 
     /**
@@ -762,10 +793,14 @@
 
         buf.append("[");
 
-        buf.append(OID_NAME_TABLE.get(PKCS9_OIDS[index]));
+        if (index == -1) {
+            buf.append(oid.toString());
+        } else {
+            buf.append(OID_NAME_TABLE.get(PKCS9_OIDS[index]));
+        }
         buf.append(": ");
 
-        if (SINGLE_VALUED[index]) {
+        if (index == -1 || SINGLE_VALUED[index]) {
             if (value instanceof byte[]) { // special case for octet string
                 HexDumpEncoder hexDump = new HexDumpEncoder();
                 buf.append(hexDump.encodeBuffer((byte[]) value));
@@ -809,20 +844,21 @@
      */
     private void throwSingleValuedException() throws IOException {
         throw new IOException("Single-value attribute " +
-                              getOID() + " (" + getName() + ")" +
+                              oid + " (" + getName() + ")" +
                               " has multiple values.");
     }
 
     /**
      * Throw an exception when the tag on a value encoding is
-     * wrong for the attribute whose value it is.
+     * wrong for the attribute whose value it is. This method
+     * will only be called for known tags.
      */
     private void throwTagException(Byte tag)
     throws IOException {
         Byte[] expectedTags = PKCS9_VALUE_TAGS[index];
         StringBuffer msg = new StringBuffer(100);
         msg.append("Value of attribute ");
-        msg.append(getOID().toString());
+        msg.append(oid.toString());
         msg.append(" (");
         msg.append(getName());
         msg.append(") has wrong tag: ");
--- a/src/share/classes/sun/security/util/UntrustedCertificates.java	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/classes/sun/security/util/UntrustedCertificates.java	Thu Apr 18 14:38:37 2013 -0700
@@ -843,5 +843,52 @@
         "zCOfhbsRWdMLYepauaNZOIMZXmFwcrIl0TGMkTAtATz+XmZc\n" +
         "-----END CERTIFICATE-----");
 
+        //
+        // Revoked code signing certificate w/ a stolen key issued by GoDaddy
+        // used to sign malware
+        //
+
+        // Subject: CN=CLEARESULT CONSULTING INC., OU=Corporate IT,
+        //          O=CLEARESULT CONSULTING INC., L=Austin, ST=TX, C=US
+        // Issuer:  SERIALNUMBER=07969287,
+        //          CN=Go Daddy Secure Certification Authority,
+        //          OU=http://certificates.godaddy.com/repository,
+        //          O="GoDaddy.com, Inc.",
+        //          L=Scottsdale,
+        //          ST=Arizona,
+        //          C=US
+        // Serial:  2b:73:43:2a:a8:4f:44
+        add("clearesult-consulting-inc-2AA84F44",
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIFYjCCBEqgAwIBAgIHK3NDKqhPRDANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE\n" +
+        "BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY\n" +
+        "BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm\n" +
+        "aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5\n" +
+        "IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky\n" +
+        "ODcwHhcNMTIwMjE1MjEwOTA2WhcNMTQwMjE1MjEwOTA2WjCBjDELMAkGA1UEBgwC\n" +
+        "VVMxCzAJBgNVBAgMAlRYMQ8wDQYDVQQHDAZBdXN0aW4xIzAhBgNVBAoMGkNMRUFS\n" +
+        "RVNVTFQgQ09OU1VMVElORyBJTkMuMRUwEwYDVQQLDAxDb3Jwb3JhdGUgSVQxIzAh\n" +
+        "BgNVBAMMGkNMRUFSRVNVTFQgQ09OU1VMVElORyBJTkMuMIIBIjANBgkqhkiG9w0B\n" +
+        "AQEFAAOCAQ8AMIIBCgKCAQEAtIOjCKeAicull+7ZIzt0/4ya3IeXUFlfypqKMLkU\n" +
+        "IbKjn0P5uMj6VE3rlbZr44RCegxvdnR6umBh1c0ZXoN3o+yc0JKcKcLiApmJJ277\n" +
+        "p7IbLwYDhBXRQNoIJm187IOMRPIxsKN4hL91txn9jGBmW+9zKlJlNhR5R7vjwU2E\n" +
+        "jrH/6oqsc9EM2yYpfjlNv6+3jSwAYZCkSWr+27PQOV+YHKmIxtJjX0upFz5FdIrV\n" +
+        "9CCX+L2Kji1THOkSgG4QTbYxmEcHqGViWz8hXLeNXjcbEsPuIiAu3hknxRHfUTE/\n" +
+        "U0Lh0Ug1e3LrJu+WnxM2SmUY4krsZ22c0yWUW9hzWITIjQIDAQABo4IBhzCCAYMw\n" +
+        "DwYDVR0TAQH/BAUwAwEBADATBgNVHSUEDDAKBggrBgEFBQcDAzAOBgNVHQ8BAf8E\n" +
+        "BAMCB4AwMwYDVR0fBCwwKjAooCagJIYiaHR0cDovL2NybC5nb2RhZGR5LmNvbS9n\n" +
+        "ZHM1LTE2LmNybDBTBgNVHSAETDBKMEgGC2CGSAGG/W0BBxcCMDkwNwYIKwYBBQUH\n" +
+        "AgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS8w\n" +
+        "gYAGCCsGAQUFBwEBBHQwcjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZ29kYWRk\n" +
+        "eS5jb20vMEoGCCsGAQUFBzAChj5odHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHku\n" +
+        "Y29tL3JlcG9zaXRvcnkvZ2RfaW50ZXJtZWRpYXRlLmNydDAfBgNVHSMEGDAWgBT9\n" +
+        "rGEyk2xF1uLuhV+auud2mWjM5zAdBgNVHQ4EFgQUDtdeKqeN2QkcbEp1HovFieNB\n" +
+        "XiowDQYJKoZIhvcNAQEFBQADggEBAD74Agw5tvi2aBl4/f/s7/VE/BClzDsKMb9K\n" +
+        "v9qpeC45ZA/jelxV11HKbQnVF194gDb7D2H9OsAsRUy8HVKbXEcc/8dKvwOqb+BC\n" +
+        "2i/EmfjLgmCfezNFtLq8xcPxF3zIRc44vPrK0z4YZsaHdH+yTEJ51p5EMdTqaLaP\n" +
+        "4n5m8LX3RfqlQB9dYFe6dUoYZjKm9d/pIRww3VqfOzjl42Edi1w6dWmBVMx1NZuR\n" +
+        "DBabJH1vJ9Gd+KwxMCmBZ6pQPl28JDimhJhI2LNqU349uADQVV0HJosddN/ARyyI\n" +
+        "LSIQO7BnNVKVG9Iujf33bvPNeg0qNz5qw+rKKq97Pqeum+L5oKU=\n" +
+        "-----END CERTIFICATE-----");
     }
 }
--- a/src/share/lib/security/java.security-linux	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/lib/security/java.security-linux	Thu Apr 18 14:38:37 2013 -0700
@@ -124,19 +124,30 @@
 # corresponding RuntimePermission ("accessClassInPackage."+package) has
 # been granted.
 package.access=sun.,\
-               com.sun.xml.internal.bind.,\
-               com.sun.xml.internal.org.jvnet.staxex.,\
-               com.sun.xml.internal.ws.,\
+               com.sun.xml.internal.,\
                com.sun.imageio.,\
                com.sun.istack.internal.,\
                com.sun.jmx.,\
                com.sun.proxy.,\
-               com.sun.org.apache.xerces.internal.utils.,\
+               com.sun.org.apache.bcel.internal.,\
+               com.sun.org.apache.regexp.internal.,\
+               com.sun.org.apache.xerces.internal.,\
+               com.sun.org.apache.xpath.internal.,\
+               com.sun.org.apache.xalan.internal.extensions.,\
+               com.sun.org.apache.xalan.internal.lib.,\
+               com.sun.org.apache.xalan.internal.res.,\
+               com.sun.org.apache.xalan.internal.templates.,\
                com.sun.org.apache.xalan.internal.utils.,\
-               com.sun.org.glassfish.external.,\
-               com.sun.org.glassfish.gmbal.,\
+               com.sun.org.apache.xalan.internal.xslt.,\
+               com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
+               com.sun.org.apache.xalan.internal.xsltc.compiler.,\
+               com.sun.org.apache.xalan.internal.xsltc.trax.,\
+               com.sun.org.apache.xalan.internal.xsltc.util.,\
+               com.sun.org.apache.xml.internal.res.,\
+               com.sun.org.apache.xml.internal.serializer.utils.,\
+               com.sun.org.apache.xml.internal.utils.,\
+               com.sun.org.glassfish.,\
                oracle.jrockit.jfr.
-
 #
 # List of comma-separated packages that start with or equal this string
 # will cause a security exception to be thrown when
@@ -148,19 +159,30 @@
 # checkPackageDefinition.
 #
 package.definition=sun.,\
-                   com.sun.xml.internal.bind.,\
-                   com.sun.xml.internal.org.jvnet.staxex.,\
-                   com.sun.xml.internal.ws.,\
+                   com.sun.xml.internal.,\
                    com.sun.imageio.,\
                    com.sun.istack.internal.,\
                    com.sun.jmx.,\
                    com.sun.proxy.,\
-                   com.sun.org.apache.xerces.internal.utils.,\
+                   com.sun.org.apache.bcel.internal.,\
+                   com.sun.org.apache.regexp.internal.,\
+                   com.sun.org.apache.xerces.internal.,\
+                   com.sun.org.apache.xpath.internal.,\
+                   com.sun.org.apache.xalan.internal.extensions.,\
+                   com.sun.org.apache.xalan.internal.lib.,\
+                   com.sun.org.apache.xalan.internal.res.,\
+                   com.sun.org.apache.xalan.internal.templates.,\
                    com.sun.org.apache.xalan.internal.utils.,\
-                   com.sun.org.glassfish.external.,\
-                   com.sun.org.glassfish.gmbal.,\
+                   com.sun.org.apache.xalan.internal.xslt.,\
+                   com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
+                   com.sun.org.apache.xalan.internal.xsltc.compiler.,\
+                   com.sun.org.apache.xalan.internal.xsltc.trax.,\
+                   com.sun.org.apache.xalan.internal.xsltc.util.,\
+                   com.sun.org.apache.xml.internal.res.,\
+                   com.sun.org.apache.xml.internal.serializer.utils.,\
+                   com.sun.org.apache.xml.internal.utils.,\
+                   com.sun.org.glassfish.,\
                    oracle.jrockit.jfr.
-
 #
 # Determines whether this properties file can be appended to
 # or overridden on the command line via -Djava.security.properties
@@ -373,7 +395,7 @@
 #   jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
 #
 #
-jdk.certpath.disabledAlgorithms=MD2
+jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
 
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
 # (SSL/TLS) processing
--- a/src/share/lib/security/java.security-macosx	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/lib/security/java.security-macosx	Thu Apr 18 14:38:37 2013 -0700
@@ -125,17 +125,29 @@
 # corresponding RuntimePermission ("accessClassInPackage."+package) has
 # been granted.
 package.access=sun.,\
-               com.sun.xml.internal.bind.,\
-               com.sun.xml.internal.org.jvnet.staxex.,\
-               com.sun.xml.internal.ws.,\
+               com.sun.xml.internal.,\
                com.sun.imageio.,\
                com.sun.istack.internal.,\
                com.sun.jmx.,\
                com.sun.proxy.,\
-               com.sun.org.apache.xerces.internal.utils.,\
+               com.sun.org.apache.bcel.internal.,\
+               com.sun.org.apache.regexp.internal.,\
+               com.sun.org.apache.xerces.internal.,\
+               com.sun.org.apache.xpath.internal.,\
+               com.sun.org.apache.xalan.internal.extensions.,\
+               com.sun.org.apache.xalan.internal.lib.,\
+               com.sun.org.apache.xalan.internal.res.,\
+               com.sun.org.apache.xalan.internal.templates.,\
                com.sun.org.apache.xalan.internal.utils.,\
-               com.sun.org.glassfish.external.,\
-               com.sun.org.glassfish.gmbal.,\
+               com.sun.org.apache.xalan.internal.xslt.,\
+               com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
+               com.sun.org.apache.xalan.internal.xsltc.compiler.,\
+               com.sun.org.apache.xalan.internal.xsltc.trax.,\
+               com.sun.org.apache.xalan.internal.xsltc.util.,\
+               com.sun.org.apache.xml.internal.res.,\
+               com.sun.org.apache.xml.internal.serializer.utils.,\
+               com.sun.org.apache.xml.internal.utils.,\
+               com.sun.org.glassfish.,\
                oracle.jrockit.jfr.,\
                apple.
 
@@ -150,17 +162,29 @@
 # checkPackageDefinition.
 #
 package.definition=sun.,\
-                   com.sun.xml.internal.bind.,\
-                   com.sun.xml.internal.org.jvnet.staxex.,\
-                   com.sun.xml.internal.ws.,\
+                   com.sun.xml.internal.,\
                    com.sun.imageio.,\
                    com.sun.istack.internal.,\
                    com.sun.jmx.,\
                    com.sun.proxy.,\
-                   com.sun.org.apache.xerces.internal.utils.,\
+                   com.sun.org.apache.bcel.internal.,\
+                   com.sun.org.apache.regexp.internal.,\
+                   com.sun.org.apache.xerces.internal.,\
+                   com.sun.org.apache.xpath.internal.,\
+                   com.sun.org.apache.xalan.internal.extensions.,\
+                   com.sun.org.apache.xalan.internal.lib.,\
+                   com.sun.org.apache.xalan.internal.res.,\
+                   com.sun.org.apache.xalan.internal.templates.,\
                    com.sun.org.apache.xalan.internal.utils.,\
-                   com.sun.org.glassfish.external.,\
-                   com.sun.org.glassfish.gmbal.,\
+                   com.sun.org.apache.xalan.internal.xslt.,\
+                   com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
+                   com.sun.org.apache.xalan.internal.xsltc.compiler.,\
+                   com.sun.org.apache.xalan.internal.xsltc.trax.,\
+                   com.sun.org.apache.xalan.internal.xsltc.util.,\
+                   com.sun.org.apache.xml.internal.res.,\
+                   com.sun.org.apache.xml.internal.serializer.utils.,\
+                   com.sun.org.apache.xml.internal.utils.,\
+                   com.sun.org.glassfish.,\
                    oracle.jrockit.jfr.,\
                    apple.
 
@@ -376,7 +400,7 @@
 #   jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
 #
 #
-jdk.certpath.disabledAlgorithms=MD2
+jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
 
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
 # (SSL/TLS) processing
--- a/src/share/lib/security/java.security-solaris	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/lib/security/java.security-solaris	Thu Apr 18 14:38:37 2013 -0700
@@ -126,17 +126,29 @@
 # corresponding RuntimePermission ("accessClassInPackage."+package) has
 # been granted.
 package.access=sun.,\
-               com.sun.xml.internal.bind.,\
-               com.sun.xml.internal.org.jvnet.staxex.,\
-               com.sun.xml.internal.ws.,\
+               com.sun.xml.internal.,\
                com.sun.imageio.,\
                com.sun.istack.internal.,\
                com.sun.jmx.,\
                com.sun.proxy.,\
-               com.sun.org.apache.xerces.internal.utils.,\
+               com.sun.org.apache.bcel.internal.,\
+               com.sun.org.apache.regexp.internal.,\
+               com.sun.org.apache.xerces.internal.,\
+               com.sun.org.apache.xpath.internal.,\
+               com.sun.org.apache.xalan.internal.extensions.,\
+               com.sun.org.apache.xalan.internal.lib.,\
+               com.sun.org.apache.xalan.internal.res.,\
+               com.sun.org.apache.xalan.internal.templates.,\
                com.sun.org.apache.xalan.internal.utils.,\
-               com.sun.org.glassfish.external.,\
-               com.sun.org.glassfish.gmbal.,\
+               com.sun.org.apache.xalan.internal.xslt.,\
+               com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
+               com.sun.org.apache.xalan.internal.xsltc.compiler.,\
+               com.sun.org.apache.xalan.internal.xsltc.trax.,\
+               com.sun.org.apache.xalan.internal.xsltc.util.,\
+               com.sun.org.apache.xml.internal.res.,\
+               com.sun.org.apache.xml.internal.serializer.utils.,\
+               com.sun.org.apache.xml.internal.utils.,\
+               com.sun.org.glassfish.,\
                oracle.jrockit.jfr.
 
 #
@@ -150,17 +162,29 @@
 # checkPackageDefinition.
 #
 package.definition=sun.,\
-                   com.sun.xml.internal.bind.,\
-                   com.sun.xml.internal.org.jvnet.staxex.,\
-                   com.sun.xml.internal.ws.,\
+                   com.sun.xml.internal.,\
                    com.sun.imageio.,\
                    com.sun.istack.internal.,\
                    com.sun.jmx.,\
                    com.sun.proxy.,\
-                   com.sun.org.apache.xerces.internal.utils.,\
+                   com.sun.org.apache.bcel.internal.,\
+                   com.sun.org.apache.regexp.internal.,\
+                   com.sun.org.apache.xerces.internal.,\
+                   com.sun.org.apache.xpath.internal.,\
+                   com.sun.org.apache.xalan.internal.extensions.,\
+                   com.sun.org.apache.xalan.internal.lib.,\
+                   com.sun.org.apache.xalan.internal.res.,\
+                   com.sun.org.apache.xalan.internal.templates.,\
                    com.sun.org.apache.xalan.internal.utils.,\
-                   com.sun.org.glassfish.external.,\
-                   com.sun.org.glassfish.gmbal.,\
+                   com.sun.org.apache.xalan.internal.xslt.,\
+                   com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
+                   com.sun.org.apache.xalan.internal.xsltc.compiler.,\
+                   com.sun.org.apache.xalan.internal.xsltc.trax.,\
+                   com.sun.org.apache.xalan.internal.xsltc.util.,\
+                   com.sun.org.apache.xml.internal.res.,\
+                   com.sun.org.apache.xml.internal.serializer.utils.,\
+                   com.sun.org.apache.xml.internal.utils.,\
+                   com.sun.org.glassfish.,\
                    oracle.jrockit.jfr.
 
 #
@@ -375,7 +399,7 @@
 #   jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
 #
 #
-jdk.certpath.disabledAlgorithms=MD2
+jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
 
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
 # (SSL/TLS) processing
--- a/src/share/lib/security/java.security-windows	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/lib/security/java.security-windows	Thu Apr 18 14:38:37 2013 -0700
@@ -125,17 +125,30 @@
 # corresponding RuntimePermission ("accessClassInPackage."+package) has
 # been granted.
 package.access=sun.,\
-               com.sun.xml.internal.bind.,\
-               com.sun.xml.internal.org.jvnet.staxex.,\
-               com.sun.xml.internal.ws.,\
+               com.sun.xml.internal.,\
                com.sun.imageio.,\
                com.sun.istack.internal.,\
                com.sun.jmx.,\
                com.sun.proxy.,\
-               com.sun.org.apache.xerces.internal.utils.,\
+               com.sun.org.apache.bcel.internal.,\
+               com.sun.org.apache.regexp.internal.,\
+               com.sun.org.apache.xerces.internal.,\
+               com.sun.org.apache.xpath.internal.,\
+               com.sun.org.apache.xalan.internal.extensions.,\
+               com.sun.org.apache.xalan.internal.lib.,\
+               com.sun.org.apache.xalan.internal.res.,\
+               com.sun.org.apache.xalan.internal.templates.,\
                com.sun.org.apache.xalan.internal.utils.,\
-               com.sun.org.glassfish.external.,\
-               com.sun.org.glassfish.gmbal.,\
+               com.sun.org.apache.xalan.internal.xslt.,\
+               com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
+               com.sun.org.apache.xalan.internal.xsltc.compiler.,\
+               com.sun.org.apache.xalan.internal.xsltc.trax.,\
+               com.sun.org.apache.xalan.internal.xsltc.util.,\
+               com.sun.org.apache.xml.internal.res.,\
+               com.sun.org.apache.xml.internal.serializer.utils.,\
+               com.sun.org.apache.xml.internal.utils.,\
+               com.sun.org.glassfish.,\
+               com.sun.java.accessibility.,\
                oracle.jrockit.jfr.
 
 #
@@ -149,17 +162,30 @@
 # checkPackageDefinition.
 #
 package.definition=sun.,\
-                   com.sun.xml.internal.bind.,\
-                   com.sun.xml.internal.org.jvnet.staxex.,\
-                   com.sun.xml.internal.ws.,\
+                   com.sun.xml.internal.,\
                    com.sun.imageio.,\
                    com.sun.istack.internal.,\
                    com.sun.jmx.,\
                    com.sun.proxy.,\
-                   com.sun.org.apache.xerces.internal.utils.,\
+                   com.sun.org.apache.bcel.internal.,\
+                   com.sun.org.apache.regexp.internal.,\
+                   com.sun.org.apache.xerces.internal.,\
+                   com.sun.org.apache.xpath.internal.,\
+                   com.sun.org.apache.xalan.internal.extensions.,\
+                   com.sun.org.apache.xalan.internal.lib.,\
+                   com.sun.org.apache.xalan.internal.res.,\
+                   com.sun.org.apache.xalan.internal.templates.,\
                    com.sun.org.apache.xalan.internal.utils.,\
-                   com.sun.org.glassfish.external.,\
-                   com.sun.org.glassfish.gmbal.,\
+                   com.sun.org.apache.xalan.internal.xslt.,\
+                   com.sun.org.apache.xalan.internal.xsltc.cmdline.,\
+                   com.sun.org.apache.xalan.internal.xsltc.compiler.,\
+                   com.sun.org.apache.xalan.internal.xsltc.trax.,\
+                   com.sun.org.apache.xalan.internal.xsltc.util.,\
+                   com.sun.org.apache.xml.internal.res.,\
+                   com.sun.org.apache.xml.internal.serializer.utils.,\
+                   com.sun.org.apache.xml.internal.utils.,\
+                   com.sun.org.glassfish.,\
+                   com.sun.java.accessibility.,\
                    oracle.jrockit.jfr.
 
 #
@@ -374,7 +400,7 @@
 #   jdk.certpath.disabledAlgorithms=MD2, DSA, RSA keySize < 2048
 #
 #
-jdk.certpath.disabledAlgorithms=MD2
+jdk.certpath.disabledAlgorithms=MD2, RSA keySize < 1024
 
 # Algorithm restrictions for Secure Socket Layer/Transport Layer Security
 # (SSL/TLS) processing
--- a/src/share/native/java/lang/System.c	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/java/lang/System.c	Thu Apr 18 14:38:37 2013 -0700
@@ -382,11 +382,19 @@
         sprops->display_variant, sprops->format_variant, putID, getPropID);
     GETPROP(props, "file.encoding", jVMVal);
     if (jVMVal == NULL) {
+#ifdef MACOSX
+        /*
+         * Since sun_jnu_encoding is now hard-coded to UTF-8 on Mac, we don't
+         * want to use it to overwrite file.encoding
+         */
+        PUTPROP(props, "file.encoding", sprops->encoding);
+#else
         if (fmtdefault) {
             PUTPROP(props, "file.encoding", sprops->encoding);
         } else {
             PUTPROP(props, "file.encoding", sprops->sun_jnu_encoding);
         }
+#endif
     } else {
         (*env)->DeleteLocalRef(env, jVMVal);
     }
--- a/src/share/native/java/net/InetAddress.c	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/java/net/InetAddress.c	Thu Apr 18 14:38:37 2013 -0700
@@ -33,8 +33,11 @@
  */
 
 jclass ia_class;
-jfieldID ia_addressID;
-jfieldID ia_familyID;
+jclass iac_class;
+jfieldID ia_holderID;
+jfieldID iac_addressID;
+jfieldID iac_familyID;
+jfieldID iac_hostNameID;
 jfieldID ia_preferIPv6AddressID;
 
 /*
@@ -48,10 +51,18 @@
     CHECK_NULL(c);
     ia_class = (*env)->NewGlobalRef(env, c);
     CHECK_NULL(ia_class);
-    ia_addressID = (*env)->GetFieldID(env, ia_class, "address", "I");
-    CHECK_NULL(ia_addressID);
-    ia_familyID = (*env)->GetFieldID(env, ia_class, "family", "I");
-    CHECK_NULL(ia_familyID);
+    c = (*env)->FindClass(env,"java/net/InetAddress$InetAddressHolder");
+    CHECK_NULL(c);
+    iac_class = (*env)->NewGlobalRef(env, c);
+    ia_holderID = (*env)->GetFieldID(env, ia_class, "holder", "Ljava/net/InetAddress$InetAddressHolder;");
+    CHECK_NULL(ia_holderID);
     ia_preferIPv6AddressID = (*env)->GetStaticFieldID(env, ia_class, "preferIPv6Address", "Z");
     CHECK_NULL(ia_preferIPv6AddressID);
+
+    iac_addressID = (*env)->GetFieldID(env, iac_class, "address", "I");
+    CHECK_NULL(iac_addressID);
+    iac_familyID = (*env)->GetFieldID(env, iac_class, "family", "I");
+    CHECK_NULL(iac_familyID);
+    iac_hostNameID = (*env)->GetFieldID(env, iac_class, "hostName", "Ljava/lang/String;");
+    CHECK_NULL(iac_hostNameID);
 }
--- a/src/share/native/java/net/net_util.c	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/java/net/net_util.c	Thu Apr 18 14:38:37 2013 -0700
@@ -84,6 +84,58 @@
     }
 }
 
+/* The address, and family fields used to be in InetAddress
+ * but are now in an implementation object. So, there is an extra
+ * level of indirection to access them now.
+ */
+
+extern jclass iac_class;
+extern jfieldID ia_holderID;
+extern jfieldID iac_addressID;
+extern jfieldID iac_familyID;
+
+void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    (*env)->SetIntField(env, holder, iac_addressID, address);
+}
+
+void setInetAddress_family(JNIEnv *env, jobject iaObj, int family) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    (*env)->SetIntField(env, holder, iac_familyID, family);
+}
+
+void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject host) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    (*env)->SetObjectField(env, holder, iac_hostNameID, host);
+}
+
+int getInetAddress_addr(JNIEnv *env, jobject iaObj) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    return (*env)->GetIntField(env, holder, iac_addressID);
+}
+
+int getInetAddress_family(JNIEnv *env, jobject iaObj) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    return (*env)->GetIntField(env, holder, iac_familyID);
+}
+
+jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj) {
+    jobject holder;
+    init(env);
+    holder = (*env)->GetObjectField(env, iaObj, ia_holderID);
+    return (*env)->GetObjectField(env, holder, iac_hostNameID);
+}
+
 JNIEXPORT jobject JNICALL
 NET_SockaddrToInetAddress(JNIEnv *env, struct sockaddr *him, int *port) {
     jobject iaObj;
@@ -110,8 +162,8 @@
             iaObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
             CHECK_NULL_RETURN(iaObj, NULL);
             address = NET_IPv4MappedToIPv4(caddr);
-            (*env)->SetIntField(env, iaObj, ia_addressID, address);
-            (*env)->SetIntField(env, iaObj, ia_familyID, IPv4);
+            setInetAddress_addr(env, iaObj, address);
+            setInetAddress_family(env, iaObj, IPv4);
         } else {
             static jclass inet6Cls = 0;
             jint scope;
@@ -131,7 +183,7 @@
 
             (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress);
 
-            (*env)->SetIntField(env, iaObj, ia_familyID, IPv6);
+            setInetAddress_family(env, iaObj, IPv6);
             scope = getScopeID(him);
             (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
             if (scope > 0)
@@ -153,9 +205,8 @@
             }
             iaObj = (*env)->NewObject(env, inet4Cls, ia4_ctrID);
             CHECK_NULL_RETURN(iaObj, NULL);
-            (*env)->SetIntField(env, iaObj, ia_familyID, IPv4);
-            (*env)->SetIntField(env, iaObj, ia_addressID,
-                                ntohl(him4->sin_addr.s_addr));
+            setInetAddress_family(env, iaObj, IPv4);
+            setInetAddress_addr(env, iaObj, ntohl(him4->sin_addr.s_addr));
             *port = ntohs(him4->sin_port);
         }
     return iaObj;
@@ -167,8 +218,7 @@
     jint family = AF_INET;
 
 #ifdef AF_INET6
-    family = (*env)->GetIntField(env, iaObj, ia_familyID) == IPv4?
-        AF_INET : AF_INET6;
+    family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
     if (him->sa_family == AF_INET6) {
 #ifdef WIN32
         struct SOCKADDR_IN6 *him6 = (struct SOCKADDR_IN6 *)him;
@@ -183,7 +233,7 @@
                 return JNI_FALSE;
             }
             addrNew = NET_IPv4MappedToIPv4(caddrNew);
-            addrCur = (*env)->GetIntField(env, iaObj, ia_addressID);
+            addrCur = getInetAddress_addr(env, iaObj);
             if (addrNew == addrCur) {
                 return JNI_TRUE;
             } else {
@@ -215,7 +265,7 @@
                 return JNI_FALSE;
             }
             addrNew = ntohl(him4->sin_addr.s_addr);
-            addrCur = (*env)->GetIntField(env, iaObj, ia_addressID);
+            addrCur = getInetAddress_addr(env, iaObj);
             if (addrNew == addrCur) {
                 return JNI_TRUE;
             } else {
--- a/src/share/native/java/net/net_util.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/java/net/net_util.h	Thu Apr 18 14:38:37 2013 -0700
@@ -53,10 +53,18 @@
  * i.e. psi_timeoutID is PlainSocketImpl's timeout field's ID.
  */
 extern jclass ia_class;
-extern jfieldID ia_addressID;
-extern jfieldID ia_familyID;
+extern jfieldID iac_addressID;
+extern jfieldID iac_familyID;
+extern jfieldID iac_hostNameID;
 extern jfieldID ia_preferIPv6AddressID;
 
+extern void setInetAddress_addr(JNIEnv *env, jobject iaObj, int address);
+extern void setInetAddress_family(JNIEnv *env, jobject iaObj, int family);
+extern void setInetAddress_hostName(JNIEnv *env, jobject iaObj, jobject h);
+extern int getInetAddress_addr(JNIEnv *env, jobject iaObj);
+extern int getInetAddress_family(JNIEnv *env, jobject iaObj);
+extern jobject getInetAddress_hostName(JNIEnv *env, jobject iaObj);
+
 extern jclass ia4_class;
 extern jmethodID ia4_ctrID;
 
--- a/src/share/native/sun/awt/image/awt_ImageRep.c	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/awt/image/awt_ImageRep.c	Thu Apr 18 14:38:37 2013 -0700
@@ -45,6 +45,53 @@
 #  define TRUE 1
 #endif
 
+#define CHECK_STRIDE(yy, hh, ss)                            \
+    if ((ss) != 0) {                                        \
+        int limit = 0x7fffffff / ((ss) > 0 ? (ss) : -(ss)); \
+        if (limit < (yy) || limit < ((yy) + (hh) - 1)) {    \
+            /* integer oveflow */                           \
+            return JNI_FALSE;                               \
+        }                                                   \
+    }                                                       \
+
+#define CHECK_SRC()                                      \
+    do {                                                 \
+        int pixeloffset;                                 \
+        if (off < 0 || off >= srcDataLength) {           \
+            return JNI_FALSE;                            \
+        }                                                \
+        CHECK_STRIDE(0, h, scansize);                    \
+                                                         \
+        /* check scansize */                             \
+        pixeloffset = scansize * (h - 1);                \
+        if ((w - 1) > (0x7fffffff - pixeloffset)) {      \
+            return JNI_FALSE;                            \
+        }                                                \
+        pixeloffset += (w - 1);                          \
+                                                         \
+        if (off > (0x7fffffff - pixeloffset)) {          \
+            return JNI_FALSE;                            \
+        }                                                \
+    } while (0)                                          \
+
+#define CHECK_DST(xx, yy)                                \
+    do {                                                 \
+        int soffset = (yy) * sStride;                    \
+        int poffset = (xx) * pixelStride;                \
+        if (poffset > (0x7fffffff - soffset)) {          \
+            return JNI_FALSE;                            \
+        }                                                \
+        poffset += soffset;                              \
+        if (dstDataOff > (0x7fffffff - poffset)) {       \
+            return JNI_FALSE;                            \
+        }                                                \
+        poffset += dstDataOff;                           \
+                                                         \
+        if (poffset < 0 || poffset >= dstDataLength) {   \
+            return JNI_FALSE;                            \
+        }                                                \
+    } while (0)                                          \
+
 static jfieldID s_JnumSrcLUTID;
 static jfieldID s_JsrcLUTtransIndexID;
 
@@ -58,7 +105,7 @@
 /*
  * This routine is used to draw ICM pixels into a default color model
  */
-JNIEXPORT void JNICALL
+JNIEXPORT jboolean JNICALL
 Java_sun_awt_image_ImageRepresentation_setICMpixels(JNIEnv *env, jclass cls,
                                                     jint x, jint y, jint w,
                                                     jint h, jintArray jlut,
@@ -67,7 +114,10 @@
                                                     jobject jict)
 {
     unsigned char *srcData = NULL;
+    jint srcDataLength;
     int *dstData;
+    jint dstDataLength;
+    jint dstDataOff;
     int *dstP, *dstyP;
     unsigned char *srcyP, *srcP;
     int *srcLUT = NULL;
@@ -80,12 +130,20 @@
 
     if (JNU_IsNull(env, jlut)) {
         JNU_ThrowNullPointerException(env, "NullPointerException");
-        return;
+        return JNI_FALSE;
     }
 
     if (JNU_IsNull(env, jpix)) {
         JNU_ThrowNullPointerException(env, "NullPointerException");
-        return;
+        return JNI_FALSE;
+    }
+
+    if (x < 0 || w < 1 || (0x7fffffff - x) < w) {
+        return JNI_FALSE;
+    }
+
+    if (y < 0 || h < 1 || (0x7fffffff - y) < h) {
+        return JNI_FALSE;
     }
 
     sStride = (*env)->GetIntField(env, jict, g_ICRscanstrID);
@@ -93,10 +151,47 @@
     joffs = (*env)->GetObjectField(env, jict, g_ICRdataOffsetsID);
     jdata = (*env)->GetObjectField(env, jict, g_ICRdataID);
 
+    if (JNU_IsNull(env, jdata)) {
+        /* no destination buffer */
+        return JNI_FALSE;
+    }
+
+    if (JNU_IsNull(env, joffs) || (*env)->GetArrayLength(env, joffs) < 1) {
+        /* invalid data offstes in raster */
+        return JNI_FALSE;
+    }
+
+    srcDataLength = (*env)->GetArrayLength(env, jpix);
+    dstDataLength = (*env)->GetArrayLength(env, jdata);
+
+    cOffs = (int *) (*env)->GetPrimitiveArrayCritical(env, joffs, NULL);
+    if (cOffs == NULL) {
+        JNU_ThrowNullPointerException(env, "Null channel offset array");
+        return JNI_FALSE;
+    }
+
+    dstDataOff = cOffs[0];
+
+    /* the offset array is not needed anymore and can be released */
+    (*env)->ReleasePrimitiveArrayCritical(env, joffs, cOffs, JNI_ABORT);
+    joffs = NULL;
+    cOffs = NULL;
+
+    /* do basic validation: make sure that offsets for
+    * first pixel and for last pixel are safe to calculate and use */
+    CHECK_STRIDE(y, h, sStride);
+    CHECK_STRIDE(x, w, pixelStride);
+
+    CHECK_DST(x, y);
+    CHECK_DST(x + w -1, y + h - 1);
+
+    /* check source array */
+    CHECK_SRC();
+
     srcLUT = (int *) (*env)->GetPrimitiveArrayCritical(env, jlut, NULL);
     if (srcLUT == NULL) {
         JNU_ThrowNullPointerException(env, "Null IndexColorModel LUT");
-        return;
+        return JNI_FALSE;
     }
 
     srcData = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, jpix,
@@ -104,27 +199,18 @@
     if (srcData == NULL) {
         (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT);
         JNU_ThrowNullPointerException(env, "Null data array");
-        return;
-    }
-
-    cOffs = (int *) (*env)->GetPrimitiveArrayCritical(env, joffs, NULL);
-    if (cOffs == NULL) {
-        (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT);
-        (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT);
-        JNU_ThrowNullPointerException(env, "Null channel offset array");
-        return;
+        return JNI_FALSE;
     }
 
     dstData = (int *) (*env)->GetPrimitiveArrayCritical(env, jdata, NULL);
     if (dstData == NULL) {
         (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT, JNI_ABORT);
         (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT);
-        (*env)->ReleasePrimitiveArrayCritical(env, joffs, cOffs, JNI_ABORT);
         JNU_ThrowNullPointerException(env, "Null tile data array");
-        return;
+        return JNI_FALSE;
     }
 
-    dstyP = dstData + cOffs[0] + y*sStride + x*pixelStride;
+    dstyP = dstData + dstDataOff + y*sStride + x*pixelStride;
     srcyP = srcData + off;
     for (yIdx = 0; yIdx < h; yIdx++, srcyP += scansize, dstyP+=sStride) {
         srcP = srcyP;
@@ -137,12 +223,12 @@
     /* Release the locked arrays */
     (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT,  JNI_ABORT);
     (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT);
-    (*env)->ReleasePrimitiveArrayCritical(env, joffs, cOffs, JNI_ABORT);
     (*env)->ReleasePrimitiveArrayCritical(env, jdata, dstData, JNI_ABORT);
 
+    return JNI_TRUE;
 }
 
-JNIEXPORT jint JNICALL
+JNIEXPORT jboolean JNICALL
 Java_sun_awt_image_ImageRepresentation_setDiffICM(JNIEnv *env, jclass cls,
                                                   jint x, jint y, jint w,
                                                   jint h, jintArray jlut,
@@ -150,7 +236,7 @@
                                                   jobject jicm,
                                                   jbyteArray jpix, jint off,
                                                   jint scansize,
-                                                  jobject jbct, jint chanOff)
+                                                  jobject jbct, jint dstDataOff)
 {
     unsigned int *srcLUT = NULL;
     unsigned int *newLUT = NULL;
@@ -159,6 +245,8 @@
     int mapSize;
     jobject jdata = NULL;
     jobject jnewlut = NULL;
+    jint srcDataLength;
+    jint dstDataLength;
     unsigned char *srcData;
     unsigned char *dstData;
     unsigned char *dataP;
@@ -174,14 +262,23 @@
 
     if (JNU_IsNull(env, jlut)) {
         JNU_ThrowNullPointerException(env, "NullPointerException");
-        return 0;
+        return JNI_FALSE;
     }
 
     if (JNU_IsNull(env, jpix)) {
         JNU_ThrowNullPointerException(env, "NullPointerException");
-        return 0;
+        return JNI_FALSE;
     }
 
+    if (x < 0 || w < 1 || (0x7fffffff - x) < w) {
+        return JNI_FALSE;
+    }
+
+    if (y < 0 || h < 1 || (0x7fffffff - y) < h) {
+        return JNI_FALSE;
+    }
+
+
     sStride = (*env)->GetIntField(env, jbct, g_BCRscanstrID);
     pixelStride =(*env)->GetIntField(env, jbct, g_BCRpixstrID);
     jdata = (*env)->GetObjectField(env, jbct, g_BCRdataID);
@@ -193,13 +290,31 @@
            of byte data type, so we have to convert the image data
            to default representation.
         */
-        return 0;
+        return JNI_FALSE;
     }
+
+    if (JNU_IsNull(env, jdata)) {
+        /* no destination buffer */
+        return JNI_FALSE;
+    }
+
+    srcDataLength = (*env)->GetArrayLength(env, jpix);
+    dstDataLength = (*env)->GetArrayLength(env, jdata);
+
+    CHECK_STRIDE(y, h, sStride);
+    CHECK_STRIDE(x, w, pixelStride);
+
+    CHECK_DST(x, y);
+    CHECK_DST(x + w -1, y + h - 1);
+
+    /* check source array */
+    CHECK_SRC();
+
     srcLUT = (unsigned int *) (*env)->GetPrimitiveArrayCritical(env, jlut,
                                                                 NULL);
     if (srcLUT == NULL) {
         /* out of memory error already thrown */
-        return 0;
+        return JNI_FALSE;
     }
 
     newLUT = (unsigned int *) (*env)->GetPrimitiveArrayCritical(env, jnewlut,
@@ -208,7 +323,7 @@
         (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT,
                                               JNI_ABORT);
         /* out of memory error already thrown */
-        return 0;
+        return JNI_FALSE;
     }
 
     newNumLut = numLut;
@@ -219,7 +334,7 @@
         (*env)->ReleasePrimitiveArrayCritical(env, jlut, srcLUT,
                                               JNI_ABORT);
         (*env)->ReleasePrimitiveArrayCritical(env, jnewlut, newLUT, JNI_ABORT);
-        return 0;
+        return JNI_FALSE;
     }
 
     /* Don't need these any more */
@@ -239,7 +354,7 @@
                                                                   NULL);
     if (srcData == NULL) {
         /* out of memory error already thrown */
-        return 0;
+        return JNI_FALSE;
     }
 
     dstData = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, jdata,
@@ -247,10 +362,10 @@
     if (dstData == NULL) {
         (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT);
         /* out of memory error already thrown */
-        return 0;
+        return JNI_FALSE;
     }
 
-    ydataP = dstData + chanOff + y*sStride + x*pixelStride;
+    ydataP = dstData + dstDataOff + y*sStride + x*pixelStride;
     ypixP  = srcData + off;
 
     for (i=0; i < h; i++) {
@@ -268,7 +383,7 @@
     (*env)->ReleasePrimitiveArrayCritical(env, jpix, srcData, JNI_ABORT);
     (*env)->ReleasePrimitiveArrayCritical(env, jdata, dstData, JNI_ABORT);
 
-    return 1;
+    return JNI_TRUE;
 }
 
 static int compareLUTs(unsigned int *lut1, int numLut1, int transIdx,
--- a/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/awt/image/jpeg/imageioJPEG.c	Thu Apr 18 14:38:37 2013 -0700
@@ -57,8 +57,8 @@
 #define MAX(a,b)        ((a) > (b) ? (a) : (b))
 
 /* Cached Java method ids */
-static jmethodID ImageInputStream_readID;
-static jmethodID ImageInputStream_skipBytesID;
+static jmethodID JPEGImageReader_readInputDataID;
+static jmethodID JPEGImageReader_skipInputBytesID;
 static jmethodID JPEGImageReader_warningOccurredID;
 static jmethodID JPEGImageReader_warningWithMessageID;
 static jmethodID JPEGImageReader_setImageDataID;
@@ -66,7 +66,7 @@
 static jmethodID JPEGImageReader_pushBackID;
 static jmethodID JPEGImageReader_passStartedID;
 static jmethodID JPEGImageReader_passCompleteID;
-static jmethodID ImageOutputStream_writeID;
+static jmethodID JPEGImageWriter_writeOutputDataID;
 static jmethodID JPEGImageWriter_warningOccurredID;
 static jmethodID JPEGImageWriter_warningWithMessageID;
 static jmethodID JPEGImageWriter_writeMetadataID;
@@ -923,7 +923,7 @@
     RELEASE_ARRAYS(env, data, src->next_input_byte);
     ret = (*env)->CallIntMethod(env,
                                 sb->stream,
-                                ImageInputStream_readID,
+                                JPEGImageReader_readInputDataID,
                                 sb->hstreamBuffer, 0,
                                 sb->bufferLength);
     if ((*env)->ExceptionOccurred(env)
@@ -1013,7 +1013,7 @@
     }
 
     ret = (*env)->CallIntMethod(env, sb->stream,
-                                ImageInputStream_readID,
+                                JPEGImageReader_readInputDataID,
                                 sb->hstreamBuffer,
                                 offset, buflen);
     if ((*env)->ExceptionOccurred(env)
@@ -1107,7 +1107,7 @@
     RELEASE_ARRAYS(env, data, src->next_input_byte);
     ret = (*env)->CallLongMethod(env,
                                  sb->stream,
-                                 ImageInputStream_skipBytesID,
+                                 JPEGImageReader_skipInputBytesID,
                                  (jlong) num_bytes);
     if ((*env)->ExceptionOccurred(env)
         || !GET_ARRAYS(env, data, &(src->next_input_byte))) {
@@ -1382,13 +1382,13 @@
      jclass qTableClass,
      jclass huffClass) {
 
-    ImageInputStream_readID = (*env)->GetMethodID(env,
-                                                  ImageInputStreamClass,
-                                                  "read",
+    JPEGImageReader_readInputDataID = (*env)->GetMethodID(env,
+                                                  cls,
+                                                  "readInputData",
                                                   "([BII)I");
-    ImageInputStream_skipBytesID = (*env)->GetMethodID(env,
-                                                       ImageInputStreamClass,
-                                                       "skipBytes",
+    JPEGImageReader_skipInputBytesID = (*env)->GetMethodID(env,
+                                                       cls,
+                                                       "skipInputBytes",
                                                        "(J)J");
     JPEGImageReader_warningOccurredID = (*env)->GetMethodID(env,
                                                             cls,
@@ -1531,8 +1531,7 @@
 Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_setSource
     (JNIEnv *env,
      jobject this,
-     jlong ptr,
-     jobject source) {
+     jlong ptr) {
 
     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
     j_common_ptr cinfo;
@@ -1546,7 +1545,7 @@
 
     cinfo = data->jpegObj;
 
-    imageio_set_stream(env, cinfo, data, source);
+    imageio_set_stream(env, cinfo, data, this);
 
     imageio_init_source((j_decompress_ptr) cinfo);
 }
@@ -2291,7 +2290,7 @@
 
     (*env)->CallVoidMethod(env,
                            sb->stream,
-                           ImageOutputStream_writeID,
+                           JPEGImageWriter_writeOutputDataID,
                            sb->hstreamBuffer,
                            0,
                            sb->bufferLength);
@@ -2328,7 +2327,7 @@
 
         (*env)->CallVoidMethod(env,
                                sb->stream,
-                               ImageOutputStream_writeID,
+                               JPEGImageWriter_writeOutputDataID,
                                sb->hstreamBuffer,
                                0,
                                datacount);
@@ -2366,13 +2365,12 @@
 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_initWriterIDs
     (JNIEnv *env,
      jclass cls,
-     jclass IOSClass,
      jclass qTableClass,
      jclass huffClass) {
 
-    ImageOutputStream_writeID = (*env)->GetMethodID(env,
-                                                    IOSClass,
-                                                    "write",
+    JPEGImageWriter_writeOutputDataID = (*env)->GetMethodID(env,
+                                                    cls,
+                                                    "writeOutputData",
                                                     "([BII)V");
 
     JPEGImageWriter_warningOccurredID = (*env)->GetMethodID(env,
@@ -2496,8 +2494,7 @@
 Java_com_sun_imageio_plugins_jpeg_JPEGImageWriter_setDest
     (JNIEnv *env,
      jobject this,
-     jlong ptr,
-     jobject destination) {
+     jlong ptr) {
 
     imageIODataPtr data = (imageIODataPtr)jlong_to_ptr(ptr);
     j_compress_ptr cinfo;
@@ -2511,7 +2508,7 @@
 
     cinfo = (j_compress_ptr) data->jpegObj;
 
-    imageio_set_stream(env, data->jpegObj, data, destination);
+    imageio_set_stream(env, data->jpegObj, data, this);
 
 
     // Don't call the init method, as that depends on pinned arrays
--- a/src/share/native/sun/font/FontInstanceAdapter.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/FontInstanceAdapter.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -66,8 +66,21 @@
     yScalePixelsToUnits = upem / yppem;
 };
 
+
 const void *FontInstanceAdapter::getFontTable(LETag tableTag) const
 {
+  size_t ignored = 0;
+  return getFontTable(tableTag, ignored);
+}
+
+static const LETag cacheMap[LAYOUTCACHE_ENTRIES] = {
+  GPOS_TAG, GDEF_TAG, GSUB_TAG, MORT_TAG, MORX_TAG, KERN_TAG
+};
+
+const void *FontInstanceAdapter::getFontTable(LETag tableTag, size_t &length) const
+{
+  length = 0;
+
   if (!layoutTables) { // t1 font
     return 0;
   }
@@ -75,14 +88,19 @@
   // cache in font's pscaler object
   // font disposer will handle for us
 
-  switch(tableTag) {
-  case GSUB_TAG: if (layoutTables->gsub_len != -1) return (void*)layoutTables->gsub; break;
-  case GPOS_TAG: if (layoutTables->gpos_len != -1) return (void*)layoutTables->gpos; break;
-  case GDEF_TAG: if (layoutTables->gdef_len != -1) return (void*)layoutTables->gdef; break;
-  case MORT_TAG: if (layoutTables->mort_len != -1) return (void*)layoutTables->mort; break;
-  case KERN_TAG: if (layoutTables->kern_len != -1) return (void*)layoutTables->kern; break;
-  default:
-   //fprintf(stderr, "unexpected table request from font instance adapter: %x\n", tableTag);
+  int cacheIdx;
+  for (cacheIdx=0;cacheIdx<LAYOUTCACHE_ENTRIES;cacheIdx++) {
+    if (tableTag==cacheMap[cacheIdx]) break;
+  }
+
+  if (cacheIdx<LAYOUTCACHE_ENTRIES) { // if found
+    if (layoutTables->entries[cacheIdx].len != -1) {
+      length = layoutTables->entries[cacheIdx].len;
+      return layoutTables->entries[cacheIdx].ptr;
+    }
+  } else {
+    //fprintf(stderr, "unexpected table request from font instance adapter: %x\n", tableTag);
+    // (don't load any other tables)
     return 0;
   }
 
@@ -96,16 +114,13 @@
     env->GetByteArrayRegion(tableBytes, 0, len, result);
   }
 
-  switch(tableTag) {
-  case GSUB_TAG: layoutTables->gsub = (void*)result; layoutTables->gsub_len = len; break;
-  case GPOS_TAG: layoutTables->gpos = (void*)result; layoutTables->gpos_len = len; break;
-  case GDEF_TAG: layoutTables->gdef = (void*)result; layoutTables->gdef_len = len; break;
-  case MORT_TAG: layoutTables->mort = (void*)result; layoutTables->mort_len = len; break;
-  case KERN_TAG: layoutTables->kern = (void*)result; layoutTables->kern_len = len; break;
-  default: break;
+  if (cacheIdx<LAYOUTCACHE_ENTRIES) { // if cacheable table
+    layoutTables->entries[cacheIdx].len = len;
+    layoutTables->entries[cacheIdx].ptr = (const void*)result;
   }
 
-  return (void*)result;
+  length = len;
+  return (const void*)result;
 };
 
 LEGlyphID FontInstanceAdapter::mapCharToGlyph(LEUnicode32 ch, const LECharMapper *mapper) const
--- a/src/share/native/sun/font/FontInstanceAdapter.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/FontInstanceAdapter.h	Thu Apr 18 14:38:37 2013 -0700
@@ -86,6 +86,7 @@
     // tables are cached with the native font scaler data
     // only supports gsub, gpos, gdef, mort tables at present
     virtual const void *getFontTable(LETag tableTag) const;
+    virtual const void *getFontTable(LETag tableTag, size_t &len) const;
 
     virtual void *getKernPairs() const {
         return layoutTables->kernPairs;
--- a/src/share/native/sun/font/fontscalerdefs.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/fontscalerdefs.h	Thu Apr 18 14:38:37 2013 -0700
@@ -120,20 +120,19 @@
 #define GPOS_TAG 0x47504F53 /* 'GPOS' */
 #define GDEF_TAG 0x47444546 /* 'GDEF' */
 #define MORT_TAG 0x6D6F7274 /* 'mort' */
+#define MORX_TAG 0x6D6F7278 /* 'morx' */
 #define KERN_TAG 0x6B65726E /* 'kern' */
 
+typedef struct TTLayoutTableCacheEntry {
+  const void* ptr;
+  int   len;
+} TTLayoutTableCacheEntry;
+
+#define LAYOUTCACHE_ENTRIES 6
+
 typedef struct TTLayoutTableCache {
-    void* gsub;
-    void* gpos;
-    void* gdef;
-    void* mort;
-    void* kern;
-    void* kernPairs;
-    int gsub_len;
-    int gpos_len;
-    int gdef_len;
-    int mort_len;
-    int kern_len;
+  TTLayoutTableCacheEntry entries[LAYOUTCACHE_ENTRIES];
+  void* kernPairs;
 } TTLayoutTableCache;
 
 #include "sunfontids.h"
--- a/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/AlternateSubstSubtables.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -39,19 +39,20 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 AlternateSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
+le_uint32 AlternateSubstitutionSubtable::process(const LEReferenceTo<AlternateSubstitutionSubtable> &base,
+                                       GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
 {
     // NOTE: For now, we'll just pick the first alternative...
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
 
-    if (coverageIndex >= 0) {
+    if (coverageIndex >= 0 && LE_SUCCESS(success)) {
         le_uint16 altSetCount = SWAPW(alternateSetCount);
 
         if (coverageIndex < altSetCount) {
             Offset alternateSetTableOffset = SWAPW(alternateSetTableOffsetArray[coverageIndex]);
-            const AlternateSetTable *alternateSetTable =
-                (const AlternateSetTable *) ((char *) this + alternateSetTableOffset);
+            const LEReferenceTo<AlternateSetTable> alternateSetTable(base, success,
+                                  (const AlternateSetTable *) ((char *) this + alternateSetTableOffset));
             TTGlyphID alternate = SWAPW(alternateSetTable->alternateArray[0]);
 
             if (filter == NULL || filter->accept(LE_SET_GLYPH(glyph, alternate))) {
--- a/src/share/native/sun/font/layout/AlternateSubstSubtables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/AlternateSubstSubtables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -51,13 +51,17 @@
     TTGlyphID alternateArray[ANY_NUMBER];
 };
 
+LE_VAR_ARRAY(AlternateSetTable, alternateArray)
+
 struct AlternateSubstitutionSubtable : GlyphSubstitutionSubtable
 {
     le_uint16 alternateSetCount;
     Offset    alternateSetTableOffsetArray[ANY_NUMBER];
 
-    le_uint32 process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const;
+    le_uint32 process(const LEReferenceTo<AlternateSubstitutionSubtable> &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
 };
 
+LE_VAR_ARRAY(AlternateSubstitutionSubtable, alternateSetTableOffsetArray)
+
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/ArabicLayoutEngine.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ArabicLayoutEngine.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -26,7 +26,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2005 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -58,15 +58,18 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ArabicOpenTypeLayoutEngine)
 
-ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                        le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
+                                                       le_int32 languageCode, le_int32 typoFlags,
+                                                       const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable,
+                                                       LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
 {
     fFeatureMap = ArabicShaping::getFeatureMap(fFeatureMapCount);
     fFeatureOrder = TRUE;
 }
 
-ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
+ArabicOpenTypeLayoutEngine::ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode,
+                                                       le_int32 languageCode,
                                                        le_int32 typoFlags, LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
 {
@@ -88,8 +91,9 @@
 // Input: characters
 // Output: characters, char indices, tags
 // Returns: output character count
-le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
-        LEUnicode *&outChars, LEGlyphStorage &glyphStorage, LEErrorCode &success)
+le_int32 ArabicOpenTypeLayoutEngine::characterProcessing(const LEUnicode chars[], le_int32 offset, le_int32 count,
+                                                         le_int32 max, le_bool rightToLeft, LEUnicode *&outChars,
+                                                         LEGlyphStorage &glyphStorage, LEErrorCode &success)
 {
     if (LE_FAILURE(success)) {
         return 0;
@@ -137,32 +141,30 @@
         return;
     }
 
-    if (fGPOSTable != NULL) {
+    if (!fGPOSTable.isEmpty()) {
         OpenTypeLayoutEngine::adjustGlyphPositions(chars, offset, count, reverse, glyphStorage, success);
-    } else if (fGDEFTable != NULL) {
-        GDEFMarkFilter filter(fGDEFTable);
-
+    } else if (!fGDEFTable.isEmpty()) {
+        GDEFMarkFilter filter(fGDEFTable, success);
         adjustMarkGlyphs(glyphStorage, &filter, success);
     } else {
-        GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
-        GDEFMarkFilter filter(gdefTable);
+        LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
+        GDEFMarkFilter filter(gdefTable, success);
 
         adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
     }
 }
 
 UnicodeArabicOpenTypeLayoutEngine::UnicodeArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
-    : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success)
+  : ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags | LE_CHAR_FILTER_FEATURE_FLAG, success)
 {
     fGSUBTable = (const GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
     fGDEFTable = (const GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
-
-    fSubstitutionFilter = new CharSubstitutionFilter(fontInstance);
+    /* OpenTypeLayoutEngine will allocate a substitution filter */
 }
 
 UnicodeArabicOpenTypeLayoutEngine::~UnicodeArabicOpenTypeLayoutEngine()
 {
-    delete fSubstitutionFilter;
+    /* OpenTypeLayoutEngine will cleanup the substitution filter */
 }
 
 // "glyphs", "indices" -> glyphs, indices
@@ -233,7 +235,7 @@
         return;
     }
 
-    GDEFMarkFilter filter(fGDEFTable);
+    GDEFMarkFilter filter(fGDEFTable, success);
 
     adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
 }
--- a/src/share/native/sun/font/layout/ArabicLayoutEngine.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ArabicLayoutEngine.h	Thu Apr 18 14:38:37 2013 -0700
@@ -75,7 +75,7 @@
      * @internal
      */
     ArabicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
+                            le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
 
     /**
      * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/ArabicShaping.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ArabicShaping.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -58,14 +58,16 @@
 */
 ArabicShaping::ShapeType ArabicShaping::getShapeType(LEUnicode c)
 {
-    const ClassDefinitionTable *joiningTypes = (const ClassDefinitionTable *) ArabicShaping::shapingTypeTable;
-    le_int32 joiningType = joiningTypes->getGlyphClass(c);
+  LEErrorCode success = LE_NO_ERROR;
+  const LEReferenceTo<ClassDefinitionTable> joiningTypes((const ClassDefinitionTable *) ArabicShaping::shapingTypeTable,
+                                                         ArabicShaping::shapingTypeTableLen);
+  le_int32 joiningType = joiningTypes->getGlyphClass(joiningTypes, c, success);
 
-    if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT) {
-        return ArabicShaping::shapeTypes[joiningType];
-    }
+  if (joiningType >= 0 && joiningType < ArabicShaping::JT_COUNT && LE_SUCCESS(success)) {
+    return ArabicShaping::shapeTypes[joiningType];
+  }
 
-    return ArabicShaping::ST_NOSHAPE_NONE;
+  return ArabicShaping::ST_NOSHAPE_NONE;
 }
 
 #define isolFeatureTag LE_ISOL_FEATURE_TAG
--- a/src/share/native/sun/font/layout/ArabicShaping.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ArabicShaping.h	Thu Apr 18 14:38:37 2013 -0700
@@ -93,6 +93,8 @@
     static ShapeType getShapeType(LEUnicode c);
 
     static const le_uint8 shapingTypeTable[];
+    static const size_t   shapingTypeTableLen;
+
     static const ShapeType shapeTypes[];
 
     static void adjustTags(le_int32 outIndex, le_int32 shapeOffset, LEGlyphStorage &glyphStorage);
--- a/src/share/native/sun/font/layout/AttachmentPosnSubtables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/AttachmentPosnSubtables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -52,14 +52,14 @@
     Offset    markArrayOffset;
     Offset    baseArrayOffset;
 
-    inline le_int32  getBaseCoverage(LEGlyphID baseGlyphId) const;
+    inline le_int32  getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphId, LEErrorCode &success) const;
 
     le_uint32 process(GlyphIterator *glyphIterator) const;
 };
 
-inline le_int32 AttachmentPositioningSubtable::getBaseCoverage(LEGlyphID baseGlyphID) const
+inline le_int32 AttachmentPositioningSubtable::getBaseCoverage(const LETableReference &base, LEGlyphID baseGlyphID, LEErrorCode &success) const
 {
-    return getGlyphCoverage(baseCoverageTableOffset, baseGlyphID);
+  return getGlyphCoverage(base, baseCoverageTableOffset, baseGlyphID, success);
 }
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/CanonData.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/CanonData.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -3641,4 +3641,9 @@
     0x00, 0xE6, 0xD2, 0x42, 0xD2, 0x44, 0x00, 0xE6
 };
 
+
+const size_t CanonShaping::glyphSubstitutionTableLen = sizeof(glyphSubstitutionTable)/sizeof(glyphSubstitutionTable[0]);
+
+const size_t CanonShaping::glyphDefinitionTableLen = sizeof(glyphDefinitionTable)/sizeof(glyphDefinitionTable[0]);
+
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/CanonShaping.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/CanonShaping.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -59,15 +59,15 @@
 void CanonShaping::reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
                                 LEUnicode *outChars, LEGlyphStorage &glyphStorage)
 {
-    const GlyphDefinitionTableHeader *gdefTable = (const GlyphDefinitionTableHeader *) glyphDefinitionTable;
-    const ClassDefinitionTable *classTable = gdefTable->getMarkAttachClassDefinitionTable();
+    LEErrorCode success = LE_NO_ERROR;
+    LEReferenceTo<GlyphDefinitionTableHeader> gdefTable(CanonShaping::glyphDefinitionTable, CanonShaping::glyphDefinitionTableLen);
+    LEReferenceTo<ClassDefinitionTable> classTable = gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success);
     le_int32 *combiningClasses = LE_NEW_ARRAY(le_int32, charCount);
     le_int32 *indices = LE_NEW_ARRAY(le_int32, charCount);
-    LEErrorCode status = LE_NO_ERROR;
     le_int32 i;
 
     for (i = 0; i < charCount; i += 1) {
-        combiningClasses[i] = classTable->getGlyphClass((LEGlyphID) inChars[i]);
+      combiningClasses[i] = classTable->getGlyphClass(classTable, (LEGlyphID) inChars[i], success);
         indices[i] = i;
     }
 
@@ -96,7 +96,7 @@
         le_int32 index = indices[i];
 
         outChars[i] = inChars[index];
-        glyphStorage.setCharIndex(out, index, status);
+        glyphStorage.setCharIndex(out, index, success);
     }
 
     LE_DELETE_ARRAY(indices);
--- a/src/share/native/sun/font/layout/CanonShaping.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/CanonShaping.h	Thu Apr 18 14:38:37 2013 -0700
@@ -42,7 +42,9 @@
 {
 public:
     static const le_uint8 glyphSubstitutionTable[];
+    static const size_t   glyphSubstitutionTableLen;
     static const le_uint8 glyphDefinitionTable[];
+    static const size_t   glyphDefinitionTableLen;
 
     static void reorderMarks(const LEUnicode *inChars, le_int32 charCount, le_bool rightToLeft,
                                    LEUnicode *outChars, LEGlyphStorage &glyphStorage);
--- a/src/share/native/sun/font/layout/ClassDefinitionTables.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ClassDefinitionTables.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -37,24 +37,51 @@
 
 U_NAMESPACE_BEGIN
 
-le_int32 ClassDefinitionTable::getGlyphClass(LEGlyphID glyphID) const
+le_int32 ClassDefinitionTable::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
 {
+  LEReferenceTo<ClassDefinitionTable> thisRef(base, success);
+  if (LE_FAILURE(success)) return 0;
+
+  switch(SWAPW(classFormat)) {
+    case 0:
+        return 0;
+
+    case 1:
+    {
+      const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
+      return f1Table->getGlyphClass(f1Table, glyphID, success);
+    }
+
+    case 2:
+    {
+      const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
+      return  f2Table->getGlyphClass(f2Table, glyphID, success);
+    }
+
+    default:
+        return 0;
+  }
+}
+
+le_bool ClassDefinitionTable::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
+{
+    LEReferenceTo<ClassDefinitionTable> thisRef(base, success);
+    if (LE_FAILURE(success)) return 0;
+
     switch(SWAPW(classFormat)) {
     case 0:
         return 0;
 
     case 1:
     {
-        const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this;
-
-        return f1Table->getGlyphClass(glyphID);
+      const LEReferenceTo<ClassDefFormat1Table> f1Table(thisRef, success);
+      return f1Table->hasGlyphClass(f1Table, glyphClass, success);
     }
 
     case 2:
     {
-        const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this;
-
-        return f2Table->getGlyphClass(glyphID);
+      const LEReferenceTo<ClassDefFormat2Table> f2Table(thisRef, success);
+      return f2Table->hasGlyphClass(f2Table, glyphClass, success);
     }
 
     default:
@@ -62,51 +89,32 @@
     }
 }
 
-le_bool ClassDefinitionTable::hasGlyphClass(le_int32 glyphClass) const
+le_int32 ClassDefFormat1Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
 {
-    switch(SWAPW(classFormat)) {
-    case 0:
-        return 0;
+    if(LE_FAILURE(success)) return 0;
 
-    case 1:
-    {
-        const ClassDefFormat1Table *f1Table = (const ClassDefFormat1Table *) this;
-
-        return f1Table->hasGlyphClass(glyphClass);
-    }
-
-    case 2:
-    {
-        const ClassDefFormat2Table *f2Table = (const ClassDefFormat2Table *) this;
-
-        return f2Table->hasGlyphClass(glyphClass);
-    }
-
-    default:
-        return 0;
-    }
-}
-
-le_int32 ClassDefFormat1Table::getGlyphClass(LEGlyphID glyphID) const
-{
+    le_uint16 count = SWAPW(glyphCount);
+    LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count);
     TTGlyphID ttGlyphID  = (TTGlyphID) LE_GET_GLYPH(glyphID);
     TTGlyphID firstGlyph = SWAPW(startGlyph);
-    TTGlyphID lastGlyph  = firstGlyph + SWAPW(glyphCount);
+    TTGlyphID lastGlyph  = firstGlyph + count;
 
-    if (ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
-        return SWAPW(classValueArray[ttGlyphID - firstGlyph]);
+    if (LE_SUCCESS(success) && ttGlyphID >= firstGlyph && ttGlyphID < lastGlyph) {
+      return SWAPW( classValueArrayRef(ttGlyphID - firstGlyph, success) );
     }
 
     return 0;
 }
 
-le_bool ClassDefFormat1Table::hasGlyphClass(le_int32 glyphClass) const
+le_bool ClassDefFormat1Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
 {
-    le_uint16 count  = SWAPW(glyphCount);
+    if(LE_FAILURE(success)) return 0;
+    le_uint16 count = SWAPW(glyphCount);
+    LEReferenceToArrayOf<le_uint16> classValueArrayRef(base, success, &classValueArray[0], count);
     int i;
 
-    for (i = 0; i < count; i += 1) {
-        if (SWAPW(classValueArray[i]) == glyphClass) {
+    for (i = 0; LE_SUCCESS(success)&& (i < count); i += 1) {
+      if (SWAPW(classValueArrayRef(i,success)) == glyphClass) {
             return TRUE;
         }
     }
@@ -114,27 +122,31 @@
     return FALSE;
 }
 
-le_int32 ClassDefFormat2Table::getGlyphClass(LEGlyphID glyphID) const
+le_int32 ClassDefFormat2Table::getGlyphClass(const LETableReference& base, LEGlyphID glyphID, LEErrorCode &success) const
 {
+    if(LE_FAILURE(success)) return 0;
     TTGlyphID ttGlyph    = (TTGlyphID) LE_GET_GLYPH(glyphID);
     le_uint16 rangeCount = SWAPW(classRangeCount);
+    LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
     le_int32  rangeIndex =
-        OpenTypeUtilities::getGlyphRangeIndex(ttGlyph, classRangeRecordArray, rangeCount);
+      OpenTypeUtilities::getGlyphRangeIndex(ttGlyph, classRangeRecordArrayRef, success);
 
-    if (rangeIndex < 0) {
+    if (rangeIndex < 0 || LE_FAILURE(success)) {
         return 0;
     }
 
-    return SWAPW(classRangeRecordArray[rangeIndex].rangeValue);
+    return SWAPW(classRangeRecordArrayRef(rangeIndex, success).rangeValue);
 }
 
-le_bool ClassDefFormat2Table::hasGlyphClass(le_int32 glyphClass) const
+le_bool ClassDefFormat2Table::hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const
 {
+    if(LE_FAILURE(success)) return 0;
     le_uint16 rangeCount = SWAPW(classRangeCount);
+    LEReferenceToArrayOf<GlyphRangeRecord> classRangeRecordArrayRef(base, success, &classRangeRecordArray[0], rangeCount);
     int i;
 
-    for (i = 0; i < rangeCount; i += 1) {
-        if (SWAPW(classRangeRecordArray[i].rangeValue) == glyphClass) {
+    for (i = 0; i < rangeCount && LE_SUCCESS(success); i += 1) {
+      if (SWAPW(classRangeRecordArrayRef(i,success).rangeValue) == glyphClass) {
             return TRUE;
         }
     }
--- a/src/share/native/sun/font/layout/ClassDefinitionTables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ClassDefinitionTables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -46,8 +46,20 @@
 {
     le_uint16 classFormat;
 
-    le_int32  getGlyphClass(LEGlyphID glyphID) const;
-    le_bool   hasGlyphClass(le_int32 glyphClass) const;
+    le_int32  getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
+    le_bool   hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
+
+  le_int32 getGlyphClass(LEGlyphID glyphID) const {
+    LETableReference base((const le_uint8*)this);
+    LEErrorCode ignored = LE_NO_ERROR;
+    return getGlyphClass(base,glyphID,ignored);
+  }
+
+  le_bool hasGlyphClass(le_int32 glyphClass) const {
+    LETableReference base((const le_uint8*)this);
+    LEErrorCode ignored = LE_NO_ERROR;
+    return hasGlyphClass(base,glyphClass,ignored);
+  }
 };
 
 struct ClassDefFormat1Table : ClassDefinitionTable
@@ -56,9 +68,11 @@
     le_uint16  glyphCount;
     le_uint16  classValueArray[ANY_NUMBER];
 
-    le_int32 getGlyphClass(LEGlyphID glyphID) const;
-    le_bool  hasGlyphClass(le_int32 glyphClass) const;
+    le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
+    le_bool  hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(ClassDefFormat1Table, classValueArray)
+
 
 struct ClassRangeRecord
 {
@@ -72,9 +86,10 @@
     le_uint16        classRangeCount;
     GlyphRangeRecord classRangeRecordArray[ANY_NUMBER];
 
-    le_int32 getGlyphClass(LEGlyphID glyphID) const;
-    le_bool hasGlyphClass(le_int32 glyphClass) const;
+    le_int32 getGlyphClass(const LETableReference &base, LEGlyphID glyphID, LEErrorCode &success) const;
+    le_bool hasGlyphClass(const LETableReference &base, le_int32 glyphClass, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(ClassDefFormat2Table, classRangeRecordArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/ContextualGlyphInsertion.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ContextualGlyphInsertion.h	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -49,6 +49,11 @@
 {
 };
 
+struct ContextualGlyphInsertionHeader2 : MorphStateTableHeader2
+{
+    le_uint32 insertionTableOffset;
+};
+
 enum ContextualGlyphInsertionFlags
 {
     cgiSetMark                  = 0x8000,
@@ -61,11 +66,17 @@
     cgiMarkedInsertCountMask    = 0x001F
 };
 
-struct LigatureSubstitutionStateEntry : StateEntry
+struct ContextualGlyphInsertionStateEntry : StateEntry
 {
     ByteOffset currentInsertionListOffset;
     ByteOffset markedInsertionListOffset;
 };
 
+struct ContextualGlyphInsertionStateEntry2 : StateEntry2
+{
+    le_uint16 currentInsertionListIndex;
+    le_uint16 markedInsertionListIndex;
+};
+
 U_NAMESPACE_END
 #endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "StateTables.h"
+#include "MorphStateTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "ContextualGlyphInsertionProc2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphInsertionProcessor2)
+
+ContextualGlyphInsertionProcessor2::ContextualGlyphInsertionProcessor2(
+         const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor2(morphSubtableHeader, success)
+{
+  contextualGlyphHeader = LEReferenceTo<ContextualGlyphInsertionHeader2>(morphSubtableHeader, success);
+  if(LE_FAILURE(success) || !contextualGlyphHeader.isValid()) return;
+  le_uint32 insertionTableOffset = SWAPL(contextualGlyphHeader->insertionTableOffset);
+  insertionTable = LEReferenceToArrayOf<le_uint16>(stHeader, success, insertionTableOffset, LE_UNBOUNDED_ARRAY);
+  entryTable = LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
+}
+
+ContextualGlyphInsertionProcessor2::~ContextualGlyphInsertionProcessor2()
+{
+}
+
+void ContextualGlyphInsertionProcessor2::beginStateTable()
+{
+    markGlyph = 0;
+}
+
+void ContextualGlyphInsertionProcessor2::doInsertion(LEGlyphStorage &glyphStorage,
+                                                     le_int16 atGlyph,
+                                                     le_int16 &index,
+                                                     le_int16 count,
+                                                     le_bool /* isKashidaLike */,
+                                                     le_bool isBefore,
+                                                     LEErrorCode &success) {
+  LEGlyphID *insertGlyphs = glyphStorage.insertGlyphs(atGlyph, count + 1, success);
+
+  if(LE_FAILURE(success) || insertGlyphs==NULL) {
+    return;
+  }
+
+  // Note: Kashida vs Split Vowel seems to only affect selection and highlighting.
+  // We note the flag, but do not layout different.
+  // https://developer.apple.com/fonts/TTRefMan/RM06/Chap6mort.html
+
+  le_int16 targetIndex = 0;
+  if(isBefore) {
+    // insert at beginning
+    insertGlyphs[targetIndex++] = glyphStorage[atGlyph];
+  } else {
+    // insert at end
+    insertGlyphs[count] = glyphStorage[atGlyph];
+  }
+
+  while(count--) {
+    insertGlyphs[targetIndex++] = insertionTable.getObject(index++, success);
+  }
+  glyphStorage.applyInsertions();
+}
+
+le_uint16 ContextualGlyphInsertionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
+                                                                EntryTableIndex2 index, LEErrorCode &success)
+{
+    const ContextualGlyphInsertionStateEntry2 *entry = entryTable.getAlias(index, success);
+
+    if(LE_FAILURE(success)) return 0; // TODO- which state?
+
+    le_uint16 newState = SWAPW(entry->newStateIndex);
+    le_uint16 flags = SWAPW(entry->flags);
+
+    le_int16 markIndex = SWAPW(entry->markedInsertionListIndex);
+    if (markIndex > 0) {
+        le_int16 count = (flags & cgiMarkedInsertCountMask) >> 5;
+        le_bool isKashidaLike = (flags & cgiMarkedIsKashidaLike);
+        le_bool isBefore = (flags & cgiMarkInsertBefore);
+        doInsertion(glyphStorage, markGlyph, markIndex, count, isKashidaLike, isBefore, success);
+    }
+
+    le_int16 currIndex = SWAPW(entry->currentInsertionListIndex);
+    if (currIndex > 0) {
+        le_int16 count = flags & cgiCurrentInsertCountMask;
+        le_bool isKashidaLike = (flags & cgiCurrentIsKashidaLike);
+        le_bool isBefore = (flags & cgiCurrentInsertBefore);
+        doInsertion(glyphStorage, currGlyph, currIndex, count, isKashidaLike, isBefore, success);
+    }
+
+    if (flags & cgiSetMark) {
+        markGlyph = currGlyph;
+    }
+
+    if (!(flags & cgiDontAdvance)) {
+        currGlyph += dir;
+    }
+
+    return newState;
+}
+
+void ContextualGlyphInsertionProcessor2::endStateTable()
+{
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/ContextualGlyphInsertionProc2.h	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H
+#define __CONTEXTUALGLYPHINSERTIONPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "ContextualGlyphInsertionProc2.h"
+#include "ContextualGlyphInsertion.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class ContextualGlyphInsertionProcessor2 : public StateTableProcessor2
+{
+public:
+    virtual void beginStateTable();
+
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage,
+                                        le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
+
+    virtual void endStateTable();
+
+    ContextualGlyphInsertionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
+    virtual ~ContextualGlyphInsertionProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+private:
+    ContextualGlyphInsertionProcessor2();
+
+    /**
+     * Perform the actual insertion
+     * @param atGlyph index of glyph to insert at
+     * @param index index into the insertionTable (in/out)
+     * @param count number of insertions
+     * @param isKashidaLike Kashida like (vs Split Vowel like). No effect currently.
+     * @param isBefore if true, insert extra glyphs before the marked glyph
+     */
+    void doInsertion(LEGlyphStorage &glyphStorage,
+                              le_int16 atGlyph,
+                              le_int16 &index,
+                              le_int16 count,
+                              le_bool isKashidaLike,
+                              le_bool isBefore,
+                              LEErrorCode &success);
+
+
+protected:
+    le_int32 markGlyph;
+    LEReferenceToArrayOf<le_uint16> insertionTable;
+    LEReferenceToArrayOf<ContextualGlyphInsertionStateEntry2> entryTable;
+    LEReferenceTo<ContextualGlyphInsertionHeader2> contextualGlyphHeader;
+};
+
+U_NAMESPACE_END
+#endif
--- a/src/share/native/sun/font/layout/ContextualGlyphSubstProc.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -43,13 +43,18 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor)
 
-ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader)
-  : StateTableProcessor(morphSubtableHeader)
+ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success)
 {
-    contextualGlyphSubstitutionHeader = (const ContextualGlyphSubstitutionHeader *) morphSubtableHeader;
-    substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
+  contextualGlyphSubstitutionHeader.orphan();
+  substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
 
-    entryTable = (const ContextualGlyphSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+
+  entryTable = LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry>(stateTableHeader, success,
+                                                                           (const ContextualGlyphSubstitutionStateEntry*)(&stateTableHeader->stHeader),
+                                                                           entryTableOffset, LE_UNBOUNDED_ARRAY);
+  int16Table = LEReferenceToArrayOf<le_int16>(stateTableHeader, success, (const le_int16*)(&stateTableHeader->stHeader),
+                                              0, LE_UNBOUNDED_ARRAY); // rest of the table as le_int16s
 }
 
 ContextualGlyphSubstitutionProcessor::~ContextualGlyphSubstitutionProcessor()
@@ -63,27 +68,26 @@
 
 ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
 {
-    const ContextualGlyphSubstitutionStateEntry *entry = &entryTable[index];
-    ByteOffset newState = SWAPW(entry->newStateOffset);
-    le_int16 flags = SWAPW(entry->flags);
-    WordOffset markOffset = SWAPW(entry->markOffset);
-    WordOffset currOffset = SWAPW(entry->currOffset);
+  LEErrorCode success = LE_NO_ERROR;
+  const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
+  ByteOffset newState = SWAPW(entry->newStateOffset);
+  le_int16 flags = SWAPW(entry->flags);
+  WordOffset markOffset = SWAPW(entry->markOffset);
+  WordOffset currOffset = SWAPW(entry->currOffset);
 
-    if (markOffset != 0) {
-        const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + markOffset * 2);
-        LEGlyphID mGlyph = glyphStorage[markGlyph];
-        TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(mGlyph)]);
+  if (markOffset != 0 && LE_SUCCESS(success)) {
+    LEGlyphID mGlyph = glyphStorage[markGlyph];
+    TTGlyphID newGlyph = SWAPW(int16Table.getObject(markOffset + LE_GET_GLYPH(mGlyph), success)); // whew.
 
-         glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
-    }
+    glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
+  }
 
-    if (currOffset != 0) {
-        const le_int16 *table = (const le_int16 *) ((char *) &stateTableHeader->stHeader + currOffset * 2);
-        LEGlyphID thisGlyph = glyphStorage[currGlyph];
-        TTGlyphID newGlyph = SWAPW(table[LE_GET_GLYPH(thisGlyph)]);
+  if (currOffset != 0) {
+    LEGlyphID thisGlyph = glyphStorage[currGlyph];
+    TTGlyphID newGlyph = SWAPW(int16Table.getObject(currOffset + LE_GET_GLYPH(thisGlyph), success)); // whew.
 
-        glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
-    }
+    glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
+  }
 
     if (flags & cgsSetMark) {
         markGlyph = currGlyph;
--- a/src/share/native/sun/font/layout/ContextualGlyphSubstProc.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc.h	Thu Apr 18 14:38:37 2013 -0700
@@ -56,7 +56,7 @@
 
     virtual void endStateTable();
 
-    ContextualGlyphSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
     virtual ~ContextualGlyphSubstitutionProcessor();
 
     /**
@@ -78,11 +78,11 @@
 
 protected:
     ByteOffset substitutionTableOffset;
-    const ContextualGlyphSubstitutionStateEntry *entryTable;
-
+    LEReferenceToArrayOf<ContextualGlyphSubstitutionStateEntry> entryTable;
+    LEReferenceToArrayOf<le_int16> int16Table;
     le_int32 markGlyph;
 
-    const ContextualGlyphSubstitutionHeader *contextualGlyphSubstitutionHeader;
+    LEReferenceTo<ContextualGlyphSubstitutionHeader> contextualGlyphSubstitutionHeader;
 
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "StateTables.h"
+#include "MorphStateTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "ContextualGlyphSubstProc2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(ContextualGlyphSubstitutionProcessor2)
+
+ContextualGlyphSubstitutionProcessor2::ContextualGlyphSubstitutionProcessor2(
+                                  const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor2(morphSubtableHeader, success), contextualGlyphHeader(morphSubtableHeader, success)
+{
+    if(LE_FAILURE(success)) return;
+    le_uint32 perGlyphTableOffset = SWAPL(contextualGlyphHeader->perGlyphTableOffset);
+    perGlyphTable = LEReferenceToArrayOf<le_uint32> (stHeader, success, perGlyphTableOffset, LE_UNBOUNDED_ARRAY);
+    entryTable = LEReferenceToArrayOf<ContextualGlyphStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
+}
+
+ContextualGlyphSubstitutionProcessor2::~ContextualGlyphSubstitutionProcessor2()
+{
+}
+
+void ContextualGlyphSubstitutionProcessor2::beginStateTable()
+{
+    markGlyph = 0;
+}
+
+le_uint16 ContextualGlyphSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
+    EntryTableIndex2 index, LEErrorCode &success)
+{
+    if(LE_FAILURE(success)) return 0;
+    const ContextualGlyphStateEntry2 *entry = entryTable.getAlias(index, success);
+    if(LE_FAILURE(success)) return 0;
+    le_uint16 newState = SWAPW(entry->newStateIndex);
+    le_uint16 flags = SWAPW(entry->flags);
+    le_int16 markIndex = SWAPW(entry->markIndex);
+    le_int16 currIndex = SWAPW(entry->currIndex);
+
+    if (markIndex != -1) {
+        le_uint32 offset = SWAPL(perGlyphTable(markIndex, success));
+        LEGlyphID mGlyph = glyphStorage[markGlyph];
+        TTGlyphID newGlyph = lookup(offset, mGlyph, success);
+        glyphStorage[markGlyph] = LE_SET_GLYPH(mGlyph, newGlyph);
+    }
+
+    if (currIndex != -1) {
+        le_uint32 offset = SWAPL(perGlyphTable(currIndex, success));
+        LEGlyphID thisGlyph = glyphStorage[currGlyph];
+        TTGlyphID newGlyph = lookup(offset, thisGlyph, success);
+        glyphStorage[currGlyph] = LE_SET_GLYPH(thisGlyph, newGlyph);
+    }
+
+    if (flags & cgsSetMark) {
+        markGlyph = currGlyph;
+    }
+
+    if (!(flags & cgsDontAdvance)) {
+        currGlyph += dir;
+    }
+
+    return newState;
+}
+
+TTGlyphID ContextualGlyphSubstitutionProcessor2::lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success)
+{
+    TTGlyphID newGlyph = 0xFFFF;
+    if(LE_FAILURE(success))  return newGlyph;
+    LEReferenceTo<LookupTable> lookupTable(perGlyphTable, success, offset);
+    if(LE_FAILURE(success))  return newGlyph;
+    le_int16 format = SWAPW(lookupTable->format);
+
+    switch (format) {
+        case ltfSimpleArray: {
+#ifdef TEST_FORMAT
+            // Disabled pending for design review
+            LEReferenceTo<SimpleArrayLookupTable> lookupTable0(lookupTable, success);
+            LEReferenceToArrayOf<LookupValue> valueArray(lookupTable0, success, &lookupTable0->valueArray[0], LE_UNBOUNDED_ARRAY);
+            if(LE_FAILURE(success))  return newGlyph;
+            TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
+            newGlyph = SWAPW(lookupTable0->valueArray(glyphCode, success));
+#endif
+            break;
+        }
+        case ltfSegmentSingle: {
+#ifdef TEST_FORMAT
+            // Disabled pending for design review
+            LEReferenceTo<SegmentSingleLookupTable> lookupTable2 = (SegmentSingleLookupTable *) lookupTable;
+            const LookupSegment *segment = lookupTable2->lookupSegment(lookupTable2->segments, gid);
+            if (segment != NULL) {
+                newGlyph = SWAPW(segment->value);
+            }
+#endif
+            break;
+        }
+        case ltfSegmentArray: {
+            //printf("Context Lookup Table Format4: specific interpretation needed!\n");
+            break;
+        }
+        case ltfSingleTable:
+        {
+#ifdef TEST_FORMAT
+            // Disabled pending for design review
+            LEReferenceTo<SingleTableLookupTable> lookupTable6 = (SingleTableLookupTable *) lookupTable;
+            const LEReferenceTo<LookupSingle> segment = lookupTable6->lookupSingle(lookupTable6->entries, gid);
+            if (segment != NULL) {
+                newGlyph = SWAPW(segment->value);
+            }
+#endif
+            break;
+        }
+        case ltfTrimmedArray: {
+            LEReferenceTo<TrimmedArrayLookupTable> lookupTable8(lookupTable, success);
+            if (LE_FAILURE(success)) return newGlyph;
+            TTGlyphID firstGlyph = SWAPW(lookupTable8->firstGlyph);
+            TTGlyphID glyphCount = SWAPW(lookupTable8->glyphCount);
+            TTGlyphID lastGlyph  = firstGlyph + glyphCount;
+            TTGlyphID glyphCode = (TTGlyphID) LE_GET_GLYPH(gid);
+            if ((glyphCode >= firstGlyph) && (glyphCode < lastGlyph)) {
+              LEReferenceToArrayOf<LookupValue> valueArray(lookupTable8, success, &lookupTable8->valueArray[0], glyphCount);
+              newGlyph = SWAPW(valueArray(glyphCode - firstGlyph, success));
+            }
+        }
+        default:
+            break;
+    }
+    return newGlyph;
+}
+
+void ContextualGlyphSubstitutionProcessor2::endStateTable()
+{
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstProc2.h	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
+#define __CONTEXTUALGLYPHSUBSTITUTIONPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "ContextualGlyphSubstitution.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class ContextualGlyphSubstitutionProcessor2 : public StateTableProcessor2
+{
+public:
+    virtual void beginStateTable();
+
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
+
+    virtual void endStateTable();
+
+    ContextualGlyphSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
+    virtual ~ContextualGlyphSubstitutionProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+private:
+    ContextualGlyphSubstitutionProcessor2();
+    TTGlyphID lookup(le_uint32 offset, LEGlyphID gid, LEErrorCode &success);
+
+protected:
+    LEReferenceToArrayOf<le_uint32>           perGlyphTable;
+    LEReferenceToArrayOf<ContextualGlyphStateEntry2> entryTable;
+
+    le_int16 perGlyphTableFormat;
+    le_int32 markGlyph;
+
+    LEReferenceTo<ContextualGlyphHeader2> contextualGlyphHeader;
+
+};
+
+U_NAMESPACE_END
+#endif
--- a/src/share/native/sun/font/layout/ContextualGlyphSubstitution.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ContextualGlyphSubstitution.h	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -49,6 +49,11 @@
     ByteOffset  substitutionTableOffset;
 };
 
+struct ContextualGlyphHeader2 : MorphStateTableHeader2
+{
+    le_uint32  perGlyphTableOffset; // no more substitution tables
+};
+
 enum ContextualGlyphSubstitutionFlags
 {
     cgsSetMark      = 0x8000,
@@ -62,5 +67,11 @@
     WordOffset currOffset;
 };
 
+struct ContextualGlyphStateEntry2 : StateEntry2
+{
+    le_uint16 markIndex;
+    le_uint16 currIndex;
+};
+
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ContextualSubstSubtables.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -217,7 +217,7 @@
     }
 
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
 
     if (coverageIndex >= 0) {
         le_uint16 srSetCount = SWAPW(subRuleSetCount);
@@ -266,7 +266,7 @@
     }
 
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
 
     if (coverageIndex >= 0) {
         const ClassDefinitionTable *classDefinitionTable =
@@ -394,7 +394,7 @@
     }
 
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
 
     if (coverageIndex >= 0) {
         le_uint16 srSetCount = SWAPW(chainSubRuleSetCount);
@@ -465,7 +465,7 @@
     }
 
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(lookupProcessor->getReference(), glyph, success);
 
     if (coverageIndex >= 0) {
         const ClassDefinitionTable *backtrackClassDefinitionTable =
--- a/src/share/native/sun/font/layout/ContextualSubstSubtables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ContextualSubstSubtables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -43,6 +43,7 @@
 #include "GlyphSubstitutionTables.h"
 #include "GlyphIterator.h"
 #include "LookupProcessor.h"
+#include "LETableReference.h"
 
 U_NAMESPACE_BEGIN
 
@@ -88,6 +89,8 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ContextualSubstitutionFormat1Subtable, subRuleSetTableOffsetArray)
+
 
 struct SubRuleSetTable
 {
@@ -95,6 +98,7 @@
     Offset  subRuleTableOffsetArray[ANY_NUMBER];
 
 };
+LE_VAR_ARRAY(SubRuleSetTable, subRuleTableOffsetArray)
 
 // NOTE: Multiple variable size arrays!!
 struct SubRuleTable
@@ -104,6 +108,7 @@
     TTGlyphID inputGlyphArray[ANY_NUMBER];
   //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(SubRuleTable, inputGlyphArray)
 
 struct ContextualSubstitutionFormat2Subtable : ContextualSubstitutionSubtable
 {
@@ -113,12 +118,16 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ContextualSubstitutionFormat2Subtable, subClassSetTableOffsetArray)
+
 
 struct SubClassSetTable
 {
     le_uint16  subClassRuleCount;
     Offset  subClassRuleTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(SubClassSetTable, subClassRuleTableOffsetArray)
+
 
 // NOTE: Multiple variable size arrays!!
 struct SubClassRuleTable
@@ -128,6 +137,8 @@
     le_uint16  classArray[ANY_NUMBER];
   //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(SubClassRuleTable, classArray)
+
 
 // NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause
 // it has an array of coverage tables instead of a single coverage table...
@@ -143,6 +154,7 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ContextualSubstitutionFormat3Subtable, coverageTableOffsetArray)
 
 struct ChainingContextualSubstitutionSubtable : ContextualSubstitutionBase
 {
@@ -156,6 +168,8 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ChainingContextualSubstitutionFormat1Subtable, chainSubRuleSetTableOffsetArray)
+
 
 struct ChainSubRuleSetTable
 {
@@ -163,6 +177,7 @@
     Offset  chainSubRuleTableOffsetArray[ANY_NUMBER];
 
 };
+LE_VAR_ARRAY(ChainSubRuleSetTable, chainSubRuleTableOffsetArray)
 
 // NOTE: Multiple variable size arrays!!
 struct ChainSubRuleTable
@@ -176,6 +191,7 @@
   //le_uint16  substCount;
   //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(ChainSubRuleTable, backtrackGlyphArray)
 
 struct ChainingContextualSubstitutionFormat2Subtable : ChainingContextualSubstitutionSubtable
 {
@@ -187,12 +203,15 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ChainingContextualSubstitutionFormat2Subtable, chainSubClassSetTableOffsetArray)
 
 struct ChainSubClassSetTable
 {
     le_uint16  chainSubClassRuleCount;
     Offset  chainSubClassRuleTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(ChainSubClassSetTable, chainSubClassRuleTableOffsetArray)
+
 
 // NOTE: Multiple variable size arrays!!
 struct ChainSubClassRuleTable
@@ -206,6 +225,7 @@
   //le_uint16  substCount;
   //SubstitutionLookupRecord substLookupRecordArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(ChainSubClassRuleTable, backtrackClassArray)
 
 // NOTE: This isn't a subclass of GlyphSubstitutionSubtable 'cause
 // it has arrays of coverage tables instead of a single coverage table...
@@ -225,6 +245,8 @@
 
     le_uint32  process(const LookupProcessor *lookupProcessor, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const;
 };
+LE_VAR_ARRAY(ChainingContextualSubstitutionFormat3Subtable, backtrackCoverageTableOffsetArray)
+
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/CoverageTables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/CoverageTables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -56,6 +56,8 @@
 
     le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
 };
+LE_VAR_ARRAY(CoverageFormat1Table, glyphArray)
+
 
 struct CoverageFormat2Table : CoverageTable
 {
@@ -64,6 +66,7 @@
 
     le_int32 getGlyphCoverage(LEGlyphID glyphID) const;
 };
+LE_VAR_ARRAY(CoverageFormat2Table, rangeRecordArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/CursiveAttachmentSubtables.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -39,10 +39,10 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 CursiveAttachmentSubtable::process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const
+le_uint32 CursiveAttachmentSubtable::process(const LEReferenceTo<CursiveAttachmentSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const
 {
     LEGlyphID glyphID       = glyphIterator->getCurrGlyphID();
-    le_int32  coverageIndex = getGlyphCoverage(glyphID);
+    le_int32  coverageIndex = getGlyphCoverage(base, glyphID, success);
     le_uint16 eeCount       = SWAPW(entryExitCount);
 
     if (coverageIndex < 0 || coverageIndex >= eeCount) {
@@ -51,7 +51,7 @@
     }
 
     LEPoint entryAnchor, exitAnchor;
-    Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor);
+    Offset entryOffset = SWAPW(entryExitRecords[coverageIndex].entryAnchor); // TODO
     Offset exitOffset  = SWAPW(entryExitRecords[coverageIndex].exitAnchor);
 
     if (entryOffset != 0) {
--- a/src/share/native/sun/font/layout/CursiveAttachmentSubtables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/CursiveAttachmentSubtables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -57,8 +57,9 @@
     le_uint16 entryExitCount;
     EntryExitRecord entryExitRecords[ANY_NUMBER];
 
-    le_uint32  process(GlyphIterator *glyphIterator, const LEFontInstance *fontInstance) const;
+    le_uint32  process(const LEReferenceTo<CursiveAttachmentSubtable> &base, GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode &success) const;
 };
+LE_VAR_ARRAY(CursiveAttachmentSubtable, entryExitRecords)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/DeviceTables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/DeviceTables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -57,6 +57,7 @@
     static const le_uint16 fieldSignBits[];
     static const le_uint16 fieldBits[];
 };
+LE_VAR_ARRAY(DeviceTable, deltaValues)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/ExtensionSubtables.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ExtensionSubtables.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -47,6 +47,8 @@
 le_uint32 ExtensionSubtable::process(const LookupProcessor *lookupProcessor, le_uint16 lookupType,
                                       GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
 {
+    const LEReferenceTo<ExtensionSubtable> thisRef(lookupProcessor->getReference(), success); // create a reference to this
+
     if (LE_FAILURE(success)) {
         return 0;
     }
@@ -55,9 +57,11 @@
 
     if (elt != lookupType) {
         le_uint32 extOffset = READ_LONG(extensionOffset);
-        LookupSubtable *subtable = (LookupSubtable *) ((char *) this + extOffset);
+        LEReferenceTo<LookupSubtable> subtable(thisRef, success, extOffset);
 
-        return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success);
+        if(LE_SUCCESS(success)) {
+          return lookupProcessor->applySubtable(subtable, elt, glyphIterator, fontInstance, success);
+        }
     }
 
     return 0;
--- a/src/share/native/sun/font/layout/Features.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/Features.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -38,19 +38,20 @@
 
 U_NAMESPACE_BEGIN
 
-const FeatureTable *FeatureListTable::getFeatureTable(le_uint16 featureIndex, LETag *featureTag) const
+LEReferenceTo<FeatureTable> FeatureListTable::getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const
 {
-    if (featureIndex >= SWAPW(featureCount)) {
-        return 0;
-    }
+  if (featureIndex >= SWAPW(featureCount) || LE_FAILURE(success)) {
+    return LEReferenceTo<FeatureTable>();
+  }
 
     Offset featureTableOffset = featureRecordArray[featureIndex].featureTableOffset;
 
     *featureTag = SWAPT(featureRecordArray[featureIndex].featureTag);
 
-    return (const FeatureTable *) ((char *) this + SWAPW(featureTableOffset));
+    return LEReferenceTo<FeatureTable>(base, success, SWAPW(featureTableOffset));
 }
 
+#if 0
 /*
  * Note: according to the OpenType Spec. v 1.4, the entries in the Feature
  * List Table are sorted alphabetically by feature tag; however, there seem
@@ -82,5 +83,6 @@
     return 0;
 #endif
 }
+#endif
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GDEFMarkFilter.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GDEFMarkFilter.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -36,9 +36,12 @@
 
 U_NAMESPACE_BEGIN
 
-GDEFMarkFilter::GDEFMarkFilter(const GlyphDefinitionTableHeader *gdefTable)
+GDEFMarkFilter::GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success)
+  : classDefTable(gdefTable->getGlyphClassDefinitionTable(gdefTable, success))
 {
-    classDefTable = gdefTable->getGlyphClassDefinitionTable();
+  if(!classDefTable.isValid()) {
+    success = LE_INTERNAL_ERROR;
+  }
 }
 
 GDEFMarkFilter::~GDEFMarkFilter()
--- a/src/share/native/sun/font/layout/GDEFMarkFilter.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GDEFMarkFilter.h	Thu Apr 18 14:38:37 2013 -0700
@@ -46,13 +46,13 @@
 class GDEFMarkFilter : public UMemory, public LEGlyphFilter
 {
 private:
-    const GlyphClassDefinitionTable *classDefTable;
+    const LEReferenceTo<GlyphClassDefinitionTable> classDefTable;
 
     GDEFMarkFilter(const GDEFMarkFilter &other); // forbid copying of this class
     GDEFMarkFilter &operator=(const GDEFMarkFilter &other); // forbid copying of this class
 
 public:
-    GDEFMarkFilter(const GlyphDefinitionTableHeader *gdefTable);
+    GDEFMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
     virtual ~GDEFMarkFilter();
 
     virtual le_bool accept(LEGlyphID glyph) const;
--- a/src/share/native/sun/font/layout/GXLayoutEngine.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GXLayoutEngine.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -41,9 +41,10 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine)
 
-GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success)
+  GXLayoutEngine::GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader> &morphTable, LEErrorCode &success)
     : LayoutEngine(fontInstance, scriptCode, languageCode, 0, success), fMorphTable(morphTable)
 {
+  fMorphTable.orphan();
     // nothing else to do?
 }
 
@@ -70,7 +71,7 @@
         return 0;
     }
 
-    fMorphTable->process(glyphStorage);
+    fMorphTable->process(fMorphTable, glyphStorage, success);
 
     return count;
 }
--- a/src/share/native/sun/font/layout/GXLayoutEngine.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GXLayoutEngine.h	Thu Apr 18 14:38:37 2013 -0700
@@ -74,7 +74,7 @@
      *
      * @internal
      */
-    GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const MorphTableHeader *morphTable, LEErrorCode &success);
+    GXLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader> &morphTable, LEErrorCode &success);
 
     /**
      * The destructor, virtual for correct polymorphic invocation.
@@ -104,7 +104,7 @@
      *
      * @internal
      */
-    const MorphTableHeader *fMorphTable;
+    LEReferenceTo<MorphTableHeader> fMorphTable;
 
     /**
      * This method does GX layout using the font's 'mort' table. It converts the
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/GXLayoutEngine2.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "LayoutEngine.h"
+#include "GXLayoutEngine2.h"
+#include "LEGlyphStorage.h"
+#include "MorphTables.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(GXLayoutEngine2)
+
+GXLayoutEngine2::GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader2> &morphTable, le_int32 typoFlags, LEErrorCode &success)
+  : LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success), fMorphTable(morphTable)
+{
+  // nothing else to do?
+}
+
+GXLayoutEngine2::~GXLayoutEngine2()
+{
+    reset();
+}
+
+// apply 'morx' table
+le_int32 GXLayoutEngine2::computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft, LEGlyphStorage &glyphStorage, LEErrorCode &success)
+{
+    if (LE_FAILURE(success)) {
+        return 0;
+    }
+
+    if (chars == NULL || offset < 0 || count < 0 || max < 0 || offset >= max || offset + count > max) {
+        success = LE_ILLEGAL_ARGUMENT_ERROR;
+        return 0;
+    }
+
+    mapCharsToGlyphs(chars, offset, count, rightToLeft, rightToLeft, glyphStorage, success);
+
+    if (LE_FAILURE(success)) {
+        return 0;
+    }
+
+    fMorphTable->process(fMorphTable, glyphStorage, fTypoFlags, success);
+    return count;
+}
+
+// apply positional tables
+void GXLayoutEngine2::adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool /*reverse*/,
+                                          LEGlyphStorage &/*glyphStorage*/, LEErrorCode &success)
+{
+    if (LE_FAILURE(success)) {
+        return;
+    }
+
+    if (chars == NULL || offset < 0 || count < 0) {
+        success = LE_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+
+    // FIXME: no positional processing yet...
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/GXLayoutEngine2.h	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,149 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __GXLAYOUTENGINE2_H
+#define __GXLAYOUTENGINE2_H
+
+#include "LETypes.h"
+#include "LayoutEngine.h"
+
+#include "MorphTables.h"
+
+U_NAMESPACE_BEGIN
+
+class LEFontInstance;
+class LEGlyphStorage;
+
+/**
+ * This class implements layout for QuickDraw GX or Apple Advanced Typograyph (AAT)
+ * fonts. A font is a GX or AAT font if it contains a 'mort' table. See Apple's
+ * TrueType Reference Manual (http://fonts.apple.com/TTRefMan/index.html) for details.
+ * Information about 'mort' tables is in the chapter titled "Font Files."
+ *
+ * @internal
+ */
+class GXLayoutEngine2 : public LayoutEngine
+{
+public:
+    /**
+     * This is the main constructor. It constructs an instance of GXLayoutEngine for
+     * a particular font, script and language. It takes the 'mort' table as a parameter since
+     * LayoutEngine::layoutEngineFactory has to read the 'mort' table to know that it has a
+     * GX font.
+     *
+     * Note: GX and AAT fonts don't contain any script and language specific tables, so
+     * the script and language are ignored.
+     *
+     * @param fontInstance - the font
+     * @param scriptCode - the script
+     * @param langaugeCode - the language
+     * @param morphTable - the 'mort' table
+     * @param success - set to an error code if the operation fails
+     *
+     * @see LayoutEngine::layoutEngineFactory
+     * @see ScriptAndLangaugeTags.h for script and language codes
+     *
+     * @internal
+     */
+    GXLayoutEngine2(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, const LEReferenceTo<MorphTableHeader2> &morphTable, le_int32 typoFlags, LEErrorCode &success);
+
+    /**
+     * The destructor, virtual for correct polymorphic invocation.
+     *
+     * @internal
+     */
+    virtual ~GXLayoutEngine2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+protected:
+
+    /**
+     * The address of the 'mort' table
+     *
+     * @internal
+     */
+    const LEReferenceTo<MorphTableHeader2> fMorphTable;
+
+    /**
+     * This method does GX layout using the font's 'mort' table. It converts the
+     * input character codes to glyph indices using mapCharsToGlyphs, and then
+     * applies the 'mort' table.
+     *
+     * Input parameters:
+     * @param chars - the input character context
+     * @param offset - the index of the first character to process
+     * @param count - the number of characters to process
+     * @param max - the number of characters in the input context
+     * @param rightToLeft - <code>TRUE</code> if the text is in a right to left directional run
+     * @param glyphStorage - the glyph storage object. The glyph and char index arrays will be set.
+     *
+     * Output parameters:
+     * @param success - set to an error code if the operation fails
+     *
+     * @return the number of glyphs in the glyph index array
+     *
+     * @internal
+     */
+    virtual le_int32 computeGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_int32 max, le_bool rightToLeft,
+        LEGlyphStorage &glyphStorage, LEErrorCode &success);
+
+    /**
+     * This method adjusts the glyph positions using the font's
+     * 'kern', 'trak', 'bsln', 'opbd' and 'just' tables.
+     *
+     * Input parameters:
+     * @param glyphStorage - the object holding the glyph storage. The positions will be updated as needed.
+     *
+     * Output parameters:
+     * @param success - set to an error code if the operation fails
+     *
+     * @internal
+     */
+    virtual void adjustGlyphPositions(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse,
+                                      LEGlyphStorage &glyphStorage, LEErrorCode &success);
+
+};
+
+U_NAMESPACE_END
+#endif
--- a/src/share/native/sun/font/layout/GlyphDefinitionTables.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphDefinitionTables.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -36,24 +36,36 @@
 
 U_NAMESPACE_BEGIN
 
-const GlyphClassDefinitionTable *GlyphDefinitionTableHeader::getGlyphClassDefinitionTable() const
+const LEReferenceTo<GlyphClassDefinitionTable>
+GlyphDefinitionTableHeader::getGlyphClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                                         LEErrorCode &success) const
 {
-    return (const GlyphClassDefinitionTable *) ((char *) this + SWAPW(glyphClassDefOffset));
+  if(LE_FAILURE(success)) return LEReferenceTo<GlyphClassDefinitionTable>();
+  return LEReferenceTo<GlyphClassDefinitionTable>(base, success, SWAPW(glyphClassDefOffset));
 }
 
-const AttachmentListTable *GlyphDefinitionTableHeader::getAttachmentListTable() const
+const LEReferenceTo<AttachmentListTable>
+GlyphDefinitionTableHeader::getAttachmentListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                                         LEErrorCode &success) const
 {
-    return (const AttachmentListTable *) ((char *) this + SWAPW(attachListOffset));
+    if(LE_FAILURE(success)) return LEReferenceTo<AttachmentListTable>();
+    return LEReferenceTo<AttachmentListTable>(base, success, SWAPW(attachListOffset));
 }
 
-const LigatureCaretListTable *GlyphDefinitionTableHeader::getLigatureCaretListTable() const
+const LEReferenceTo<LigatureCaretListTable>
+GlyphDefinitionTableHeader::getLigatureCaretListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                                         LEErrorCode &success) const
 {
-    return (const LigatureCaretListTable *) ((char *) this + SWAPW(ligCaretListOffset));
+    if(LE_FAILURE(success)) return LEReferenceTo<LigatureCaretListTable>();
+    return LEReferenceTo<LigatureCaretListTable>(base, success, SWAPW(ligCaretListOffset));
 }
 
-const MarkAttachClassDefinitionTable *GlyphDefinitionTableHeader::getMarkAttachClassDefinitionTable() const
+const LEReferenceTo<MarkAttachClassDefinitionTable>
+GlyphDefinitionTableHeader::getMarkAttachClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                                         LEErrorCode &success) const
 {
-    return (const MarkAttachClassDefinitionTable *) ((char *) this + SWAPW(MarkAttachClassDefOffset));
+    if(LE_FAILURE(success)) return LEReferenceTo<MarkAttachClassDefinitionTable>();
+    return LEReferenceTo<MarkAttachClassDefinitionTable>(base, success, SWAPW(MarkAttachClassDefOffset));
 }
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphDefinitionTables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphDefinitionTables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -60,12 +60,14 @@
     le_uint16  glyphCount;
     Offset  attachPointTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(AttachmentListTable, attachPointTableOffsetArray)
 
 struct AttachPointTable
 {
     le_uint16  pointCount;
     le_uint16  pointIndexArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(AttachPointTable, pointIndexArray)
 
 struct LigatureCaretListTable
 {
@@ -73,12 +75,14 @@
     le_uint16  ligGlyphCount;
     Offset  ligGlyphTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(LigatureCaretListTable, ligGlyphTableOffsetArray)
 
 struct LigatureGlyphTable
 {
     le_uint16  caretCount;
     Offset  caretValueTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(LigatureGlyphTable, caretValueTableOffsetArray)
 
 struct CaretValueTable
 {
@@ -111,10 +115,18 @@
     Offset  ligCaretListOffset;
     Offset  MarkAttachClassDefOffset;
 
-    const GlyphClassDefinitionTable *getGlyphClassDefinitionTable() const;
-    const AttachmentListTable *getAttachmentListTable()const ;
-    const LigatureCaretListTable *getLigatureCaretListTable() const;
-    const MarkAttachClassDefinitionTable *getMarkAttachClassDefinitionTable() const;
+    const LEReferenceTo<GlyphClassDefinitionTable>
+    getGlyphClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                 LEErrorCode &success) const;
+    const LEReferenceTo<AttachmentListTable>
+    getAttachmentListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                           LEErrorCode &success)const ;
+    const LEReferenceTo<LigatureCaretListTable>
+    getLigatureCaretListTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                              LEErrorCode &success) const;
+    const LEReferenceTo<MarkAttachClassDefinitionTable>
+    getMarkAttachClassDefinitionTable(const LEReferenceTo<GlyphDefinitionTableHeader>& base,
+                                      LEErrorCode &success) const;
 };
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphIterator.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphIterator.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -41,18 +41,21 @@
 U_NAMESPACE_BEGIN
 
 GlyphIterator::GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
-                             FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader)
+                             FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader)
   : direction(1), position(-1), nextLimit(-1), prevLimit(-1),
     glyphStorage(theGlyphStorage), glyphPositionAdjustments(theGlyphPositionAdjustments),
     srcIndex(-1), destIndex(-1), lookupFlags(theLookupFlags), featureMask(theFeatureMask), glyphGroup(0),
-    glyphClassDefinitionTable(NULL), markAttachClassDefinitionTable(NULL)
+    glyphClassDefinitionTable(), markAttachClassDefinitionTable()
 
 {
+  LEErrorCode success = LE_NO_ERROR; // TODO
     le_int32 glyphCount = glyphStorage.getGlyphCount();
 
-    if (theGlyphDefinitionTableHeader != NULL) {
-        glyphClassDefinitionTable = theGlyphDefinitionTableHeader->getGlyphClassDefinitionTable();
-        markAttachClassDefinitionTable = theGlyphDefinitionTableHeader->getMarkAttachClassDefinitionTable();
+    if (theGlyphDefinitionTableHeader.isValid()) {
+      glyphClassDefinitionTable = theGlyphDefinitionTableHeader
+        -> getGlyphClassDefinitionTable(theGlyphDefinitionTableHeader, success);
+      markAttachClassDefinitionTable = theGlyphDefinitionTableHeader
+        ->getMarkAttachClassDefinitionTable(theGlyphDefinitionTableHeader, success);
     }
 
     nextLimit = glyphCount;
@@ -380,6 +383,7 @@
 
 le_bool GlyphIterator::filterGlyph(le_uint32 index) const
 {
+    LEErrorCode success = LE_NO_ERROR;
     LEGlyphID glyphID = glyphStorage[index];
     le_int32 glyphClass = gcdNoGlyphClass;
 
@@ -387,8 +391,8 @@
         return TRUE;
     }
 
-    if (glyphClassDefinitionTable != NULL) {
-        glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphID);
+    if (glyphClassDefinitionTable.isValid()) {
+      glyphClass = glyphClassDefinitionTable->getGlyphClass(glyphClassDefinitionTable, glyphID, success);
     }
 
     switch (glyphClass)
@@ -410,8 +414,9 @@
 
         le_uint16 markAttachType = (lookupFlags & lfMarkAttachTypeMask) >> lfMarkAttachTypeShift;
 
-        if ((markAttachType != 0) && (markAttachClassDefinitionTable != NULL)) {
-            return markAttachClassDefinitionTable->getGlyphClass(glyphID) != markAttachType;
+        if ((markAttachType != 0) && (markAttachClassDefinitionTable.isValid())) {
+          return markAttachClassDefinitionTable
+            -> getGlyphClass(markAttachClassDefinitionTable, glyphID, success) != markAttachType;
         }
 
         return FALSE;
@@ -461,6 +466,7 @@
     while (newPosition != nextLimit && delta > 0) {
         do {
             newPosition += direction;
+            //fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
         } while (newPosition != nextLimit && filterGlyph(newPosition));
 
         delta -= 1;
@@ -468,6 +474,7 @@
 
     position = newPosition;
 
+    //fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
     return position != nextLimit;
 }
 
@@ -483,6 +490,7 @@
     while (newPosition != prevLimit && delta > 0) {
         do {
             newPosition -= direction;
+            //fprintf(stderr,"%s:%d:%s: newPosition = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, newPosition, delta);
         } while (newPosition != prevLimit && filterGlyph(newPosition));
 
         delta -= 1;
@@ -490,6 +498,7 @@
 
     position = newPosition;
 
+    //fprintf(stderr,"%s:%d:%s: exit position = %d, delta = %d\n", __FILE__, __LINE__, __FUNCTION__, position, delta);
     return position != prevLimit;
 }
 
--- a/src/share/native/sun/font/layout/GlyphIterator.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphIterator.h	Thu Apr 18 14:38:37 2013 -0700
@@ -49,7 +49,7 @@
 class GlyphIterator : public UMemory {
 public:
     GlyphIterator(LEGlyphStorage &theGlyphStorage, GlyphPositionAdjustments *theGlyphPositionAdjustments, le_bool rightToLeft, le_uint16 theLookupFlags,
-        FeatureMask theFeatureMask, const GlyphDefinitionTableHeader *theGlyphDefinitionTableHeader);
+                  FeatureMask theFeatureMask, const LEReferenceTo<GlyphDefinitionTableHeader> &theGlyphDefinitionTableHeader);
 
     GlyphIterator(GlyphIterator &that);
 
@@ -117,8 +117,8 @@
     FeatureMask featureMask;
     le_int32    glyphGroup;
 
-    const GlyphClassDefinitionTable *glyphClassDefinitionTable;
-    const MarkAttachClassDefinitionTable *markAttachClassDefinitionTable;
+    LEReferenceTo<GlyphClassDefinitionTable> glyphClassDefinitionTable;
+    LEReferenceTo<MarkAttachClassDefinitionTable> markAttachClassDefinitionTable;
 
     GlyphIterator &operator=(const GlyphIterator &other); // forbid copying of this class
 };
--- a/src/share/native/sun/font/layout/GlyphLookupTables.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphLookupTables.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -37,21 +37,22 @@
 
 U_NAMESPACE_BEGIN
 
-le_bool GlyphLookupTableHeader::coversScript(LETag scriptTag) const
+le_bool GlyphLookupTableHeader::coversScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const
 {
-    const ScriptListTable *scriptListTable = (const ScriptListTable *) ((char *)this + SWAPW(scriptListOffset));
+  LEReferenceTo<ScriptListTable> scriptListTable(base, success, SWAPW(scriptListOffset));
 
-    return scriptListOffset != 0 && scriptListTable->findScript(scriptTag) != NULL;
+  return (scriptListOffset != 0) && scriptListTable->findScript(scriptListTable, scriptTag, success) .isValid();
 }
 
-le_bool GlyphLookupTableHeader::coversScriptAndLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch) const
+le_bool GlyphLookupTableHeader::coversScriptAndLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch) const
 {
-    const ScriptListTable *scriptListTable = (const ScriptListTable *) ((char *)this + SWAPW(scriptListOffset));
-    const LangSysTable    *langSysTable    = scriptListTable->findLanguage(scriptTag, languageTag, exactMatch);
+  LEReferenceTo<ScriptListTable> scriptListTable(base, success, SWAPW(scriptListOffset));
+  LEReferenceTo<LangSysTable> langSysTable = scriptListTable->findLanguage(scriptListTable,
+                                    scriptTag, languageTag, success, exactMatch);
 
     // FIXME: could check featureListOffset, lookupListOffset, and lookup count...
     // Note: don't have to SWAPW langSysTable->featureCount to check for non-zero.
-    return langSysTable != NULL && langSysTable->featureCount != 0;
+  return LE_SUCCESS(success)&&langSysTable.isValid() && langSysTable->featureCount != 0;
 }
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphLookupTables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphLookupTables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -49,8 +49,8 @@
     Offset  featureListOffset;
     Offset  lookupListOffset;
 
-    le_bool coversScript(LETag scriptTag) const;
-    le_bool coversScriptAndLanguage(LETag scriptTag, LETag languageTag, le_bool exactMatch = FALSE) const;
+  le_bool coversScript(const LETableReference &base, LETag scriptTag, LEErrorCode &success) const;
+  le_bool coversScriptAndLanguage(const LETableReference &base, LETag scriptTag, LETag languageTag, LEErrorCode &success, le_bool exactMatch = FALSE) const;
 };
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/GlyphPositioningTables.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphPositioningTables.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -41,16 +41,16 @@
 
 U_NAMESPACE_BEGIN
 
-void GlyphPositioningTableHeader::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft,
+void GlyphPositioningTableHeader::process(const LEReferenceTo<GlyphPositioningTableHeader> &base, LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments, le_bool rightToLeft,
                                           LETag scriptTag, LETag languageTag,
-                                          const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success,
+                                          const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, LEErrorCode &success,
                                           const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const
 {
     if (LE_FAILURE(success)) {
         return;
     }
 
-    GlyphPositioningLookupProcessor processor(this, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success);
+    GlyphPositioningLookupProcessor processor(base, scriptTag, languageTag, featureMap, featureMapCount, featureOrder, success);
     if (LE_FAILURE(success)) {
         return;
     }
--- a/src/share/native/sun/font/layout/GlyphPositioningTables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphPositioningTables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -40,6 +40,7 @@
 #include "OpenTypeTables.h"
 #include "Lookups.h"
 #include "GlyphLookupTables.h"
+#include "LETableReference.h"
 
 U_NAMESPACE_BEGIN
 
@@ -51,9 +52,9 @@
 
 struct GlyphPositioningTableHeader : public GlyphLookupTableHeader
 {
-    void    process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
+  void    process(const LEReferenceTo<GlyphPositioningTableHeader> &base, LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
                 le_bool rightToLeft, LETag scriptTag, LETag languageTag,
-                const GlyphDefinitionTableHeader *glyphDefinitionTableHeader, LEErrorCode &success,
+                const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader, LEErrorCode &success,
                 const LEFontInstance *fontInstance, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool featureOrder) const;
 };
 
--- a/src/share/native/sun/font/layout/GlyphPosnLookupProc.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphPosnLookupProc.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -57,7 +57,7 @@
 typedef ChainingContextualSubstitutionSubtable ChainingContextualPositioningSubtable;
 
 GlyphPositioningLookupProcessor::GlyphPositioningLookupProcessor(
-        const GlyphPositioningTableHeader *glyphPositioningTableHeader,
+        const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader,
         LETag scriptTag,
         LETag languageTag,
         const FeatureMap *featureMap,
@@ -65,7 +65,7 @@
         le_bool featureOrder,
         LEErrorCode& success)
     : LookupProcessor(
-                      (char *) glyphPositioningTableHeader,
+                      glyphPositioningTableHeader,
                       SWAPW(glyphPositioningTableHeader->scriptListOffset),
                       SWAPW(glyphPositioningTableHeader->featureListOffset),
                       SWAPW(glyphPositioningTableHeader->lookupListOffset),
@@ -84,7 +84,7 @@
 {
 }
 
-le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType,
+le_uint32 GlyphPositioningLookupProcessor::applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType,
                                                        GlyphIterator *glyphIterator,
                                                        const LEFontInstance *fontInstance,
                                                        LEErrorCode& success) const
@@ -102,55 +102,55 @@
 
     case gpstSingle:
     {
-        const SinglePositioningSubtable *subtable = (const SinglePositioningSubtable *) lookupSubtable;
+      LEReferenceTo<SinglePositioningSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
     case gpstPair:
     {
-        const PairPositioningSubtable *subtable = (const PairPositioningSubtable *) lookupSubtable;
+        LEReferenceTo<PairPositioningSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
     case gpstCursive:
     {
-        const CursiveAttachmentSubtable *subtable = (const CursiveAttachmentSubtable *) lookupSubtable;
+        LEReferenceTo<CursiveAttachmentSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
     case gpstMarkToBase:
     {
-        const MarkToBasePositioningSubtable *subtable = (const MarkToBasePositioningSubtable *) lookupSubtable;
+        LEReferenceTo<MarkToBasePositioningSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
      case gpstMarkToLigature:
     {
-        const MarkToLigaturePositioningSubtable *subtable = (const MarkToLigaturePositioningSubtable *) lookupSubtable;
+        LEReferenceTo<MarkToLigaturePositioningSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
     case gpstMarkToMark:
     {
-        const MarkToMarkPositioningSubtable *subtable = (const MarkToMarkPositioningSubtable *) lookupSubtable;
+        LEReferenceTo<MarkToMarkPositioningSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fontInstance);
+        delta = subtable->process(subtable, glyphIterator, fontInstance, success);
         break;
     }
 
    case gpstContext:
     {
-        const ContextualPositioningSubtable *subtable = (const ContextualPositioningSubtable *) lookupSubtable;
+        LEReferenceTo<ContextualPositioningSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, glyphIterator, fontInstance, success);
         break;
@@ -158,7 +158,7 @@
 
     case gpstChainedContext:
     {
-        const ChainingContextualPositioningSubtable *subtable = (const ChainingContextualPositioningSubtable *) lookupSubtable;
+        LEReferenceTo<ChainingContextualPositioningSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, glyphIterator, fontInstance, success);
         break;
@@ -166,7 +166,7 @@
 
     case gpstExtension:
     {
-        const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable;
+        LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
         break;
--- a/src/share/native/sun/font/layout/GlyphPosnLookupProc.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphPosnLookupProc.h	Thu Apr 18 14:38:37 2013 -0700
@@ -51,7 +51,7 @@
 class GlyphPositioningLookupProcessor : public LookupProcessor
 {
 public:
-    GlyphPositioningLookupProcessor(const GlyphPositioningTableHeader *glyphPositioningTableHeader,
+    GlyphPositioningLookupProcessor(const LEReferenceTo<GlyphPositioningTableHeader> &glyphPositioningTableHeader,
         LETag scriptTag,
         LETag languageTag,
         const FeatureMap *featureMap,
@@ -61,7 +61,7 @@
 
     virtual ~GlyphPositioningLookupProcessor();
 
-    virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
+    virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
         const LEFontInstance *fontInstance, LEErrorCode& success) const;
 
 protected:
--- a/src/share/native/sun/font/layout/GlyphSubstLookupProc.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphSubstLookupProc.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -51,7 +51,7 @@
 U_NAMESPACE_BEGIN
 
 GlyphSubstitutionLookupProcessor::GlyphSubstitutionLookupProcessor(
-        const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader,
+        const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader,
         LETag scriptTag,
         LETag languageTag,
         const LEGlyphFilter *filter,
@@ -60,7 +60,7 @@
         le_bool featureOrder,
         LEErrorCode& success)
     : LookupProcessor(
-                      (char *) glyphSubstitutionTableHeader,
+                      glyphSubstitutionTableHeader,
                       SWAPW(glyphSubstitutionTableHeader->scriptListOffset),
                       SWAPW(glyphSubstitutionTableHeader->featureListOffset),
                       SWAPW(glyphSubstitutionTableHeader->lookupListOffset),
@@ -73,7 +73,7 @@
 {
 }
 
-le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType,
+le_uint32 GlyphSubstitutionLookupProcessor::applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType,
                                                        GlyphIterator *glyphIterator, const LEFontInstance *fontInstance, LEErrorCode& success) const
 {
     if (LE_FAILURE(success)) {
@@ -89,39 +89,39 @@
 
     case gsstSingle:
     {
-        const SingleSubstitutionSubtable *subtable = (const SingleSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<SingleSubstitutionSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fFilter);
+        delta = subtable->process(subtable, glyphIterator, success, fFilter);
         break;
     }
 
     case gsstMultiple:
     {
-        const MultipleSubstitutionSubtable *subtable = (const MultipleSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<MultipleSubstitutionSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, success, fFilter);
+        delta = subtable->process(subtable, glyphIterator, success, fFilter);
         break;
     }
 
     case gsstAlternate:
     {
-        const AlternateSubstitutionSubtable *subtable = (const AlternateSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<AlternateSubstitutionSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fFilter);
+        delta = subtable->process(subtable, glyphIterator, success, fFilter);
         break;
     }
 
     case gsstLigature:
     {
-        const LigatureSubstitutionSubtable *subtable = (const LigatureSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<LigatureSubstitutionSubtable> subtable(lookupSubtable, success);
 
-        delta = subtable->process(glyphIterator, fFilter);
+        delta = subtable->process(subtable, glyphIterator, success, fFilter);
         break;
     }
 
     case gsstContext:
     {
-        const ContextualSubstitutionSubtable *subtable = (const ContextualSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<ContextualSubstitutionSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, glyphIterator, fontInstance, success);
         break;
@@ -129,7 +129,7 @@
 
     case gsstChainingContext:
     {
-        const ChainingContextualSubstitutionSubtable *subtable = (const ChainingContextualSubstitutionSubtable *) lookupSubtable;
+        const LEReferenceTo<ChainingContextualSubstitutionSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, glyphIterator, fontInstance, success);
         break;
@@ -137,7 +137,7 @@
 
     case gsstExtension:
     {
-        const ExtensionSubtable *subtable = (const ExtensionSubtable *) lookupSubtable;
+        const LEReferenceTo<ExtensionSubtable> subtable(lookupSubtable, success);
 
         delta = subtable->process(this, lookupType, glyphIterator, fontInstance, success);
         break;
--- a/src/share/native/sun/font/layout/GlyphSubstLookupProc.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphSubstLookupProc.h	Thu Apr 18 14:38:37 2013 -0700
@@ -52,7 +52,7 @@
 class GlyphSubstitutionLookupProcessor : public LookupProcessor
 {
 public:
-    GlyphSubstitutionLookupProcessor(const GlyphSubstitutionTableHeader *glyphSubstitutionTableHeader,
+    GlyphSubstitutionLookupProcessor(const LEReferenceTo<GlyphSubstitutionTableHeader> &glyphSubstitutionTableHeader,
         LETag scriptTag,
         LETag languageTag,
         const LEGlyphFilter *filter,
@@ -63,7 +63,7 @@
 
     virtual ~GlyphSubstitutionLookupProcessor();
 
-    virtual le_uint32 applySubtable(const LookupSubtable *lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
+    virtual le_uint32 applySubtable(const LEReferenceTo<LookupSubtable> &lookupSubtable, le_uint16 lookupType, GlyphIterator *glyphIterator,
         const LEFontInstance *fontInstance, LEErrorCode& success) const;
 
 protected:
--- a/src/share/native/sun/font/layout/GlyphSubstitutionTables.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphSubstitutionTables.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -42,11 +42,12 @@
 
 U_NAMESPACE_BEGIN
 
-le_int32 GlyphSubstitutionTableHeader::process(LEGlyphStorage &glyphStorage,
+le_int32 GlyphSubstitutionTableHeader::process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base,
+                                               LEGlyphStorage &glyphStorage,
                                                le_bool rightToLeft,
                                                LETag scriptTag,
                                                LETag languageTag,
-                                           const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
+                                               const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
                                                const LEGlyphFilter *filter,
                                                const FeatureMap *featureMap,
                                                le_int32 featureMapCount,
@@ -57,7 +58,7 @@
         return 0;
     }
 
-    GlyphSubstitutionLookupProcessor processor(this, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder, success);
+    GlyphSubstitutionLookupProcessor processor(base, scriptTag, languageTag, filter, featureMap, featureMapCount, featureOrder, success);
     return processor.process(glyphStorage, NULL, rightToLeft, glyphDefinitionTableHeader, NULL, success);
 }
 
--- a/src/share/native/sun/font/layout/GlyphSubstitutionTables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/GlyphSubstitutionTables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -50,11 +50,12 @@
 
 struct GlyphSubstitutionTableHeader : public GlyphLookupTableHeader
 {
-    le_int32    process(LEGlyphStorage &glyphStorage,
+  le_int32    process(const LEReferenceTo<GlyphSubstitutionTableHeader> &base,
+                      LEGlyphStorage &glyphStorage,
                         le_bool rightToLeft,
                         LETag scriptTag,
                         LETag languageTag,
-                        const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
+                        const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
                         const LEGlyphFilter *filter,
                         const FeatureMap *featureMap,
                         le_int32 featureMapCount,
--- a/src/share/native/sun/font/layout/HanLayoutEngine.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/HanLayoutEngine.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -64,7 +64,7 @@
 #define features (loclFeatureMask)
 
 HanOpenTypeLayoutEngine::HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                        le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+                                                 le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
 {
     fFeatureMap      = featureMap;
--- a/src/share/native/sun/font/layout/HanLayoutEngine.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/HanLayoutEngine.h	Thu Apr 18 14:38:37 2013 -0700
@@ -73,7 +73,7 @@
      * @internal
      */
     HanOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTablem, LEErrorCode &success);
+                            le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTablem, LEErrorCode &success);
 
 
     /**
--- a/src/share/native/sun/font/layout/HangulLayoutEngine.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/HangulLayoutEngine.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -209,7 +209,7 @@
 }
 
 HangulOpenTypeLayoutEngine::HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 /*languageCode*/,
-                                       le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+                                                       le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, korLanguageCode, typoFlags, gsubTable, success)
 {
     fFeatureMap = featureMap;
--- a/src/share/native/sun/font/layout/HangulLayoutEngine.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/HangulLayoutEngine.h	Thu Apr 18 14:38:37 2013 -0700
@@ -79,7 +79,7 @@
      * @internal
      */
     HangulOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
+                               le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
 
     /**
      * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/ICUFeatures.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/ICUFeatures.h	Thu Apr 18 14:38:37 2013 -0700
@@ -54,16 +54,21 @@
     le_uint16   lookupCount;
     le_uint16   lookupListIndexArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(FeatureTable, lookupListIndexArray)
 
 struct FeatureListTable
 {
     le_uint16           featureCount;
     FeatureRecord       featureRecordArray[ANY_NUMBER];
 
-    const FeatureTable  *getFeatureTable(le_uint16 featureIndex, LETag *featureTag) const;
+  LEReferenceTo<FeatureTable>  getFeatureTable(const LETableReference &base, le_uint16 featureIndex, LETag *featureTag, LEErrorCode &success) const;
 
-    const FeatureTable *getFeatureTable(LETag featureTag) const;
+#if 0
+  const LEReferenceTo<FeatureTable>  getFeatureTable(const LETableReference &base, LETag featureTag, LEErrorCode &success) const;
+#endif
 };
 
+LE_VAR_ARRAY(FeatureListTable, featureRecordArray)
+
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/IndicClassTables.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/IndicClassTables.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -186,13 +186,15 @@
 };
 
 // FIXME: Should some of the bb's be pb's? (KA, NA, MA, YA, VA, etc. (approx 13))
+// U+C43 and U+C44 are _lm here not _dr.  Similar to the situation with U+CC3 and
+// U+CC4 in Kannada below.
 static const IndicClassTable::CharClass teluCharClasses[] =
 {
     _xx, _mp, _mp, _mp, _xx, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _iv, _xx, _iv, _iv, // 0C00 - 0C0F
     _iv, _xx, _iv, _iv, _iv, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, // 0C10 - 0C1F
     _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _bb, // 0C20 - 0C2F
     _bb, _bb, _bb, _bb, _xx, _bb, _bb, _bb, _bb, _bb, _xx, _xx, _xx, _xx, _da, _da, // 0C30 - 0C3F
-    _da, _dr, _dr, _dr, _dr, _xx, _a1, _da, _s1, _xx, _da, _da, _da, _vr, _xx, _xx, // 0C40 - 0C4F
+    _da, _dr, _dr, _lm, _lm, _xx, _a1, _da, _s1, _xx, _da, _da, _da, _vr, _xx, _xx, // 0C40 - 0C4F
     _xx, _xx, _xx, _xx, _xx, _da, _m2, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, // 0C50 - 0C5F
     _iv, _iv, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx  // 0C60 - 0C6F
 };
--- a/src/share/native/sun/font/layout/IndicLayoutEngine.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/IndicLayoutEngine.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -50,7 +50,7 @@
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicOpenTypeLayoutEngine)
 
 IndicOpenTypeLayoutEngine::IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                    le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+                                                     le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success), fMPreFixups(NULL)
 {
         if ( version2 ) {
--- a/src/share/native/sun/font/layout/IndicLayoutEngine.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/IndicLayoutEngine.h	Thu Apr 18 14:38:37 2013 -0700
@@ -81,7 +81,7 @@
      * @internal
      */
     IndicOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, le_bool version2, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
+                            le_int32 typoFlags, le_bool version2, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
 
     /**
      * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/IndicRearrangement.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/IndicRearrangement.h	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -49,6 +49,10 @@
 {
 };
 
+struct IndicRearrangementSubtableHeader2 : MorphStateTableHeader2
+{
+};
+
 enum IndicRearrangementFlags
 {
     irfMarkFirst    = 0x8000,
@@ -85,6 +89,10 @@
 {
 };
 
+struct IndicRearrangementStateEntry2 : StateEntry2
+{
+};
+
 U_NAMESPACE_END
 #endif
 
--- a/src/share/native/sun/font/layout/IndicRearrangementProcessor.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -43,11 +43,14 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor)
 
-IndicRearrangementProcessor::IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader)
-  : StateTableProcessor(morphSubtableHeader)
+  IndicRearrangementProcessor::IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor(morphSubtableHeader, success),
+  indicRearrangementSubtableHeader(morphSubtableHeader, success),
+  entryTable(stateTableHeader, success, (const IndicRearrangementStateEntry*)(&stateTableHeader->stHeader),
+             entryTableOffset, LE_UNBOUNDED_ARRAY),
+  int16Table(stateTableHeader, success, (const le_int16*)entryTable.getAlias(), 0, LE_UNBOUNDED_ARRAY)
+
 {
-    indicRearrangementSubtableHeader = (const IndicRearrangementSubtableHeader *) morphSubtableHeader;
-    entryTable = (const IndicRearrangementStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
 }
 
 IndicRearrangementProcessor::~IndicRearrangementProcessor()
@@ -62,7 +65,8 @@
 
 ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
 {
-    const IndicRearrangementStateEntry *entry = &entryTable[index];
+  LEErrorCode success = LE_NO_ERROR; // todo- make a param?
+  const IndicRearrangementStateEntry *entry = entryTable.getAlias(index,success);
     ByteOffset newState = SWAPW(entry->newStateOffset);
     IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
 
--- a/src/share/native/sun/font/layout/IndicRearrangementProcessor.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor.h	Thu Apr 18 14:38:37 2013 -0700
@@ -58,7 +58,7 @@
 
     void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const;
 
-    IndicRearrangementProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    IndicRearrangementProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
     virtual ~IndicRearrangementProcessor();
 
     /**
@@ -79,8 +79,9 @@
     le_int32 firstGlyph;
     le_int32 lastGlyph;
 
-    const IndicRearrangementStateEntry *entryTable;
-    const IndicRearrangementSubtableHeader *indicRearrangementSubtableHeader;
+    LEReferenceTo<IndicRearrangementSubtableHeader> indicRearrangementSubtableHeader;
+    LEReferenceToArrayOf<IndicRearrangementStateEntry> entryTable;
+    LEReferenceToArrayOf<le_int16> int16Table;
 
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor2.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,425 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "StateTables.h"
+#include "MorphStateTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "IndicRearrangementProcessor2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(IndicRearrangementProcessor2)
+
+IndicRearrangementProcessor2::IndicRearrangementProcessor2(
+      const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor2(morphSubtableHeader, success), indicRearrangementSubtableHeader(morphSubtableHeader, success),
+  entryTable(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY)
+{
+}
+
+IndicRearrangementProcessor2::~IndicRearrangementProcessor2()
+{
+}
+
+void IndicRearrangementProcessor2::beginStateTable()
+{
+    firstGlyph = 0;
+    lastGlyph = 0;
+}
+
+le_uint16 IndicRearrangementProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
+                                                          EntryTableIndex2 index, LEErrorCode &success)
+{
+    const IndicRearrangementStateEntry2 *entry = entryTable.getAlias(index, success);
+    if (LE_FAILURE(success)) return 0; // TODO - what to return in bad state?
+    le_uint16 newState = SWAPW(entry->newStateIndex); // index to the new state
+    IndicRearrangementFlags  flags =  (IndicRearrangementFlags) SWAPW(entry->flags);
+
+    if (flags & irfMarkFirst) {
+        firstGlyph = currGlyph;
+    }
+
+    if (flags & irfMarkLast) {
+        lastGlyph = currGlyph;
+    }
+
+    doRearrangementAction(glyphStorage, (IndicRearrangementVerb) (flags & irfVerbMask));
+
+    if (!(flags & irfDontAdvance)) {
+        currGlyph += dir;
+    }
+
+    return newState; // index to new state
+}
+
+void IndicRearrangementProcessor2::endStateTable()
+{
+}
+
+void IndicRearrangementProcessor2::doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const
+{
+    LEGlyphID a, b, c, d;
+    le_int32 ia, ib, ic, id, ix, x;
+    LEErrorCode success = LE_NO_ERROR;
+
+    switch(verb)
+    {
+    case irvNoAction:
+        break;
+
+    case irvxA:
+        a = glyphStorage[firstGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        x = firstGlyph + 1;
+
+        while (x <= lastGlyph) {
+            glyphStorage[x - 1] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x - 1, ix, success);
+            x += 1;
+        }
+
+        glyphStorage[lastGlyph] = a;
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvDx:
+        d = glyphStorage[lastGlyph];
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = lastGlyph - 1;
+
+        while (x >= firstGlyph) {
+            glyphStorage[x + 1] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x + 1, ix, success);
+            x -= 1;
+        }
+
+        glyphStorage[firstGlyph] = d;
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        break;
+
+    case irvDxA:
+        a = glyphStorage[firstGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        id = glyphStorage.getCharIndex(lastGlyph,  success);
+
+        glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
+        glyphStorage[lastGlyph] = a;
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(lastGlyph,  ia, success);
+        break;
+
+    case irvxAB:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        x = firstGlyph + 2;
+
+        while (x <= lastGlyph) {
+            glyphStorage[x - 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x - 2, ix, success);
+            x += 1;
+        }
+
+        glyphStorage[lastGlyph - 1] = a;
+        glyphStorage[lastGlyph] = b;
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
+        glyphStorage.setCharIndex(lastGlyph, ib, success);
+        break;
+
+    case irvxBA:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        x = firstGlyph + 2;
+
+        while (x <= lastGlyph) {
+            glyphStorage[x - 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x - 2, ix, success);
+            x += 1;
+        }
+
+        glyphStorage[lastGlyph - 1] = b;
+        glyphStorage[lastGlyph] = a;
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvCDx:
+        c = glyphStorage[lastGlyph - 1];
+        d = glyphStorage[lastGlyph];
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = lastGlyph - 2;
+
+        while (x >= firstGlyph) {
+            glyphStorage[x + 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x + 2, ix, success);
+            x -= 1;
+        }
+
+        glyphStorage[firstGlyph] = c;
+        glyphStorage[firstGlyph + 1] = d;
+
+        glyphStorage.setCharIndex(firstGlyph, ic, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
+        break;
+
+    case irvDCx:
+        c = glyphStorage[lastGlyph - 1];
+        d = glyphStorage[lastGlyph];
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = lastGlyph - 2;
+
+        while (x >= firstGlyph) {
+            glyphStorage[x + 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x + 2, ix, success);
+            x -= 1;
+        }
+
+        glyphStorage[firstGlyph] = d;
+        glyphStorage[firstGlyph + 1] = c;
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
+        break;
+
+    case irvCDxA:
+        a = glyphStorage[firstGlyph];
+        c = glyphStorage[lastGlyph - 1];
+        d = glyphStorage[lastGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = lastGlyph - 2;
+
+        while (x > firstGlyph) {
+            glyphStorage[x + 1] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x + 1, ix, success);
+            x -= 1;
+        }
+
+        glyphStorage[firstGlyph] = c;
+        glyphStorage[firstGlyph + 1] = d;
+        glyphStorage[lastGlyph] = a;
+
+        glyphStorage.setCharIndex(firstGlyph, ic, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvDCxA:
+        a = glyphStorage[firstGlyph];
+        c = glyphStorage[lastGlyph - 1];
+        d = glyphStorage[lastGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = lastGlyph - 2;
+
+        while (x > firstGlyph) {
+            glyphStorage[x + 1] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x + 1, ix, success);
+            x -= 1;
+        }
+
+        glyphStorage[firstGlyph] = d;
+        glyphStorage[firstGlyph + 1] = c;
+        glyphStorage[lastGlyph] = a;
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvDxAB:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+        d = glyphStorage[lastGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = firstGlyph + 2;
+
+        while (x < lastGlyph) {
+            glyphStorage[x - 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x - 2, ix, success);
+            x += 1;
+        }
+
+        glyphStorage[firstGlyph] = d;
+        glyphStorage[lastGlyph - 1] = a;
+        glyphStorage[lastGlyph] = b;
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
+        glyphStorage.setCharIndex(lastGlyph, ib, success);
+        break;
+
+    case irvDxBA:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+        d = glyphStorage[lastGlyph];
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+        x = firstGlyph + 2;
+
+        while (x < lastGlyph) {
+            glyphStorage[x - 2] = glyphStorage[x];
+            ix = glyphStorage.getCharIndex(x, success);
+            glyphStorage.setCharIndex(x - 2, ix, success);
+            x += 1;
+        }
+
+        glyphStorage[firstGlyph] = d;
+        glyphStorage[lastGlyph - 1] = b;
+        glyphStorage[lastGlyph] = a;
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvCDxAB:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+
+        glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
+        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
+
+        glyphStorage[lastGlyph - 1] = a;
+        glyphStorage[lastGlyph] = b;
+
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+
+        glyphStorage.setCharIndex(firstGlyph, ic, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
+        glyphStorage.setCharIndex(lastGlyph, ib, success);
+        break;
+
+    case irvCDxBA:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+
+        glyphStorage[firstGlyph] = glyphStorage[lastGlyph - 1];
+        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph];
+
+        glyphStorage[lastGlyph - 1] = b;
+        glyphStorage[lastGlyph] = a;
+
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+
+        glyphStorage.setCharIndex(firstGlyph, ic, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, id, success);
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    case irvDCxAB:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+
+        glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
+        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
+
+        glyphStorage[lastGlyph - 1] = a;
+        glyphStorage[lastGlyph] = b;
+
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ia, success);
+        glyphStorage.setCharIndex(lastGlyph, ib, success);
+        break;
+
+    case irvDCxBA:
+        a = glyphStorage[firstGlyph];
+        b = glyphStorage[firstGlyph + 1];
+
+        glyphStorage[firstGlyph] = glyphStorage[lastGlyph];
+        glyphStorage[firstGlyph + 1] = glyphStorage[lastGlyph - 1];
+
+        glyphStorage[lastGlyph - 1] = b;
+        glyphStorage[lastGlyph] = a;
+
+        ia = glyphStorage.getCharIndex(firstGlyph, success);
+        ib = glyphStorage.getCharIndex(firstGlyph + 1, success);
+        ic = glyphStorage.getCharIndex(lastGlyph - 1, success);
+        id = glyphStorage.getCharIndex(lastGlyph, success);
+
+        glyphStorage.setCharIndex(firstGlyph, id, success);
+        glyphStorage.setCharIndex(firstGlyph + 1, ic, success);
+
+        glyphStorage.setCharIndex(lastGlyph - 1, ib, success);
+        glyphStorage.setCharIndex(lastGlyph, ia, success);
+        break;
+
+    default:
+        break;
+    }
+
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/IndicRearrangementProcessor2.h	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __INDICREARRANGEMENTPROCESSOR2_H
+#define __INDICREARRANGEMENTPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor.h"
+#include "StateTableProcessor2.h"
+#include "IndicRearrangement.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+class IndicRearrangementProcessor2 : public StateTableProcessor2
+{
+public:
+    virtual void beginStateTable();
+
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success);
+
+    virtual void endStateTable();
+
+    void doRearrangementAction(LEGlyphStorage &glyphStorage, IndicRearrangementVerb verb) const;
+
+    IndicRearrangementProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
+    virtual ~IndicRearrangementProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+protected:
+    le_int32 firstGlyph;
+    le_int32 lastGlyph;
+
+    LEReferenceToArrayOf<IndicRearrangementStateEntry2> entryTable;
+    LEReferenceTo<IndicRearrangementSubtableHeader2> indicRearrangementSubtableHeader;
+
+};
+
+U_NAMESPACE_END
+#endif
--- a/src/share/native/sun/font/layout/IndicReordering.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/IndicReordering.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -266,7 +266,7 @@
                                         le_uint32 saveAuxData = fGlyphStorage.getAuxData(i+inv_count,success);
                     const SplitMatra *splitMatra = classTable->getSplitMatra(matraClass);
                     int j;
-                    for (j = 0 ; *(splitMatra)[j] != 0 ; j++) {
+                    for (j = 0 ; j < SM_MAX_PIECES && *(splitMatra)[j] != 0 ; j++) {
                         LEUnicode piece = (*splitMatra)[j];
                                                 if ( j == 0 ) {
                                                         fOutChars[i+inv_count] = piece;
@@ -357,7 +357,7 @@
                 const SplitMatra *splitMatra = classTable->getSplitMatra(matraClass);
                 int i;
 
-                for (i = 0; i < 3 && (*splitMatra)[i] != 0; i += 1) {
+                for (i = 0; i < SM_MAX_PIECES && (*splitMatra)[i] != 0; i += 1) {
                     LEUnicode piece = (*splitMatra)[i];
                     IndicClassTable::CharClass pieceClass = classTable->getCharClass(piece);
 
@@ -658,6 +658,11 @@
     MPreFixups *mpreFixups = NULL;
     const IndicClassTable *classTable = IndicClassTable::getScriptClassTable(scriptCode);
 
+    if(classTable==NULL) {
+      success = LE_MEMORY_ALLOCATION_ERROR;
+      return 0;
+    }
+
     if (classTable->scriptFlags & SF_MPRE_FIXUP) {
         mpreFixups = new MPreFixups(charCount);
         if (mpreFixups == NULL) {
@@ -1224,7 +1229,6 @@
 
 
     LEUnicode currentChar;
-    LEUnicode virama;
     LEUnicode workChars[2];
     LEGlyphStorage workGlyphs;
 
@@ -1232,14 +1236,17 @@
 
     //le_int32 offset = 0;
 
+#if 0
+// TODO:  Should this section of code have actually been doing something?
     // First find the relevant virama for the script we are dealing with
-
+    LEUnicode virama;
     for ( currentChar = classTable->firstChar ; currentChar <= classTable->lastChar ; currentChar++ ) {
         if ( classTable->isVirama(currentChar)) {
             virama = currentChar;
             break;
         }
     }
+#endif
 
     for ( currentChar = classTable->firstChar ; currentChar <= classTable->lastChar ; currentChar++ ) {
         if ( classTable->isConsonant(currentChar)) {
--- a/src/share/native/sun/font/layout/IndicReordering.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/IndicReordering.h	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2009 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -96,7 +96,9 @@
 #define SF_POST_BASE_LIMIT_MASK  0x0000FFFFU
 #define SF_NO_POST_BASE_LIMIT    0x00007FFFU
 
-typedef LEUnicode SplitMatra[3];
+#define SM_MAX_PIECES 3
+
+typedef LEUnicode SplitMatra[SM_MAX_PIECES];
 
 class MPreFixups;
 class LEGlyphStorage;
--- a/src/share/native/sun/font/layout/KernTable.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/KernTable.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -48,7 +48,7 @@
   le_int16  value; // fword, kern value in funits
 };
 #define KERN_PAIRINFO_SIZE 6
-
+LE_CORRECT_SIZE(PairInfo, KERN_PAIRINFO_SIZE)
 struct Subtable_0 {
   le_uint16 nPairs;
   le_uint16 searchRange;
@@ -56,6 +56,7 @@
   le_uint16 rangeShift;
 };
 #define KERN_SUBTABLE_0_HEADER_SIZE 8
+LE_CORRECT_SIZE(Subtable_0, KERN_SUBTABLE_0_HEADER_SIZE)
 
 // Kern table version 0 only
 struct SubtableHeader {
@@ -64,6 +65,7 @@
   le_uint16 coverage;
 };
 #define KERN_SUBTABLE_HEADER_SIZE 6
+LE_CORRECT_SIZE(SubtableHeader, KERN_SUBTABLE_HEADER_SIZE)
 
 // Version 0 only, version 1 has different layout
 struct KernTableHeader {
@@ -71,6 +73,7 @@
   le_uint16 nTables;
 };
 #define KERN_TABLE_HEADER_SIZE 4
+LE_CORRECT_SIZE(KernTableHeader, KERN_TABLE_HEADER_SIZE)
 
 #define COVERAGE_HORIZONTAL 0x1
 #define COVERAGE_MINIMUM 0x2
@@ -92,21 +95,21 @@
  * TODO: support multiple subtables
  * TODO: respect header flags
  */
-KernTable::KernTable(const LEFontInstance* font_, const void* tableData)
-  : pairs(0), font(font_)
+KernTable::KernTable(const LETableReference& base, LEErrorCode &success)
+  : pairs(), pairsSwapped(NULL), fTable(base)
 {
-  const KernTableHeader* header = (const KernTableHeader*)tableData;
-  if (header == 0) {
+  if(LE_FAILURE(success) || (fTable.isEmpty())) {
 #if DEBUG
     fprintf(stderr, "no kern data\n");
 #endif
     return;
   }
+  LEReferenceTo<KernTableHeader> header(fTable, success);
 
 #if DEBUG
   // dump first 32 bytes of header
   for (int i = 0; i < 64; ++i) {
-    fprintf(stderr, "%0.2x ", ((const char*)tableData)[i]&0xff);
+    fprintf(stderr, "%0.2x ", ((const char*)header.getAlias())[i]&0xff);
     if (((i+1)&0xf) == 0) {
       fprintf(stderr, "\n");
     } else if (((i+1)&0x7) == 0) {
@@ -115,12 +118,17 @@
   }
 #endif
 
-  if (header->version == 0 && SWAPW(header->nTables) > 0) {
-    const SubtableHeader* subhead = (const SubtableHeader*)((char*)tableData + KERN_TABLE_HEADER_SIZE);
-    if (subhead->version == 0) {
+  if(LE_FAILURE(success)) return;
+
+  if (!header.isEmpty() && header->version == 0 && SWAPW(header->nTables) > 0) {
+    LEReferenceTo<SubtableHeader> subhead(header, success, KERN_TABLE_HEADER_SIZE);
+
+    if (LE_SUCCESS(success) && !subhead.isEmpty() && subhead->version == 0) {
       coverage = SWAPW(subhead->coverage);
       if (coverage & COVERAGE_HORIZONTAL) { // only handle horizontal kerning
-        const Subtable_0* table = (const Subtable_0*)((char*)subhead + KERN_SUBTABLE_HEADER_SIZE);
+        LEReferenceTo<Subtable_0> table(subhead, success, KERN_SUBTABLE_HEADER_SIZE);
+
+        if(table.isEmpty() || LE_FAILURE(success)) return;
 
         nPairs        = SWAPW(table->nPairs);
 
@@ -134,19 +142,31 @@
         rangeShift    = (nPairs * KERN_PAIRINFO_SIZE) - searchRange;
 #endif
 
-        pairs = (PairInfo*)font->getKernPairs();
-        if (pairs == NULL) {
-            char *pairData = (char*)table + KERN_SUBTABLE_0_HEADER_SIZE;
-            char *pptr = pairData;
-            pairs =  (PairInfo*)(malloc(nPairs*sizeof(PairInfo)));
-            PairInfo *p = (PairInfo*)pairs;
-            for (int i = 0; i < nPairs; i++, pptr += KERN_PAIRINFO_SIZE, p++) {
-              memcpy(p, pptr, KERN_PAIRINFO_SIZE);
+        if(LE_SUCCESS(success) && nPairs>0) {
+          // pairs is an instance member, and table is on the stack.
+          // set 'pairs' based on table.getAlias(). This will range check it.
+
+          pairs = LEReferenceToArrayOf<PairInfo>(fTable, // based on overall table
+                                                 success,
+                                                 (const PairInfo*)table.getAlias(),  // subtable 0 + ..
+                                                 KERN_SUBTABLE_0_HEADER_SIZE,  // .. offset of header size
+                                                 nPairs); // count
+        }
+        if (LE_SUCCESS(success) && pairs.isValid()) {
+            pairsSwapped =  (PairInfo*)(malloc(nPairs*sizeof(PairInfo)));
+            PairInfo *p = (PairInfo*)pairsSwapped;
+            for (int i = 0; LE_SUCCESS(success) && i < nPairs; i++, p++) {
+              memcpy(p, pairs.getAlias(i,success), KERN_PAIRINFO_SIZE);
               p->key = SWAPL(p->key);
             }
-            font->setKernPairs((void*)pairs);
+            fTable.getFont()->setKernPairs((void*)pairsSwapped); // store it
         }
 
+#if 0
+        fprintf(stderr, "coverage: %0.4x nPairs: %d pairs %p\n", coverage, nPairs, pairs.getAlias());
+        fprintf(stderr, "  searchRange: %d entrySelector: %d rangeShift: %d\n", searchRange, entrySelector, rangeShift);
+        fprintf(stderr, "[[ ignored font table entries: range %d selector %d shift %d ]]\n", SWAPW(table->searchRange), SWAPW(table->entrySelector), SWAPW(table->rangeShift));
+#endif
 #if DEBUG
         fprintf(stderr, "coverage: %0.4x nPairs: %d pairs 0x%x\n", coverage, nPairs, pairs);
         fprintf(stderr,
@@ -194,14 +214,17 @@
  * Process the glyph positions.  The positions array has two floats for each
  * glyph, plus a trailing pair to mark the end of the last glyph.
  */
-void KernTable::process(LEGlyphStorage& storage)
+void KernTable::process(LEGlyphStorage& storage, LEErrorCode &success)
 {
-  if (pairs) {
-    LEErrorCode success = LE_NO_ERROR;
+  if(LE_FAILURE(success)) return;
+
+  if (pairsSwapped) {
+    success = LE_NO_ERROR;
 
     le_uint32 key = storage[0]; // no need to mask off high bits
     float adjust = 0;
-    for (int i = 1, e = storage.getGlyphCount(); i < e; ++i) {
+
+    for (int i = 1, e = storage.getGlyphCount(); LE_SUCCESS(success)&&  i < e; ++i) {
       key = key << 16 | (storage[i] & 0xffff);
 
       // argh, to do a binary search, we need to have the pair list in sorted order
@@ -209,7 +232,7 @@
       // so either I have to swap the element each time I examine it, or I have to swap
       // all the elements ahead of time and store them in the font
 
-      const PairInfo* p = pairs;
+      const PairInfo* p = pairsSwapped;
       const PairInfo* tp = (const PairInfo*)(p + (rangeShift/KERN_PAIRINFO_SIZE)); /* rangeshift is in original table bytes */
       if (key > tp->key) {
         p = tp;
@@ -225,7 +248,7 @@
         tp = (const PairInfo*)(p + (probe/KERN_PAIRINFO_SIZE));
         le_uint32 tkey = tp->key;
 #if DEBUG
-        fprintf(stdout, "   %.3d (%0.8x)\n", (tp - pairs), tkey);
+        fprintf(stdout, "   %.3d (%0.8x)\n", (tp - pairsSwapped), tkey);
 #endif
         if (tkey <= key) {
           if (tkey == key) {
@@ -240,10 +263,10 @@
             // device transform, or a faster way, such as moving the
             // entire kern table up to Java.
             LEPoint pt;
-            pt.fX = font->xUnitsToPoints(value);
+            pt.fX = fTable.getFont()->xUnitsToPoints(value);
             pt.fY = 0;
 
-            font->getKerningAdjustment(pt);
+            fTable.getFont()->getKerningAdjustment(pt);
             adjust += pt.fX;
             break;
           }
--- a/src/share/native/sun/font/layout/KernTable.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/KernTable.h	Thu Apr 18 14:38:37 2013 -0700
@@ -26,7 +26,7 @@
 /*
  *
  *
- * (C) Copyright IBM Corp. 2004-2005 - All Rights Reserved
+ * (C) Copyright IBM Corp. 2004-2013 - All Rights Reserved
  *
  */
 
@@ -38,6 +38,7 @@
 #endif
 
 #include "LETypes.h"
+#include "LETableReference.h"
 //#include "LEFontInstance.h"
 //#include "LEGlyphStorage.h"
 
@@ -56,19 +57,20 @@
  private:
   le_uint16 coverage;
   le_uint16 nPairs;
-  const PairInfo* pairs;
-  const LEFontInstance* font;
+  LEReferenceToArrayOf<PairInfo> pairs;
+  PairInfo  *pairsSwapped;
+  const LETableReference &fTable;
   le_uint16 searchRange;
   le_uint16 entrySelector;
   le_uint16 rangeShift;
 
  public:
-  KernTable(const LEFontInstance* font, const void* tableData);
+  KernTable(const LETableReference &table, LEErrorCode &success);
 
   /*
    * Process the glyph positions.
    */
-  void process(LEGlyphStorage& storage);
+  void process(LEGlyphStorage& storage, LEErrorCode &success);
 };
 
 U_NAMESPACE_END
--- a/src/share/native/sun/font/layout/KhmerLayoutEngine.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/KhmerLayoutEngine.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -43,7 +43,7 @@
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(KhmerOpenTypeLayoutEngine)
 
 KhmerOpenTypeLayoutEngine::KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                    le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success)
+                                                     le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success)
     : OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success)
 {
     fFeatureMap   = KhmerReordering::getFeatureMap(fFeatureMapCount);
--- a/src/share/native/sun/font/layout/KhmerLayoutEngine.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/KhmerLayoutEngine.h	Thu Apr 18 14:38:37 2013 -0700
@@ -83,7 +83,7 @@
      * @internal
      */
     KhmerOpenTypeLayoutEngine(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode,
-                            le_int32 typoFlags, const GlyphSubstitutionTableHeader *gsubTable, LEErrorCode &success);
+                            le_int32 typoFlags, const LEReferenceTo<GlyphSubstitutionTableHeader> &gsubTable, LEErrorCode &success);
 
     /**
      * This constructor is used when the font requires a "canned" GSUB table which can't be known
--- a/src/share/native/sun/font/layout/LEFontInstance.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LEFontInstance.h	Thu Apr 18 14:38:37 2013 -0700
@@ -190,6 +190,25 @@
      */
     virtual const void *getFontTable(LETag tableTag) const = 0;
 
+    /**
+     * This method reads a table from the font. Note that in general,
+     * it only makes sense to call this method on an <code>LEFontInstance</code>
+     * which represents a physical font - i.e. one which has been returned by
+     * <code>getSubFont()</code>. This is because each subfont in a composite font
+     * will have different tables, and there's no way to know which subfont to access.
+     *
+     * Subclasses which represent composite fonts should always return <code>NULL</code>.
+     *
+     * This version sets a length, for range checking.
+     *
+     * @param tableTag - the four byte table tag. (e.g. 'cmap')
+     * @param length - ignored on entry, on exit will be the length of the table if known, or -1 if unknown.
+     * @return the address of the table in memory, or <code>NULL</code>
+     *         if the table doesn't exist.
+     * @internal
+     */
+    virtual const void* getFontTable(LETag tableTag, size_t &length) const { length=-1; return getFontTable(tableTag); }  /* -1 = unknown length */
+
     virtual void *getKernPairs() const = 0;
     virtual void  setKernPairs(void *pairs) const = 0;
 
--- a/src/share/native/sun/font/layout/LEGlyphFilter.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LEGlyphFilter.h	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -36,6 +36,7 @@
 
 U_NAMESPACE_BEGIN
 
+#ifndef U_HIDE_INTERNAL_API
 /**
  * This is a helper class that is used to
  * recognize a set of glyph indices.
@@ -63,6 +64,7 @@
      */
     virtual le_bool accept(LEGlyphID glyph) const = 0;
 };
+#endif  /* U_HIDE_INTERNAL_API */
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/LEInsertionList.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LEInsertionList.h	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  **********************************************************************
- *   Copyright (C) 1998-2008, International Business Machines
+ *   Copyright (C) 1998-2013, International Business Machines
  *   Corporation and others.  All Rights Reserved.
  **********************************************************************
  */
@@ -39,6 +39,7 @@
 
 struct InsertionRecord;
 
+#ifndef U_HIDE_INTERNAL_API
 /**
  * This class encapsulates the callback used by <code>LEInsertionList</code>
  * to apply an insertion from the insertion list.
@@ -194,6 +195,7 @@
      */
     le_bool  append;
 };
+#endif  /* U_HIDE_INTERNAL_API */
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/LEScripts.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LEScripts.h	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2010. All Rights Reserved.
+ * (C) Copyright IBM Corp. 1998-2013. All Rights Reserved.
  *
  * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS
  * YOU REALLY KNOW WHAT YOU'RE DOING.
@@ -241,8 +241,28 @@
     palmScriptCode = 144,
     sindScriptCode = 145,
     waraScriptCode = 146,
+/**
+ * @stable ICU 4.8
+ */
 
-    scriptCodeCount = 147
+    afakScriptCode = 147,
+    jurcScriptCode = 148,
+    mrooScriptCode = 149,
+    nshuScriptCode = 150,
+    shrdScriptCode = 151,
+    soraScriptCode = 152,
+    takrScriptCode = 153,
+    tangScriptCode = 154,
+    woleScriptCode = 155,
+/**
+ * @stable ICU 49
+ */
+
+    hluwScriptCode = 156, /* bump to match current ICU */
+    khojScriptCode = 157,
+    tirhScriptCode = 158,
+
+    scriptCodeCount = 159
 };
 
 U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/LETableReference.h	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2007, 2010, 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.
+ */
+
+/*
+ * -*- c++ -*-
+ *
+ * (C) Copyright IBM Corp. and others 2013 - All Rights Reserved
+ *
+ * Range checking
+ *
+ */
+
+#ifndef __LETABLEREFERENCE_H
+#define __LETABLEREFERENCE_H
+
+#include "LETypes.h"
+#include "LEFontInstance.h"
+
+
+#define kQuestionmarkTableTag  0x3F3F3F3FUL
+#define kTildeTableTag  0x7e7e7e7eUL
+#ifdef __cplusplus
+
+// internal - interface for range checking
+U_NAMESPACE_BEGIN
+
+#if LE_ASSERT_BAD_FONT
+class LETableReference; // fwd
+/**
+ *  defined in OpenTypeUtilities.cpp
+ * @internal
+ */
+extern void _debug_LETableReference(const char *f, int l, const char *msg, const LETableReference *what, const void *ptr, size_t len);
+
+#define LE_DEBUG_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
+#define LE_DEBUG_TR3(x,y,z) _debug_LETableReference(__FILE__, __LINE__, x, this, (const void*)y, (size_t)z);
+#if 0
+#define LE_TRACE_TR(x) _debug_LETableReference(__FILE__, __LINE__, x, this, NULL, 0);
+#else
+#define LE_TRACE_TR(x)
+#endif
+
+#else
+#define LE_DEBUG_TR(x)
+#define LE_DEBUG_TR3(x,y,z)
+#define LE_TRACE_TR(x)
+#endif
+
+/**
+ * @internal
+ */
+class LETableReference {
+public:
+/**
+ * @internal
+ * Construct from a specific tag
+ */
+  LETableReference(const LEFontInstance* font, LETag tableTag, LEErrorCode &success) :
+    fFont(font), fTag(tableTag), fParent(NULL), fStart(NULL),fLength(LE_UINTPTR_MAX) {
+      loadTable(success);
+    LE_TRACE_TR("INFO: new table load")
+  }
+
+  LETableReference(const LETableReference &parent, LEErrorCode &success) : fFont(parent.fFont), fTag(parent.fTag), fParent(&parent), fStart(parent.fStart), fLength(parent.fLength) {
+    if(LE_FAILURE(success)) {
+      clear();
+    }
+    LE_TRACE_TR("INFO: new clone")
+  }
+
+   LETableReference(const le_uint8* data, size_t length = LE_UINTPTR_MAX) :
+    fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(data), fLength(length) {
+    LE_TRACE_TR("INFO: new raw")
+  }
+  LETableReference() :
+    fFont(NULL), fTag(kQuestionmarkTableTag), fParent(NULL), fStart(NULL), fLength(0) {
+    LE_TRACE_TR("INFO: new empty")
+  }
+
+  ~LETableReference() {
+    fTag=kTildeTableTag;
+    LE_TRACE_TR("INFO: new dtor")
+  }
+
+  /**
+   * @internal
+   * @param length  if LE_UINTPTR_MAX means "whole table"
+   * subset
+   */
+  LETableReference(const LETableReference &parent, size_t offset, size_t length,
+                   LEErrorCode &err) :
+    fFont(parent.fFont), fTag(parent.fTag), fParent(&parent),
+    fStart((parent.fStart)+offset), fLength(length) {
+    if(LE_SUCCESS(err)) {
+      if(isEmpty()) {
+        //err = LE_MISSING_FONT_TABLE_ERROR;
+        clear(); // it's just empty. Not an error.
+      } else if(offset >= fParent->fLength) {
+        LE_DEBUG_TR3("offset out of range: (%p) +%d", NULL, offset);
+        err = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+        clear();
+      } else {
+        if(fLength == LE_UINTPTR_MAX &&
+           fParent->fLength != LE_UINTPTR_MAX) {
+          fLength = (fParent->fLength) - offset; // decrement length as base address is incremented
+        }
+        if(fLength != LE_UINTPTR_MAX) {  // if we have bounds:
+          if(offset+fLength > fParent->fLength) {
+            LE_DEBUG_TR3("offset+fLength out of range: (%p) +%d", NULL, offset+fLength);
+            err = LE_INDEX_OUT_OF_BOUNDS_ERROR; // exceeded
+            clear();
+          }
+        }
+      }
+    } else {
+      clear();
+    }
+    LE_TRACE_TR("INFO: new subset")
+  }
+
+  const void* getAlias() const { return (const void*)fStart; }
+  const void* getAliasTODO() const { LE_DEBUG_TR("getAliasTODO()"); return (const void*)fStart; }
+  le_bool isEmpty() const { return fStart==NULL || fLength==0; }
+  le_bool isValid() const { return !isEmpty(); }
+  le_bool hasBounds() const { return fLength!=LE_UINTPTR_MAX; }
+  void clear() { fLength=0; fStart=NULL; }
+  size_t getLength() const { return fLength; }
+  const LEFontInstance* getFont() const { return fFont; }
+  LETag getTag() const { return fTag; }
+  const LETableReference* getParent() const { return fParent; }
+
+  void addOffset(size_t offset, LEErrorCode &success) {
+    if(hasBounds()) {
+      if(offset > fLength) {
+        LE_DEBUG_TR("addOffset off end");
+        success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+        return;
+      } else {
+        fLength -= offset;
+      }
+    }
+    fStart += offset;
+  }
+
+  size_t ptrToOffset(const void *atPtr, LEErrorCode &success) const {
+    if(atPtr==NULL) return 0;
+    if(LE_FAILURE(success)) return LE_UINTPTR_MAX;
+    if((atPtr < fStart) ||
+       (hasBounds() && (atPtr > fStart+fLength))) {
+      LE_DEBUG_TR3("ptrToOffset args out of range: %p", atPtr, 0);
+      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+      return LE_UINTPTR_MAX;
+    }
+    return ((const le_uint8*)atPtr)-fStart;
+  }
+
+  /**
+   * Clamp down the length, for range checking.
+   */
+  size_t contractLength(size_t newLength) {
+    if(fLength!=LE_UINTPTR_MAX&&newLength>0&&newLength<=fLength) {
+      fLength = newLength;
+    }
+    return fLength;
+  }
+
+  /**
+   * Throw an error if offset+length off end
+   */
+public:
+  size_t verifyLength(size_t offset, size_t length, LEErrorCode &success) {
+    if(isValid()&&
+       LE_SUCCESS(success) &&
+       fLength!=LE_UINTPTR_MAX && length!=LE_UINTPTR_MAX && offset!=LE_UINTPTR_MAX &&
+       (offset+length)>fLength) {
+      LE_DEBUG_TR3("verifyLength failed (%p) %d",NULL, offset+length);
+      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+#if LE_ASSERT_BAD_FONT
+      fprintf(stderr, "offset=%lu, len=%lu, would be at %p, (%lu) off end. End at %p\n", offset,length, fStart+offset+length, (offset+length-fLength), (offset+length-fLength)+fStart);
+#endif
+    }
+    return fLength;
+  }
+
+  /**
+   * Change parent link to another
+   */
+  LETableReference &reparent(const LETableReference &base) {
+    fParent = &base;
+    return *this;
+  }
+
+  /**
+   * remove parent link. Factory functions should do this.
+   */
+  void orphan(void) {
+    fParent=NULL;
+  }
+
+protected:
+  const LEFontInstance* fFont;
+  LETag  fTag;
+  const LETableReference *fParent;
+  const le_uint8 *fStart; // keep as 8 bit internally, for pointer math
+  size_t fLength;
+
+  void loadTable(LEErrorCode &success) {
+    if(LE_SUCCESS(success)) {
+      fStart = (const le_uint8*)(fFont->getFontTable(fTag, fLength)); // note - a null table is not an error.
+    }
+  }
+
+  void setRaw(const void *data, size_t length = LE_UINTPTR_MAX) {
+    fFont = NULL;
+    fTag = kQuestionmarkTableTag;
+    fParent = NULL;
+    fStart = (const le_uint8*)data;
+    fLength = length;
+  }
+};
+
+
+template<class T>
+class LETableVarSizer {
+ public:
+  inline static size_t getSize();
+};
+
+// base definition- could override for adjustments
+template<class T> inline
+size_t LETableVarSizer<T>::getSize() {
+  return sizeof(T);
+}
+
+/**
+ * \def LE_VAR_ARRAY
+ * @param x Type (T)
+ * @param y some member that is of length ANY_NUMBER
+ * Call this after defining a class, for example:
+ *   LE_VAR_ARRAY(FeatureListTable,featureRecordArray)
+ * this is roughly equivalent to:
+ *   template<> inline size_t LETableVarSizer<FeatureListTable>::getSize() { return sizeof(FeatureListTable) - (sizeof(le_uint16)*ANY_NUMBER); }
+ * it's a specialization that informs the LETableReference subclasses to NOT include the variable array in the size.
+ * dereferencing NULL is valid here because we never actually dereference it, just inside sizeof.
+ */
+#define LE_VAR_ARRAY(x,y) template<> inline size_t LETableVarSizer<x>::getSize() { return sizeof(x) - (sizeof(((const x*)0)->y)); }
+/**
+ * \def LE_CORRECT_SIZE
+ * @param x type (T)
+ * @param y fixed size for T
+ */
+#define LE_CORRECT_SIZE(x,y) template<> inline size_t LETableVarSizer<x>::getSize() { return y; }
+
+/**
+ * Open a new entry based on an existing table
+ */
+
+/**
+ * \def LE_UNBOUNDED_ARRAY
+ * define an array with no *known* bound. Will trim to available size.
+ * @internal
+ */
+#define LE_UNBOUNDED_ARRAY LE_UINT32_MAX
+
+template<class T>
+class LEReferenceToArrayOf : public LETableReference {
+public:
+  LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, size_t offset, le_uint32 count)
+    : LETableReference(parent, offset, LE_UINTPTR_MAX, success), fCount(count) {
+    LE_TRACE_TR("INFO: new RTAO by offset")
+    if(LE_SUCCESS(success)) {
+      if(count == LE_UNBOUNDED_ARRAY) { // not a known length
+        count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
+      }
+      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
+    }
+    if(LE_FAILURE(success)) {
+      fCount=0;
+      clear();
+    }
+  }
+
+  LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, le_uint32 count)
+    : LETableReference(parent, parent.ptrToOffset(array, success), LE_UINTPTR_MAX, success), fCount(count) {
+LE_TRACE_TR("INFO: new RTAO")
+    if(LE_SUCCESS(success)) {
+      if(count == LE_UNBOUNDED_ARRAY) { // not a known length
+        count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
+      }
+      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
+    }
+    if(LE_FAILURE(success)) clear();
+  }
+ LEReferenceToArrayOf(const LETableReference &parent, LEErrorCode &success, const T* array, size_t offset, le_uint32 count)
+   : LETableReference(parent, parent.ptrToOffset(array, success)+offset, LE_UINTPTR_MAX, success), fCount(count) {
+LE_TRACE_TR("INFO: new RTAO")
+    if(LE_SUCCESS(success)) {
+      if(count == LE_UNBOUNDED_ARRAY) { // not a known length
+        count = getLength()/LETableVarSizer<T>::getSize(); // fit to max size
+      }
+      LETableReference::verifyLength(0, LETableVarSizer<T>::getSize()*count, success);
+    }
+    if(LE_FAILURE(success)) clear();
+  }
+
+ LEReferenceToArrayOf() :LETableReference(), fCount(0) {}
+
+  le_uint32 getCount() const { return fCount; }
+
+  using LETableReference::getAlias;
+
+  const T *getAlias(le_uint32 i, LEErrorCode &success) const {
+    return ((const T*)(((const char*)getAlias())+getOffsetFor(i, success)));
+  }
+
+  const T *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; }
+
+  const T& getObject(le_uint32 i, LEErrorCode &success) const {
+    return *getAlias(i,success);
+  }
+
+  const T& operator()(le_uint32 i, LEErrorCode &success) const {
+    return *getAlias(i,success);
+  }
+
+  size_t getOffsetFor(le_uint32 i, LEErrorCode &success) const {
+    if(LE_SUCCESS(success)&&i<getCount()) {
+      return LETableVarSizer<T>::getSize()*i;
+    } else {
+      success = LE_INDEX_OUT_OF_BOUNDS_ERROR;
+    }
+    return 0;
+  }
+
+  LEReferenceToArrayOf<T> &reparent(const LETableReference &base) {
+    fParent = &base;
+    return *this;
+  }
+
+ LEReferenceToArrayOf(const LETableReference& parent, LEErrorCode & success) : LETableReference(parent,0, LE_UINTPTR_MAX, success), fCount(0) {
+    LE_TRACE_TR("INFO: null RTAO")
+  }
+
+private:
+  le_uint32 fCount;
+};
+
+
+template<class T>
+class LEReferenceTo : public LETableReference {
+public:
+  /**
+   * open a sub reference.
+   * @param parent parent reference
+   * @param success error status
+   * @param atPtr location of reference - if NULL, will be at offset zero (i.e. downcast of parent). Otherwise must be a pointer within parent's bounds.
+   */
+  LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr)
+    : LETableReference(parent, parent.ptrToOffset(atPtr, success), LE_UINTPTR_MAX, success) {
+    verifyLength(0, LETableVarSizer<T>::getSize(), success);
+    if(LE_FAILURE(success)) clear();
+  }
+  /**
+   * ptr plus offset
+   */
+ LEReferenceTo(const LETableReference &parent, LEErrorCode &success, const void* atPtr, size_t offset)
+    : LETableReference(parent, parent.ptrToOffset(atPtr, success)+offset, LE_UINTPTR_MAX, success) {
+    verifyLength(0, LETableVarSizer<T>::getSize(), success);
+    if(LE_FAILURE(success)) clear();
+  }
+  LEReferenceTo(const LETableReference &parent, LEErrorCode &success, size_t offset)
+    : LETableReference(parent, offset, LE_UINTPTR_MAX, success) {
+    verifyLength(0, LETableVarSizer<T>::getSize(), success);
+    if(LE_FAILURE(success)) clear();
+  }
+  LEReferenceTo(const LETableReference &parent, LEErrorCode &success)
+    : LETableReference(parent, 0, LE_UINTPTR_MAX, success) {
+    verifyLength(0, LETableVarSizer<T>::getSize(), success);
+    if(LE_FAILURE(success)) clear();
+  }
+ LEReferenceTo(const LEFontInstance *font, LETag tableTag, LEErrorCode &success)
+   : LETableReference(font, tableTag, success) {
+    verifyLength(0, LETableVarSizer<T>::getSize(), success);
+    if(LE_FAILURE(success)) clear();
+  }
+ LEReferenceTo(const le_uint8 *data, size_t length = LE_UINTPTR_MAX) : LETableReference(data, length) {}
+ LEReferenceTo(const T *data, size_t length = LE_UINTPTR_MAX) : LETableReference((const le_uint8*)data, length) {}
+  LEReferenceTo() : LETableReference(NULL) {}
+
+  LEReferenceTo<T>& operator=(const T* other) {
+    setRaw(other);
+    return *this;
+  }
+
+  LEReferenceTo<T> &reparent(const LETableReference &base) {
+    fParent = &base;
+    return *this;
+  }
+
+  /**
+   * roll forward by one <T> size.
+   * same as addOffset(LETableVarSizer<T>::getSize(),success)
+   */
+  void addObject(LEErrorCode &success) {
+    addOffset(LETableVarSizer<T>::getSize(), success);
+  }
+  void addObject(size_t count, LEErrorCode &success) {
+    addOffset(LETableVarSizer<T>::getSize()*count, success);
+  }
+
+  const T *operator->() const { return getAlias(); }
+  const T *getAlias() const { return (const T*)fStart; }
+  const T *getAliasTODO() const { LE_DEBUG_TR("getAliasTODO<>"); return (const T*)fStart; }
+};
+
+
+U_NAMESPACE_END
+
+#endif
+
+#endif
--- a/src/share/native/sun/font/layout/LETypes.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LETypes.h	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -50,14 +50,15 @@
 #endif
 
 #include "unicode/utypes.h"
+
+#ifdef __cplusplus
 #include "unicode/uobject.h"
+#endif
+
 #ifdef LE_USE_CMEMORY
 #include "cmemory.h"
 #endif
-#endif /* not standalone */
-
-
-U_NAMESPACE_BEGIN
+#endif
 
 /*!
  * \file
@@ -296,12 +297,14 @@
  */
 typedef UChar32 LEUnicode32;
 
+#ifndef U_HIDE_DEPRECATED_API
 /**
  * Used to represent 16-bit Unicode code points.
  *
  * @deprecated since ICU 2.4. Use LEUnicode16 instead
  */
 typedef UChar LEUnicode;
+#endif  /* U_HIDE_DEPRECATED_API */
 
 /**
  * Used to hold a pair of (x, y) values which represent a point.
@@ -325,7 +328,7 @@
     float fY;
 };
 
-#ifndef XP_CPLUSPLUS
+#ifndef __cplusplus
 /**
  * Used to hold a pair of (x, y) values which represent a point.
  *
@@ -335,6 +338,39 @@
 #endif
 
 
+#ifndef U_HIDE_INTERNAL_API
+
+#ifndef LE_ASSERT_BAD_FONT
+#define LE_ASSERT_BAD_FONT 0
+#endif
+
+#if LE_ASSERT_BAD_FONT
+#include <stdio.h>
+#define LE_DEBUG_BAD_FONT(x) fprintf(stderr,"%s:%d: BAD FONT: %s\n", __FILE__, __LINE__, (x));
+#else
+#define LE_DEBUG_BAD_FONT(x)
+#endif
+
+/**
+ * Max value representable by a uintptr
+ */
+
+#ifndef UINT32_MAX
+#define LE_UINT32_MAX 0xFFFFFFFFU
+#else
+#define LE_UINT32_MAX UINT32_MAX
+#endif
+
+#ifndef UINTPTR_MAX
+#define LE_UINTPTR_MAX LE_UINT32_MAX
+#else
+#define LE_UINTPTR_MAX UINTPTR_MAX
+#endif
+
+/**
+ * Range check for overflow
+ */
+#define LE_RANGE_CHECK(type, count, ptrfn) (( (LE_UINTPTR_MAX / sizeof(type)) < count ) ? NULL : (ptrfn))
 /**
  * A convenience macro to get the length of an array.
  *
@@ -356,7 +392,7 @@
  *
  * @internal
  */
-#define LE_NEW_ARRAY(type, count) (type *) uprv_malloc((count) * sizeof(type))
+#define LE_NEW_ARRAY(type, count) (type *)  LE_RANGE_CHECK(type,count,uprv_malloc((count) * sizeof(type)))
 
 /**
  * Re-allocate an array of basic types. This is used to isolate the rest of
@@ -373,7 +409,52 @@
  * @internal
  */
 #define LE_DELETE_ARRAY(array) uprv_free((void *) (array))
-#endif
+#else
+/* !LE_USE_CMEMORY - Not using ICU memory - use C std lib versions */
+
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * A convenience macro to get the length of an array.
+ *
+ * @internal
+ */
+#define LE_ARRAY_SIZE(array) (sizeof array / sizeof array[0])
+
+/**
+ * A convenience macro for copying an array.
+ *
+ * @internal
+ */
+#define LE_ARRAY_COPY(dst, src, count) memcpy((void *) (dst), (void *) (src), (count) * sizeof (src)[0])
+
+/**
+ * Allocate an array of basic types. This is used to isolate the rest of
+ * the LayoutEngine code from cmemory.h.
+ *
+ * @internal
+ */
+#define LE_NEW_ARRAY(type, count) LE_RANGE_CHECK(type,count,(type *) malloc((count) * sizeof(type)))
+
+/**
+ * Re-allocate an array of basic types. This is used to isolate the rest of
+ * the LayoutEngine code from cmemory.h.
+ *
+ * @internal
+ */
+#define LE_GROW_ARRAY(array, newSize) realloc((void *) (array), (newSize) * sizeof (array)[0])
+
+ /**
+ * Free an array of basic types. This is used to isolate the rest of
+ * the LayoutEngine code from cmemory.h.
+ *
+ * @internal
+ */
+#define LE_DELETE_ARRAY(array) free((void *) (array))
+
+#endif  /* LE_USE_CMEMORY */
+#endif  /* U_HIDE_INTERNAL_API */
 
 /**
  * A macro to construct the four-letter tags used to
@@ -536,7 +617,7 @@
     LE_RAND_FEATURE_TAG = 0x72616E64UL, /**< 'rand' */
     LE_RLIG_FEATURE_TAG = 0x726C6967UL, /**< 'rlig' */
     LE_RPHF_FEATURE_TAG = 0x72706866UL, /**< 'rphf' */
-        LE_RKRF_FEATURE_TAG = 0x726B7266UL, /**< 'rkrf' */
+    LE_RKRF_FEATURE_TAG = 0x726B7266UL, /**< 'rkrf' */
     LE_RTBD_FEATURE_TAG = 0x72746264UL, /**< 'rtbd' */
     LE_RTLA_FEATURE_TAG = 0x72746C61UL, /**< 'rtla' */
     LE_RUBY_FEATURE_TAG = 0x72756279UL, /**< 'ruby' */
@@ -588,6 +669,68 @@
 };
 
 /**
+ * @internal
+ */
+enum LEFeatureENUMs {
+  LE_Kerning_FEATURE_ENUM = 0,   /**< Requests Kerning. Formerly LayoutEngine::kTypoFlagKern */
+  LE_Ligatures_FEATURE_ENUM = 1, /**< Requests Ligatures. Formerly LayoutEngine::kTypoFlagLiga */
+  LE_NoCanon_FEATURE_ENUM = 2, /**< Requests No Canonical Processing */
+  LE_CLIG_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_DLIG_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_HLIG_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_LIGA_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_RLIG_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SMCP_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_FRAC_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_AFRC_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_ZERO_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SWSH_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_CSWH_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SALT_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_NALT_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_RUBY_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS01_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS02_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS03_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS04_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS05_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS06_FEATURE_ENUM,  /**< Feature specific enum */
+  LE_SS07_FEATURE_ENUM,   /**< Feature specific enum */
+
+  LE_CHAR_FILTER_FEATURE_ENUM = 31, /**< Apply CharSubstitutionFilter */
+  LE_FEATURE_ENUM_MAX = LE_CHAR_FILTER_FEATURE_ENUM
+};
+
+#define LE_Kerning_FEATURE_FLAG   (1 << LE_Kerning_FEATURE_ENUM)
+#define LE_Ligatures_FEATURE_FLAG (1 << LE_Ligatures_FEATURE_ENUM)
+#define LE_NoCanon_FEATURE_FLAG (1 << LE_NoCanon_FEATURE_ENUM)
+#define LE_CLIG_FEATURE_FLAG (1 << LE_CLIG_FEATURE_ENUM)
+#define LE_DLIG_FEATURE_FLAG (1 << LE_DLIG_FEATURE_ENUM)
+#define LE_HLIG_FEATURE_FLAG (1 << LE_HLIG_FEATURE_ENUM)
+#define LE_LIGA_FEATURE_FLAG (1 << LE_LIGA_FEATURE_ENUM)
+#define LE_RLIG_FEATURE_FLAG (1 << LE_RLIG_FEATURE_ENUM)
+#define LE_SMCP_FEATURE_FLAG (1 << LE_SMCP_FEATURE_ENUM)
+#define LE_FRAC_FEATURE_FLAG (1 << LE_FRAC_FEATURE_ENUM)
+#define LE_AFRC_FEATURE_FLAG (1 << LE_AFRC_FEATURE_ENUM)
+#define LE_ZERO_FEATURE_FLAG (1 << LE_ZERO_FEATURE_ENUM)
+#define LE_SWSH_FEATURE_FLAG (1 << LE_SWSH_FEATURE_ENUM)
+#define LE_CSWH_FEATURE_FLAG (1 << LE_CSWH_FEATURE_ENUM)
+#define LE_SALT_FEATURE_FLAG (1 << LE_SALT_FEATURE_ENUM)
+#define LE_NALT_FEATURE_FLAG (1 << LE_NALT_FEATURE_ENUM)
+#define LE_RUBY_FEATURE_FLAG (1 << LE_RUBY_FEATURE_ENUM)
+#define LE_SS01_FEATURE_FLAG (1 << LE_SS01_FEATURE_ENUM)
+#define LE_SS02_FEATURE_FLAG (1 << LE_SS02_FEATURE_ENUM)
+#define LE_SS03_FEATURE_FLAG (1 << LE_SS03_FEATURE_ENUM)
+#define LE_SS04_FEATURE_FLAG (1 << LE_SS04_FEATURE_ENUM)
+#define LE_SS05_FEATURE_FLAG (1 << LE_SS05_FEATURE_ENUM)
+#define LE_SS06_FEATURE_FLAG (1 << LE_SS06_FEATURE_ENUM)
+#define LE_SS07_FEATURE_FLAG (1 << LE_SS07_FEATURE_ENUM)
+
+#define LE_CHAR_FILTER_FEATURE_FLAG (1 << LE_CHAR_FILTER_FEATURE_ENUM)
+
+#define LE_DEFAULT_FEATURE_FLAG (LE_Kerning_FEATURE_FLAG | LE_Ligatures_FEATURE_FLAG) /**< default features */
+
+/**
  * Error codes returned by the LayoutEngine.
  *
  * @stable ICU 2.4
@@ -611,7 +754,7 @@
 };
 #endif
 
-#ifndef XP_CPLUSPLUS
+#ifndef __cplusplus
 /**
  * Error codes returned by the LayoutEngine.
  *
@@ -638,7 +781,4 @@
 #define LE_FAILURE(code) (U_FAILURE((UErrorCode)code))
 #endif
 
-U_NAMESPACE_END
-#endif
-
-
+#endif /* __LETYPES_H */
--- a/src/share/native/sun/font/layout/LayoutEngine.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LayoutEngine.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -33,6 +33,7 @@
 #include "LETypes.h"
 #include "LEScripts.h"
 #include "LELanguages.h"
+#include "LESwaps.h"
 
 #include "LayoutEngine.h"
 #include "ArabicLayoutEngine.h"
@@ -44,6 +45,8 @@
 #include "ThaiLayoutEngine.h"
 #include "TibetanLayoutEngine.h"
 #include "GXLayoutEngine.h"
+#include "GXLayoutEngine2.h"
+
 #include "ScriptAndLanguageTags.h"
 #include "CharSubstitutionFilter.h"
 
@@ -63,6 +66,10 @@
 /* Leave this copyright notice here! It needs to go somewhere in this library. */
 static const char copyright[] = U_COPYRIGHT_STRING;
 
+/* TODO: remove these? */
+const le_int32 LayoutEngine::kTypoFlagKern = LE_Kerning_FEATURE_FLAG;
+const le_int32 LayoutEngine::kTypoFlagLiga = LE_Ligatures_FEATURE_FLAG;
+
 const LEUnicode32 DefaultCharMapper::controlChars[] = {
     0x0009, 0x000A, 0x000D,
     /*0x200C, 0x200D,*/ 0x200E, 0x200F,
@@ -140,21 +147,21 @@
 class CanonMarkFilter : public UMemory, public LEGlyphFilter
 {
 private:
-    const GlyphClassDefinitionTable *classDefTable;
+  const LEReferenceTo<GlyphClassDefinitionTable> classDefTable;
 
     CanonMarkFilter(const CanonMarkFilter &other); // forbid copying of this class
     CanonMarkFilter &operator=(const CanonMarkFilter &other); // forbid copying of this class
 
 public:
-    CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable);
+    CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success);
     virtual ~CanonMarkFilter();
 
     virtual le_bool accept(LEGlyphID glyph) const;
 };
 
-CanonMarkFilter::CanonMarkFilter(const GlyphDefinitionTableHeader *gdefTable)
+CanonMarkFilter::CanonMarkFilter(const LEReferenceTo<GlyphDefinitionTableHeader> &gdefTable, LEErrorCode &success)
+  : classDefTable(gdefTable->getMarkAttachClassDefinitionTable(gdefTable, success))
 {
-    classDefTable = gdefTable->getMarkAttachClassDefinitionTable();
 }
 
 CanonMarkFilter::~CanonMarkFilter()
@@ -164,9 +171,10 @@
 
 le_bool CanonMarkFilter::accept(LEGlyphID glyph) const
 {
-    le_int32 glyphClass = classDefTable->getGlyphClass(glyph);
-
-    return glyphClass != 0;
+  LEErrorCode success = LE_NO_ERROR;
+  le_int32 glyphClass = classDefTable->getGlyphClass(classDefTable, glyph, success);
+  if(LE_FAILURE(success)) return false;
+  return glyphClass != 0;
 }
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LayoutEngine)
@@ -251,24 +259,24 @@
         return 0;
     }
 
-    if ((fTypoFlags & 0x4) == 0) { // no canonical processing
+    if ((fTypoFlags & LE_NoCanon_FEATURE_FLAG) == 0) { // no canonical processing
       return count;
     }
 
-    const GlyphSubstitutionTableHeader *canonGSUBTable = (GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable;
+    LEReferenceTo<GlyphSubstitutionTableHeader> canonGSUBTable((GlyphSubstitutionTableHeader *) CanonShaping::glyphSubstitutionTable);
     LETag scriptTag  = OpenTypeLayoutEngine::getScriptTag(fScriptCode);
     LETag langSysTag = OpenTypeLayoutEngine::getLangSysTag(fLanguageCode);
     le_int32 i, dir = 1, out = 0, outCharCount = count;
 
-    if (canonGSUBTable->coversScript(scriptTag)) {
+    if (canonGSUBTable->coversScript(canonGSUBTable,scriptTag, success) || LE_SUCCESS(success)) {
         CharSubstitutionFilter *substitutionFilter = new CharSubstitutionFilter(fFontInstance);
         if (substitutionFilter == NULL) {
             success = LE_MEMORY_ALLOCATION_ERROR;
             return 0;
         }
 
-                const LEUnicode *inChars = &chars[offset];
-                LEUnicode *reordered = NULL;
+        const LEUnicode *inChars = &chars[offset];
+        LEUnicode *reordered = NULL;
         LEGlyphStorage fakeGlyphStorage;
 
         fakeGlyphStorage.allocateGlyphArray(count, rightToLeft, success);
@@ -278,20 +286,20 @@
             return 0;
         }
 
-                // This is the cheapest way to get mark reordering only for Hebrew.
-                // We could just do the mark reordering for all scripts, but most
-                // of them probably don't need it...
-                if (fScriptCode == hebrScriptCode) {
-                        reordered = LE_NEW_ARRAY(LEUnicode, count);
+        // This is the cheapest way to get mark reordering only for Hebrew.
+        // We could just do the mark reordering for all scripts, but most
+        // of them probably don't need it...
+        if (fScriptCode == hebrScriptCode) {
+          reordered = LE_NEW_ARRAY(LEUnicode, count);
 
-                        if (reordered == NULL) {
-                delete substitutionFilter;
-                                success = LE_MEMORY_ALLOCATION_ERROR;
-                                return 0;
-                        }
+          if (reordered == NULL) {
+            delete substitutionFilter;
+            success = LE_MEMORY_ALLOCATION_ERROR;
+            return 0;
+          }
 
-                        CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
-                        inChars = reordered;
+          CanonShaping::reorderMarks(&chars[offset], count, rightToLeft, reordered, fakeGlyphStorage);
+          inChars = reordered;
                 }
 
         fakeGlyphStorage.allocateAuxData(success);
@@ -311,11 +319,11 @@
             fakeGlyphStorage.setAuxData(out, canonFeatures, success);
         }
 
-                if (reordered != NULL) {
-                        LE_DELETE_ARRAY(reordered);
-                }
+        if (reordered != NULL) {
+          LE_DELETE_ARRAY(reordered);
+        }
 
-        outCharCount = canonGSUBTable->process(fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
+        outCharCount = canonGSUBTable->process(canonGSUBTable, fakeGlyphStorage, rightToLeft, scriptTag, langSysTag, (const GlyphDefinitionTableHeader*)NULL, substitutionFilter, canonFeatureMap, canonFeatureMapCount, FALSE, success);
 
         if (LE_FAILURE(success)) {
             delete substitutionFilter;
@@ -416,16 +424,16 @@
         return;
     }
 
-    GlyphDefinitionTableHeader *gdefTable = (GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable;
-    CanonMarkFilter filter(gdefTable);
+    LEReferenceTo<GlyphDefinitionTableHeader> gdefTable((GlyphDefinitionTableHeader *) CanonShaping::glyphDefinitionTable,
+                                                        CanonShaping::glyphDefinitionTableLen);
+    CanonMarkFilter filter(gdefTable, success);
 
     adjustMarkGlyphs(&chars[offset], count, reverse, glyphStorage, &filter, success);
 
-    if (fTypoFlags & 0x1) { /* kerning enabled */
-      static const le_uint32 kernTableTag = LE_KERN_TABLE_TAG;
-
-      KernTable kt(fFontInstance, getFontTable(kernTableTag));
-      kt.process(glyphStorage);
+    if (fTypoFlags & LE_Kerning_FEATURE_FLAG) { /* kerning enabled */
+      LETableReference kernTable(fFontInstance, LE_KERN_TABLE_TAG, success);
+      KernTable kt(kernTable, success);
+      kt.process(glyphStorage, success);
     }
 
     // default is no adjustments
@@ -510,9 +518,9 @@
     glyphStorage.adjustPosition(glyphCount, xAdjust, 0, success);
 }
 
-const void *LayoutEngine::getFontTable(LETag tableTag) const
+const void *LayoutEngine::getFontTable(LETag tableTag, size_t &length) const
 {
-    return fFontInstance->getFontTable(tableTag);
+  return fFontInstance->getFontTable(tableTag, length);
 }
 
 void LayoutEngine::mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror,
@@ -559,37 +567,41 @@
 
 void LayoutEngine::reset()
 {
+  if(fGlyphStorage!=NULL) {
     fGlyphStorage->reset();
+    fGlyphStorage = NULL;
+  }
 }
 
 LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, LEErrorCode &success)
 {
-  // 3 -> kerning and ligatures
-  return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, languageCode, 3, success);
+  //kerning and ligatures - by default
+  return LayoutEngine::layoutEngineFactory(fontInstance, scriptCode, languageCode, LE_DEFAULT_FEATURE_FLAG, success);
 }
 
 LayoutEngine *LayoutEngine::layoutEngineFactory(const LEFontInstance *fontInstance, le_int32 scriptCode, le_int32 languageCode, le_int32 typoFlags, LEErrorCode &success)
 {
     static const le_uint32 gsubTableTag = LE_GSUB_TABLE_TAG;
     static const le_uint32 mortTableTag = LE_MORT_TABLE_TAG;
+    static const le_uint32 morxTableTag = LE_MORX_TABLE_TAG;
 
     if (LE_FAILURE(success)) {
         return NULL;
     }
 
-    const GlyphSubstitutionTableHeader *gsubTable = (const GlyphSubstitutionTableHeader *) fontInstance->getFontTable(gsubTableTag);
+    LEReferenceTo<GlyphSubstitutionTableHeader> gsubTable(fontInstance,gsubTableTag,success);
     LayoutEngine *result = NULL;
     LETag scriptTag   = 0x00000000;
     LETag languageTag = 0x00000000;
-        LETag v2ScriptTag = OpenTypeLayoutEngine::getV2ScriptTag(scriptCode);
+    LETag v2ScriptTag = OpenTypeLayoutEngine::getV2ScriptTag(scriptCode);
 
     // Right now, only invoke V2 processing for Devanagari.  TODO: Allow more V2 scripts as they are
     // properly tested.
 
-        if ( v2ScriptTag == dev2ScriptTag && gsubTable != NULL && gsubTable->coversScript( v2ScriptTag )) {
-                result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success);
-        }
-    else if (gsubTable != NULL && gsubTable->coversScript(scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode))) {
+    if ( v2ScriptTag == dev2ScriptTag && gsubTable.isValid() && gsubTable->coversScript(gsubTable, v2ScriptTag, success )) {
+      result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, TRUE, gsubTable, success);
+    }
+    else if (gsubTable.isValid() && gsubTable->coversScript(gsubTable, scriptTag = OpenTypeLayoutEngine::getScriptTag(scriptCode), success)) {
         switch (scriptCode) {
         case bengScriptCode:
         case devaScriptCode:
@@ -608,6 +620,11 @@
             result = new ArabicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
             break;
 
+        case hebrScriptCode:
+            // Disable hebrew ligatures since they have only archaic uses, see ticket #8318
+            result = new OpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags & ~kTypoFlagLiga, gsubTable, success);
+            break;
+
         case hangScriptCode:
             result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
             break;
@@ -620,10 +637,10 @@
             case janLanguageCode:
             case zhtLanguageCode:
             case zhsLanguageCode:
-                if (gsubTable->coversScriptAndLanguage(scriptTag, languageTag, TRUE)) {
+              if (gsubTable->coversScriptAndLanguage(gsubTable, scriptTag, languageTag, success, TRUE)) {
                     result = new HanOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, gsubTable, success);
                     break;
-                }
+              }
 
                 // note: falling through to default case.
             default:
@@ -646,26 +663,29 @@
             break;
         }
     } else {
-        const MorphTableHeader *morphTable = (MorphTableHeader *) fontInstance->getFontTable(mortTableTag);
-
-        if (morphTable != NULL) {
-            result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, morphTable, success);
+        MorphTableHeader2 *morxTable = (MorphTableHeader2 *)fontInstance->getFontTable(morxTableTag);
+        if (morxTable != NULL && SWAPL(morxTable->version)==0x00020000) {
+            result = new GXLayoutEngine2(fontInstance, scriptCode, languageCode, morxTable, typoFlags, success);
         } else {
-            switch (scriptCode) {
-            case bengScriptCode:
-            case devaScriptCode:
-            case gujrScriptCode:
-            case kndaScriptCode:
-            case mlymScriptCode:
-            case oryaScriptCode:
-            case guruScriptCode:
-            case tamlScriptCode:
-            case teluScriptCode:
-            case sinhScriptCode:
-            {
-                result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
-                break;
-            }
+          LEReferenceTo<MorphTableHeader> mortTable(fontInstance, mortTableTag, success);
+          if (LE_SUCCESS(success) && mortTable.isValid() && SWAPL(mortTable->version)==0x00010000) { // mort
+            result = new GXLayoutEngine(fontInstance, scriptCode, languageCode, mortTable, success);
+            } else {
+                switch (scriptCode) {
+                    case bengScriptCode:
+                    case devaScriptCode:
+                    case gujrScriptCode:
+                    case kndaScriptCode:
+                    case mlymScriptCode:
+                    case oryaScriptCode:
+                    case guruScriptCode:
+                    case tamlScriptCode:
+                    case teluScriptCode:
+                    case sinhScriptCode:
+                    {
+                        result = new IndicOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
+                        break;
+                    }
 
             case arabScriptCode:
             //case hebrScriptCode:
@@ -683,9 +703,10 @@
                 result = new HangulOpenTypeLayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
                 break;
 
-            default:
-                result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
-                break;
+                    default:
+                        result = new LayoutEngine(fontInstance, scriptCode, languageCode, typoFlags, success);
+                        break;
+                }
             }
         }
     }
--- a/src/share/native/sun/font/layout/LayoutEngine.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LayoutEngine.h	Thu Apr 18 14:38:37 2013 -0700
@@ -26,7 +26,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2008 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -90,6 +90,14 @@
  * @stable ICU 2.8
  */
 class U_LAYOUT_API LayoutEngine : public UObject {
+public:
+#ifndef U_HIDE_INTERNAL_API
+    /** @internal Flag to request kerning. Use LE_Kerning_FEATURE_FLAG instead. */
+    static const le_int32 kTypoFlagKern;
+    /** @internal Flag to request ligatures. Use LE_Ligatures_FEATURE_FLAG instead. */
+    static const le_int32 kTypoFlagLiga;
+#endif  /* U_HIDE_INTERNAL_API */
+
 protected:
     /**
      * The object which holds the glyph storage
@@ -140,6 +148,7 @@
      */
     le_bool fFilterZeroWidth;
 
+#ifndef U_HIDE_INTERNAL_API
     /**
      * This constructs an instance for a given font, script and language. Subclass constructors
      * must call this constructor.
@@ -161,7 +170,10 @@
                  le_int32 languageCode,
                  le_int32 typoFlags,
                  LEErrorCode &success);
+#endif  /* U_HIDE_INTERNAL_API */
 
+    // Do not enclose the protected default constructor with #ifndef U_HIDE_INTERNAL_API
+    // or else the compiler will create a public default constructor.
     /**
      * This overrides the default no argument constructor to make it
      * difficult for clients to call it. Clients are expected to call
@@ -268,12 +280,18 @@
      * some other way must override this method.
      *
      * @param tableTag - the four byte table tag.
+     * @param length - length to use
      *
      * @return the address of the table.
      *
      * @internal
      */
-    virtual const void *getFontTable(LETag tableTag) const;
+    virtual const void *getFontTable(LETag tableTag, size_t &length) const;
+
+    /**
+     * @deprecated
+     */
+    virtual const void *getFontTable(LETag tableTag) const { size_t ignored; return getFontTable(tableTag, ignored); }
 
     /**
      * This method does character to glyph mapping. The default implementation
@@ -302,6 +320,7 @@
      */
     virtual void mapCharsToGlyphs(const LEUnicode chars[], le_int32 offset, le_int32 count, le_bool reverse, le_bool mirror, LEGlyphStorage &glyphStorage, LEErrorCode &success);
 
+#ifndef U_HIDE_INTERNAL_API
     /**
      * This is a convenience method that forces the advance width of mark
      * glyphs to be zero, which is required for proper selection and highlighting.
@@ -336,7 +355,7 @@
      * @internal
      */
     static void adjustMarkGlyphs(const LEUnicode chars[], le_int32 charCount, le_bool reverse, LEGlyphStorage &glyphStorage, LEGlyphFilter *markFilter, LEErrorCode &success);
-
+#endif  /* U_HIDE_INTERNAL_API */
 
 public:
     /**
--- a/src/share/native/sun/font/layout/LigatureSubstProc.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LigatureSubstProc.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -47,15 +47,15 @@
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor)
 
-LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader)
-  : StateTableProcessor(morphSubtableHeader)
+  LigatureSubstitutionProcessor::LigatureSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
+: StateTableProcessor(morphSubtableHeader, success), ligatureSubstitutionHeader(morphSubtableHeader, success)
 {
-    ligatureSubstitutionHeader = (const LigatureSubstitutionHeader *) morphSubtableHeader;
+    if(LE_FAILURE(success)) return;
     ligatureActionTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureActionTableOffset);
     componentTableOffset = SWAPW(ligatureSubstitutionHeader->componentTableOffset);
     ligatureTableOffset = SWAPW(ligatureSubstitutionHeader->ligatureTableOffset);
 
-    entryTable = (const LigatureSubstitutionStateEntry *) ((char *) &stateTableHeader->stHeader + entryTableOffset);
+    entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
 }
 
 LigatureSubstitutionProcessor::~LigatureSubstitutionProcessor()
@@ -69,7 +69,9 @@
 
 ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
 {
-    const LigatureSubstitutionStateEntry *entry = &entryTable[index];
+  LEErrorCode success = LE_NO_ERROR;
+  const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
+
     ByteOffset newState = SWAPW(entry->newStateOffset);
     le_int16 flags = SWAPW(entry->flags);
 
@@ -79,12 +81,16 @@
         }
 
         componentStack[m] = currGlyph;
+    } else if ( m == -1) {
+        // bad font- skip this glyph.
+        currGlyph++;
+        return newState;
     }
 
     ByteOffset actionOffset = flags & lsfActionOffsetMask;
 
     if (actionOffset != 0) {
-        const LigatureActionEntry *ap = (const LigatureActionEntry *) ((char *) &ligatureSubstitutionHeader->stHeader + actionOffset);
+      LEReferenceTo<LigatureActionEntry> ap(stHeader, success, actionOffset);
         LigatureActionEntry action;
         le_int32 offset, i = 0;
         le_int32 stack[nComponents];
@@ -93,7 +99,8 @@
         do {
             le_uint32 componentGlyph = componentStack[m--];
 
-            action = SWAPL(*ap++);
+            action = SWAPL(*ap.getAlias());
+            ap.addObject(success); // ap++
 
             if (m < 0) {
                 m = nComponents - 1;
@@ -101,29 +108,48 @@
 
             offset = action & lafComponentOffsetMask;
             if (offset != 0) {
-                const le_int16 *offsetTable = (const le_int16 *)((char *) &ligatureSubstitutionHeader->stHeader + 2 * SignExtend(offset, lafComponentOffsetMask));
+              LEReferenceToArrayOf<le_int16> offsetTable(stHeader, success, 2 * SignExtend(offset, lafComponentOffsetMask), LE_UNBOUNDED_ARRAY);
 
-                i += SWAPW(offsetTable[LE_GET_GLYPH(glyphStorage[componentGlyph])]);
+              if(LE_FAILURE(success)) {
+                  currGlyph++;
+                  LE_DEBUG_BAD_FONT("off end of ligature substitution header");
+                  return newState; // get out! bad font
+              }
+              if(componentGlyph > glyphStorage.getGlyphCount()) {
+                LE_DEBUG_BAD_FONT("preposterous componentGlyph");
+                currGlyph++;
+                return newState; // get out! bad font
+              }
+              i += SWAPW(offsetTable.getObject(LE_GET_GLYPH(glyphStorage[componentGlyph]), success));
 
                 if (action & (lafLast | lafStore))  {
-                    const TTGlyphID *ligatureOffset = (const TTGlyphID *) ((char *) &ligatureSubstitutionHeader->stHeader + i);
-                    TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset);
+                  LEReferenceTo<TTGlyphID> ligatureOffset(stHeader, success, i);
+                  TTGlyphID ligatureGlyph = SWAPW(*ligatureOffset.getAlias());
 
-                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
-                    stack[++mm] = componentGlyph;
-                    i = 0;
+                  glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
+                  if(mm==nComponents) {
+                    LE_DEBUG_BAD_FONT("exceeded nComponents");
+                    mm--; // don't overrun the stack.
+                  }
+                  stack[++mm] = componentGlyph;
+                  i = 0;
                 } else {
-                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
+                  glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
                 }
             }
-        } while (!(action & lafLast));
+#if LE_ASSERT_BAD_FONT
+            if(m<0) {
+              LE_DEBUG_BAD_FONT("m<0")
+            }
+#endif
+        } while (!(action & lafLast)  && (m>=0) ); // stop if last bit is set, or if run out of items
 
         while (mm >= 0) {
-            if (++m >= nComponents) {
-                m = 0;
-            }
+          if (++m >= nComponents) {
+            m = 0;
+          }
 
-            componentStack[m] = stack[mm--];
+          componentStack[m] = stack[mm--];
         }
     }
 
--- a/src/share/native/sun/font/layout/LigatureSubstProc.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LigatureSubstProc.h	Thu Apr 18 14:38:37 2013 -0700
@@ -58,7 +58,7 @@
 
     virtual void endStateTable();
 
-    LigatureSubstitutionProcessor(const MorphSubtableHeader *morphSubtableHeader);
+    LigatureSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success);
     virtual ~LigatureSubstitutionProcessor();
 
     /**
@@ -83,12 +83,12 @@
     ByteOffset componentTableOffset;
     ByteOffset ligatureTableOffset;
 
-    const LigatureSubstitutionStateEntry *entryTable;
+    LEReferenceToArrayOf<LigatureSubstitutionStateEntry> entryTable;
 
     le_int32 componentStack[nComponents];
     le_int16 m;
 
-    const LigatureSubstitutionHeader *ligatureSubstitutionHeader;
+    LEReferenceTo<LigatureSubstitutionHeader> ligatureSubstitutionHeader;
 
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/LigatureSubstProc2.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp and Others. 1998-2013 - All Rights Reserved
+ *
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "StateTables.h"
+#include "MorphStateTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "LigatureSubstProc2.h"
+#include "LEGlyphStorage.h"
+#include "LESwaps.h"
+
+U_NAMESPACE_BEGIN
+
+#define ExtendedComplement(m) ((le_int32) (~((le_uint32) (m))))
+#define SignBit(m) ((ExtendedComplement(m) >> 1) & (le_int32)(m))
+#define SignExtend(v,m) (((v) & SignBit(m))? ((v) | ExtendedComplement(m)): (v))
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(LigatureSubstitutionProcessor2)
+
+LigatureSubstitutionProcessor2::LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success)
+  : StateTableProcessor2(morphSubtableHeader, success),
+  ligActionOffset(0),
+  ligatureSubstitutionHeader(morphSubtableHeader, success), componentOffset(0), ligatureOffset(0), entryTable()
+{
+    if (LE_FAILURE(success)) return;
+
+    ligActionOffset = SWAPL(ligatureSubstitutionHeader->ligActionOffset);
+    componentOffset = SWAPL(ligatureSubstitutionHeader->componentOffset);
+    ligatureOffset = SWAPL(ligatureSubstitutionHeader->ligatureOffset);
+
+    entryTable = LEReferenceToArrayOf<LigatureSubstitutionStateEntry2>(stHeader, success, entryTableOffset, LE_UNBOUNDED_ARRAY);
+}
+
+LigatureSubstitutionProcessor2::~LigatureSubstitutionProcessor2()
+{
+}
+
+void LigatureSubstitutionProcessor2::beginStateTable()
+{
+    m = -1;
+}
+
+le_uint16 LigatureSubstitutionProcessor2::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex2 index, LEErrorCode &success)
+{
+    const LigatureSubstitutionStateEntry2 *entry = entryTable.getAlias(index, success);
+    if(LE_FAILURE(success)) return 0;
+
+    le_uint16 nextStateIndex = SWAPW(entry->nextStateIndex);
+    le_uint16 flags = SWAPW(entry->entryFlags);
+    le_uint16 ligActionIndex = SWAPW(entry->ligActionIndex);
+
+    if (flags & lsfSetComponent) {
+        if (++m >= nComponents) {
+            m = 0;
+        }
+        componentStack[m] = currGlyph;
+    } else if ( m == -1) {
+        // bad font- skip this glyph.
+        //LE_DEBUG_BAD_FONT("m==-1 (componentCount went negative)")
+        currGlyph+= dir;
+        return nextStateIndex;
+    }
+
+    ByteOffset actionOffset = flags & lsfPerformAction;
+
+    if (actionOffset != 0) {
+        LEReferenceTo<LigatureActionEntry> ap(stHeader, success, ligActionOffset); // byte offset
+        ap.addObject(ligActionIndex - 1, success);  // index offset ( one before the actual start, because we will pre-increment)
+        LEReferenceToArrayOf<TTGlyphID> ligatureTable(stHeader, success, ligatureOffset, LE_UNBOUNDED_ARRAY);
+        LigatureActionEntry action;
+        le_int32 offset, i = 0;
+        le_int32 stack[nComponents];
+        le_int16 mm = -1;
+
+        LEReferenceToArrayOf<le_uint16> componentTable(stHeader, success, componentOffset, LE_UNBOUNDED_ARRAY);
+        if(LE_FAILURE(success)) {
+          currGlyph+= dir;
+            return nextStateIndex; // get out! bad font
+        }
+
+        do {
+            le_uint32 componentGlyph = componentStack[m--]; // pop off
+
+            ap.addObject(success);
+            action = SWAPL(*ap.getAlias());
+
+            if (m < 0) {
+                m = nComponents - 1;
+            }
+
+            offset = action & lafComponentOffsetMask;
+            if (offset != 0) {
+                if(componentGlyph > glyphStorage.getGlyphCount()) {
+                  LE_DEBUG_BAD_FONT("preposterous componentGlyph");
+                  currGlyph+= dir;
+                  return nextStateIndex; // get out! bad font
+                }
+                i += SWAPW(componentTable(LE_GET_GLYPH(glyphStorage[componentGlyph]) + (SignExtend(offset, lafComponentOffsetMask)),success));
+
+                if (action & (lafLast | lafStore))  {
+                  TTGlyphID ligatureGlyph = SWAPW(ligatureTable(i,success));
+                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], ligatureGlyph);
+                    if(mm==nComponents) {
+                      LE_DEBUG_BAD_FONT("exceeded nComponents");
+                      mm--; // don't overrun the stack.
+                    }
+                    stack[++mm] = componentGlyph;
+                    i = 0;
+                } else {
+                    glyphStorage[componentGlyph] = LE_SET_GLYPH(glyphStorage[componentGlyph], 0xFFFF);
+                }
+            }
+#if LE_ASSERT_BAD_FONT
+            if(m<0) {
+              LE_DEBUG_BAD_FONT("m<0")
+            }
+#endif
+        } while (!(action & lafLast) && (m>=0) ); // stop if last bit is set, or if run out of items
+
+        while (mm >= 0) {
+            if (++m >= nComponents) {
+                m = 0;
+            }
+
+            componentStack[m] = stack[mm--];
+        }
+    }
+
+    if (!(flags & lsfDontAdvance)) {
+        currGlyph += dir;
+    }
+
+    return nextStateIndex;
+}
+
+void LigatureSubstitutionProcessor2::endStateTable()
+{
+}
+
+U_NAMESPACE_END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/native/sun/font/layout/LigatureSubstProc2.h	Thu Apr 18 14:38:37 2013 -0700
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ *
+ */
+
+/*
+ *
+ * (C) Copyright IBM Corp.  and others 1998-2013 - All Rights Reserved
+ *
+ */
+
+#ifndef __LIGATURESUBSTITUTIONPROCESSOR2_H
+#define __LIGATURESUBSTITUTIONPROCESSOR2_H
+
+/**
+ * \file
+ * \internal
+ */
+
+#include "LETypes.h"
+#include "MorphTables.h"
+#include "SubtableProcessor2.h"
+#include "StateTableProcessor2.h"
+#include "LigatureSubstitution.h"
+
+U_NAMESPACE_BEGIN
+
+class LEGlyphStorage;
+
+#define nComponents 16
+
+class LigatureSubstitutionProcessor2 : public StateTableProcessor2
+{
+public:
+    virtual void beginStateTable();
+
+    virtual le_uint16 processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph,
+                                        EntryTableIndex2 index, LEErrorCode &success);
+
+    virtual void endStateTable();
+
+    LigatureSubstitutionProcessor2(const LEReferenceTo<MorphSubtableHeader2> &morphSubtableHeader, LEErrorCode &success);
+    virtual ~LigatureSubstitutionProcessor2();
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for the actual class.
+     *
+     * @stable ICU 2.8
+     */
+    virtual UClassID getDynamicClassID() const;
+
+    /**
+     * ICU "poor man's RTTI", returns a UClassID for this class.
+     *
+     * @stable ICU 2.8
+     */
+    static UClassID getStaticClassID();
+
+private:
+    LigatureSubstitutionProcessor2();
+
+protected:
+    le_uint32 ligActionOffset;
+    le_uint32 componentOffset;
+    le_uint32 ligatureOffset;
+
+    LEReferenceToArrayOf<LigatureSubstitutionStateEntry2> entryTable;
+
+    le_int32 componentStack[nComponents];
+    le_int16 m;
+
+    const LEReferenceTo<LigatureSubstitutionHeader2> ligatureSubstitutionHeader;
+
+};
+
+U_NAMESPACE_END
+#endif
--- a/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LigatureSubstSubtables.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -40,10 +40,10 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 LigatureSubstitutionSubtable::process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter) const
+le_uint32 LigatureSubstitutionSubtable::process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter) const
 {
     LEGlyphID glyph = glyphIterator->getCurrGlyphID();
-    le_int32 coverageIndex = getGlyphCoverage(glyph);
+    le_int32 coverageIndex = getGlyphCoverage(base, glyph, success);
 
     if (coverageIndex >= 0) {
         Offset ligSetTableOffset = SWAPW(ligSetTableOffsetArray[coverageIndex]);
--- a/src/share/native/sun/font/layout/LigatureSubstSubtables.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LigatureSubstSubtables.h	Thu Apr 18 14:38:37 2013 -0700
@@ -50,6 +50,7 @@
     le_uint16 ligatureCount;
     Offset    ligatureTableOffsetArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(LigatureSetTable, ligatureTableOffsetArray)
 
 struct LigatureTable
 {
@@ -57,14 +58,16 @@
     le_uint16 compCount;
     TTGlyphID componentArray[ANY_NUMBER];
 };
+LE_VAR_ARRAY(LigatureTable, componentArray)
 
 struct LigatureSubstitutionSubtable : GlyphSubstitutionSubtable
 {
     le_uint16 ligSetCount;
     Offset    ligSetTableOffsetArray[ANY_NUMBER];
 
-    le_uint32  process(GlyphIterator *glyphIterator, const LEGlyphFilter *filter = NULL) const;
+    le_uint32  process(const LETableReference &base, GlyphIterator *glyphIterator, LEErrorCode &success, const LEGlyphFilter *filter = NULL) const;
 };
+LE_VAR_ARRAY(LigatureSubstitutionSubtable, ligSetTableOffsetArray)
 
 U_NAMESPACE_END
 #endif
--- a/src/share/native/sun/font/layout/LigatureSubstitution.h	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LigatureSubstitution.h	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2004 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -52,17 +52,32 @@
     ByteOffset ligatureTableOffset;
 };
 
+struct LigatureSubstitutionHeader2 : MorphStateTableHeader2
+{
+    le_uint32 ligActionOffset;
+    le_uint32 componentOffset;
+    le_uint32 ligatureOffset;
+};
+
 enum LigatureSubstitutionFlags
 {
     lsfSetComponent     = 0x8000,
     lsfDontAdvance      = 0x4000,
-    lsfActionOffsetMask = 0x3FFF
+    lsfActionOffsetMask = 0x3FFF, // N/A in morx
+    lsfPerformAction    = 0x2000
 };
 
 struct LigatureSubstitutionStateEntry : StateEntry
 {
 };
 
+struct LigatureSubstitutionStateEntry2
+{
+    le_uint16 nextStateIndex;
+    le_uint16 entryFlags;
+    le_uint16 ligActionIndex;
+};
+
 typedef le_uint32 LigatureActionEntry;
 
 enum LigatureActionFlags
--- a/src/share/native/sun/font/layout/LookupProcessor.cpp	Wed Apr 17 12:13:43 2013 -0700
+++ b/src/share/native/sun/font/layout/LookupProcessor.cpp	Thu Apr 18 14:38:37 2013 -0700
@@ -25,7 +25,7 @@
 
 /*
  *
- * (C) Copyright IBM Corp. 1998-2010 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1998-2013 - All Rights Reserved
  *
  */
 
@@ -44,7 +44,7 @@
 
 U_NAMESPACE_BEGIN
 
-le_uint32 LookupProcessor::applyLookupTable(const LookupTable *lookupTable, GlyphIterator *glyphIterator,
+le_uint32 LookupProcessor::applyLookupTable(const LEReferenceTo<LookupTable> &lookupTable, GlyphIterator *glyphIterator,
                                          const LEFontInstance *fontInstance, LEErrorCode& success) const
 {
     if (LE_FAILURE(success)) {
@@ -57,7 +57,7 @@
     le_uint32 delta;
 
     for (le_uint16 subtable = 0; subtable < subtableCount; subtable += 1) {
-        const LookupSubtable *lookupSubtable = lookupTable->getLookupSubtable(subtable);
+      LEReferenceTo<LookupSubtable> lookupSubtable = lookupTable->getLookupSubtable(lookupTable, subtable, success);
 
         delta = applySubtable(lookupSubtable, lookupType, glyphIterator, fontInstance, success);
 
@@ -72,7 +72,7 @@
 }
 
 le_int32 LookupProcessor::process(LEGlyphStorage &glyphStorage, GlyphPositionAdjustments *glyphPositionAdjustments,
-                              le_bool rightToLeft, const GlyphDefinitionTableHeader *glyphDefinitionTableHeader,
+                                  le_bool rightToLeft, const LEReferenceTo<GlyphDefinitionTableHeader> &glyphDefinitionTableHeader,
                               const LEFontInstance *fontInstance, LEErrorCode& success) const
 {
     if (LE_FAILURE(success)) {
@@ -89,22 +89,21 @@
                                 rightToLeft, 0, 0, glyphDefinitionTableHeader);
     le_int32 newGlyphCount = glyphCount;
 
-    for (le_uint16 order = 0; order < lookupOrderCount; order += 1) {
+    for (le_uint16 order = 0; order < lookupOrderCount && LE_SUCCESS(success); order += 1) {
         le_uint16 lookup = lookupOrderArray[order];
         FeatureMask selectMask = lookupSelectArray[lookup];
 
         if (selectMask != 0) {
-            const LookupTable *lookupTable = lookupListTable->getLookupTable(lookup);
-
-            if (!lookupTable)
+          const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookup, success);
+          if (!lookupTable.isValid() ||LE_FAILURE(success) ) {
                 continue;
-
+            }
             le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
 
             glyphIterator.reset(lookupFlags, selectMask);
 
             while (glyphIterator.findFeatureTag()) {
-                applyLookupTable(lookupTable, &glyphIterator, fontInstance, success);
+              applyLookupTable(lookupTable, &glyphIterator, fontInstance, success); // TODO
                 if (LE_FAILURE(success)) {
                     return 0;
                 }
@@ -124,7 +123,11 @@
         return 0;
     }
 
-    const LookupTable *lookupTable = lookupListTable->getLookupTable(lookupTableIndex);
+    const LEReferenceTo<LookupTable> lookupTable = lookupListTable->getLookupTable(lookupListTable, lookupTableIndex, success);
+    if (!lookupTable.isValid()) {
+        success = LE_INTERNAL_ERROR;
+        return 0;
+    }
     le_uint16 lookupFlags = SWAPW(lookupTable->lookupFlags);
     GlyphIterator tempIterator(*glyphIterator, lookupFlags);
     le_uint32 delta = applyLookupTable(lookupTable, &tempIterator, fontInstance, success);
@@ -132,33 +135,35 @@
     return delta;
 }
 
-le_int32 LookupProcessor::selectLookups(const FeatureTable *featureTable, FeatureMask featureMask, le_int32 order)
+le_int32 LookupProcessor::selectLookups(const LEReferenceTo<FeatureTable> &featureTable, FeatureMask featureMask, le_int32 order, LEErrorCode &success)
 {
-    le_uint16 lookupCount = featureTable? SWAPW(featureTable->lookupCount) : 0;
+  le_uint16 lookupCount = featureTable.isValid()? SWAPW(featureTable->lookupCount) : 0;
     le_int32  store = order;
 
-    for (le_uint16 lookup = 0; lookup < lookupCount; lookup += 1) {
-        le_uint16 lookupListIndex = SWAPW(featureTable->lookupListIndexArray[lookup]);
+    LEReferenceToArrayOf<le_uint16> lookupListIndexArray(featureTable, success, featureTable->lookupListIndexArray, lookupCount);
 
-        if (lookupListIndex >= lookupSelectCount)
-            continue;
+    for (le_uint16 lookup = 0; LE_SUCCESS(success) && lookup < lookupCount; lookup += 1) {
+      le_uint16 lookupListIndex = SWAPW(lookupListIndexArray.getObject(lookup,success));
+      if (lookupListIndex >= lookupSelectCount) {
+        continue;
+      }
 
-        lookupSelectArray[lookupListIndex] |= featureMask;
-        lookupOrderArray[store++] = lookupListIndex;
+      lookupSelectArray[lookupListIndex] |= featureMask;
+      lookupOrderArray[store++] = lookupListIndex;
     }
 
     return store - order;
 }
 
-LookupProcessor::LookupProcessor(const char *baseAddress,
+LookupProcessor::LookupProcessor(const LETableReference &baseAddress,
         Offset scriptListOffset, Offset featureListOffset, Offset lookupListOffset,
         LETag scriptTag, LETag languageTag, const FeatureMap *featureMap, le_int32 featureMapCount, le_bool orderFeatures,
         LEErrorCode& success)
-    : lookupListTable(NULL), featureListTable(NULL), lookupSelectArray(NULL), lookupSelectCount(0),
-      lookupOrderArray(NULL), lookupOrderCount(0)
+    : lookupListTable(), featureListTable(), lookupSelectArray(NULL), lookupSelectCount(0),
+      lookupOrderArray(NULL), lookupOrderCount(0), fReference(baseAddress)
 {
-    const ScriptListTable *scriptListTable = NULL;
-    const LangSysTable *langSysTable = NULL;
+  LEReferenceTo<ScriptListTable> scriptListTable;
+  LEReferenceTo<LangSysTable> langSysTable;
     le_uint16 featureCount = 0;
     le_uint16 lookupListCount = 0;
     le_uint16 requiredFeatureIndex;
@@ -168,29 +173,33 @@
     }
 
     if (scriptListOffset != 0) {
-        scriptListTable = (const ScriptListTable *) (baseAddress + scriptListOffset);
-        langSysTable = scriptListTable->findLanguage(scriptTag, languageTag);
+      scriptListTable = LEReferenceTo<ScriptListTable>(baseAddress, success, scriptListOffset);
+      langSysTable = scriptListTable->findLanguage(scriptListTable, scriptTag, languageTag, success);
 
-        if (langSysTable != 0) {
-            featureCount = SWAPW(langSysTable->featureCount);
-        }
+      if (langSysTable.isValid() && LE_SUCCESS(success)) {
+        featureCount = SWAPW(langSysTable->featureCount);
+      }
     }
 
     if (featureListOffset != 0) {
-        featureListTable = (const FeatureListTable *) (baseAddress + featureListOffset);
+      featureListTable = LEReferenceTo<FeatureListTable>(baseAddress, success, featureListOffset);
     }
 
     if (lookupListOffset != 0) {
-        lookupListTable = (const LookupListTable *) (baseAddress + lookupListOffset);
+      lookupListTable = LEReferenceTo<LookupListTable>(baseAddress,success, lookupListOffset);
+      if(LE_SUCCESS(success) && lookupListTable.isValid()) {
         lookupListCount = SWAPW(lookupListTable->lookupCount);
+      }
     }
 
-    if (langSysTable == NULL || featureListTable == NULL || lookupListTable == NULL ||
+    if (langSysTable.isEmpty() || featureListTable.isEmpty() || lookupListTable.isEmpty() ||
         featureCount == 0 || lookupListCount == 0) {
         return;
     }
 
-    requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
+    if(langSysTable.isValid()) {
+      requiredFeatureIndex = SWAPW(langSysTable->reqFeatureIndex);
+    }
 
     lookupSelectArray = LE_NEW_ARRAY(FeatureMask, lookupListCount);
     if (lookupSelectArray == NULL) {
@@ -205,31 +214,39 @@
     lookupSelectCount = lookupListCount;
 
     le_int32 count, order = 0;
-    le_int32 featureReferences = 0;
-    const FeatureTable *featureTable = NULL;
+    le_uint32 featureReferences = 0;
+    LEReferenceTo<FeatureTable> featureTable;
     LETag featureTag;
 
-    const FeatureTable *requiredFeatureTable = NULL;
+    LEReferenceTo<FeatureTable> requiredFeatureTable;
     LETag requiredFeatureTag = 0x00000000U;
 
     // Count the total number of lookups referenced by all features. This will
     // be the maximum number of entries in the lookupOrderArray. We can't use
     // lookupListCount because some lookups might be referenced by more than
     // one feature.
-    for (le_int32 feature = 0; feature < featureCount; feature += 1) {
-        le_uint16 featureIndex = SWAPW(langSysTable->featureIndexArray[feature]);
+    if(featureListTable.isValid() && LE_SUCCESS(success)) {
+      LEReferenceToArrayOf<le_uint16> featureIndexArray(langSysTable, success, langSysTable->featureIndexArray, featureCount);
 
-        featureTable = featureListTable->getFeatureTable(featureIndex, &featureTag);
+      for (le_uint32 feature = 0; LE_SUCCESS(success)&&(feature < featureCount); feature += 1) {
+        le_uint16 featureIndex = SWAPW(featureIndexArray.getObject(feature, success));
 
-        if (!featureTable)
-            continue;
+        featureTable = featureListTable->getFeatureTable(featureListTable, featureIndex,  &featureTag, success);
+        if (!featureTable.isValid() || LE_FAILURE(success)) {
+          continue;
+        }
+        featureReferences +=