changeset 27513:0638b9ab226b

Merge
author ddehaven
date Wed, 12 Nov 2014 09:20:12 -0800
parents 10c5f7509a99 0438995dba34
children b31703bbd2cb 4fc210ca031f ce958253b829
files
diffstat 26 files changed, 2447 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Wed Nov 12 10:47:08 2014 +0800
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Wed Nov 12 09:20:12 2014 -0800
@@ -678,7 +678,7 @@
         final long nsWindowPtr = getNSWindowPtr();
         LWCToolkit lwcToolkit = (LWCToolkit) Toolkit.getDefaultToolkit();
         Window w = DefaultKeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
-        if( w != null
+        if( w != null && w.getPeer() != null
                 && ((LWWindowPeer)w.getPeer()).getPeerType() == LWWindowPeer.PeerType.EMBEDDED_FRAME
                 && !lwcToolkit.isApplicationActive()) {
             lwcToolkit.activateApplicationIgnoringOtherApps();
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m	Wed Nov 12 10:47:08 2014 +0800
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLGraphicsConfig.m	Wed Nov 12 09:20:12 2014 -0800
@@ -72,7 +72,9 @@
             }
             [pool drain];
             free(ctxinfo);
+            oglc->ctxInfo = NULL;
         }
+        cglinfo->context = NULL;
     }
 
     free(cglinfo);
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m	Wed Nov 12 10:47:08 2014 +0800
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/java2d/opengl/CGLSurfaceData.m	Wed Nov 12 09:20:12 2014 -0800
@@ -187,6 +187,11 @@
     }
 
     OGLContext *oglc = cglInfo->context;
+    if (oglc == NULL) {
+        J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLSD_SetScratchContext: ogl context is null");
+        return NULL;
+    }
+
     CGLCtxInfo *ctxinfo = (CGLCtxInfo *)oglc->ctxInfo;
 
 JNF_COCOA_ENTER(env);
--- a/jdk/src/java.desktop/share/classes/java/awt/Component.java	Wed Nov 12 10:47:08 2014 +0800
+++ b/jdk/src/java.desktop/share/classes/java/awt/Component.java	Wed Nov 12 09:20:12 2014 -0800
@@ -8607,7 +8607,7 @@
      * @param propertyName the programmatic name of the property
      *          that was changed
      * @param oldValue the old value of the property (as a short)
-     * @param newValue the old value of the property (as a short)
+     * @param newValue the new value of the property (as a short)
      * @see #firePropertyChange(java.lang.String, java.lang.Object,
      *          java.lang.Object)
      * @since 1.5
--- a/jdk/src/java.desktop/share/classes/java/awt/Robot.java	Wed Nov 12 10:47:08 2014 +0800
+++ b/jdk/src/java.desktop/share/classes/java/awt/Robot.java	Wed Nov 12 09:20:12 2014 -0800
@@ -34,9 +34,12 @@
 import java.awt.image.WritableRaster;
 import java.awt.peer.RobotPeer;
 import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+
 import sun.awt.AWTPermissions;
 import sun.awt.ComponentFactory;
 import sun.awt.SunToolkit;
+import sun.awt.OSInfo;
 import sun.awt.image.SunWritableRaster;
 
 /**
@@ -555,15 +558,21 @@
      */
     public synchronized void waitForIdle() {
         checkNotDispatchThread();
-        // post a dummy event to the queue so we know when
-        // all the events before it have been processed
+
         try {
             SunToolkit.flushPendingEvents();
-            EventQueue.invokeAndWait( new Runnable() {
-                                            public void run() {
-                                                // dummy implementation
-                                            }
-                                        } );
+            // 7185258: realSync() call blocks all DnD tests on OS X
+            if (AccessController.doPrivileged(OSInfo.getOSTypeAction()) == OSInfo.OSType.MACOSX) {
+                // post a dummy event to the queue so we know when
+                // all the events before it have been processed
+                EventQueue.invokeAndWait( new Runnable() {
+                                                public void run() {
+                                                    // dummy implementation
+                                                }
+                                            } );
+            } else {
+                ((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
+            }
         } catch(InterruptedException ite) {
             System.err.println("Robot.waitForIdle, non-fatal exception caught:");
             ite.printStackTrace();
--- a/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java	Wed Nov 12 10:47:08 2014 +0800
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java	Wed Nov 12 09:20:12 2014 -0800
@@ -1320,7 +1320,8 @@
      */
     public void actionPerformed(ActionEvent e) {
         ComboBoxEditor editor = getEditor();
-        if ((editor != null) && (e != null) && (editor == e.getSource())) {
+        if ((editor != null) && (e != null)
+                && (editor.getEditorComponent() == e.getSource())) {
             setPopupVisible(false);
             getModel().setSelectedItem(editor.getItem());
             String oldCommand = getActionCommand();
--- a/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java	Wed Nov 12 10:47:08 2014 +0800
+++ b/jdk/src/java.desktop/share/classes/sun/java2d/pipe/DrawImage.java	Wed Nov 12 09:20:12 2014 -0800
@@ -278,18 +278,34 @@
                                      Color bgColor, int interpType,
                                      double coords[])
     {
-        double dx = coords[0];
-        double dy = coords[1];
-        double dw = coords[2] - dx;
-        double dh = coords[3] - dy;
+        double dx1 = coords[0];
+        double dy1 = coords[1];
+        double dx2 = coords[2];
+        double dy2 = coords[3];
+        double dw = dx2 - dx1;
+        double dh = dy2 - dy1;
+
+        /* If any of the destination coordinates exceed the integer range,
+         * then the calculations performed in calls made here cannot be
+         * guaranteed to be correct, or to converge (terminate).
+         * So return out of here, deferring to code that can handle this.
+         */
+        if (dx1 < Integer.MIN_VALUE || dx1 > Integer.MAX_VALUE ||
+            dy1 < Integer.MIN_VALUE || dy1 > Integer.MAX_VALUE ||
+            dx2 < Integer.MIN_VALUE || dx2 > Integer.MAX_VALUE ||
+            dy2 < Integer.MIN_VALUE || dy2 > Integer.MAX_VALUE)
+        {
+            return false;
+        }
+
         // First check if width and height are very close to img w&h.
         if (closeToInteger(sx2-sx1, dw) && closeToInteger(sy2-sy1, dh)) {
             // Round location to nearest pixel and then test
             // if it will cause interpolation anomalies.
-            int idx = (int) Math.floor(dx + 0.5);
-            int idy = (int) Math.floor(dy + 0.5);
+            int idx = (int) Math.floor(dx1 + 0.5);
+            int idy = (int) Math.floor(dy1 + 0.5);
             if (interpType == AffineTransformOp.TYPE_NEAREST_NEIGHBOR ||
-                (closeToInteger(idx, dx) && closeToInteger(idy, dy)))
+                (closeToInteger(idx, dx1) && closeToInteger(idy, dy1)))
             {
                 renderImageCopy(sg, img, bgColor,
                                 idx, idy,
@@ -302,7 +318,7 @@
         if (dw > 0 && dh > 0) {
             if (renderImageScale(sg, img, bgColor, interpType,
                                  sx1, sy1, sx2, sy2,
-                                 coords[0], coords[1], coords[2], coords[3]))
+                                 dx1, dy1, dx2, dy2))
             {
                 return true;
             }
@@ -494,7 +510,7 @@
         // We need to transform to a temp image and then copy
         // just the pieces that are valid data to the dest.
         BufferedImage tmpimg = new BufferedImage(dx2-dx1, dy2-dy1,
-                                                 BufferedImage.TYPE_INT_ARGB);
+                                                 BufferedImage.TYPE_INT_ARGB_PRE);
         SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg);
         SurfaceType tmpType = tmpData.getSurfaceType();
         MaskBlit tmpmaskblit =
--- a/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java	Wed Nov 12 10:47:08 2014 +0800
+++ b/jdk/src/java.desktop/windows/classes/sun/java2d/d3d/D3DBlitLoops.java	Wed Nov 12 09:20:12 2014 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2014, 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
@@ -48,7 +48,7 @@
 import static sun.java2d.pipe.BufferedOpCodes.*;
 import sun.java2d.windows.GDIWindowSurfaceData;
 
-class D3DBlitLoops {
+final class D3DBlitLoops {
 
     static void register() {
         Blit blitIntArgbPreToSurface =
@@ -57,7 +57,9 @@
         Blit blitIntArgbPreToTexture =
             new D3DSwToTextureBlit(SurfaceType.IntArgbPre,
                                    D3DSurfaceData.ST_INT_ARGB_PRE);
-
+        TransformBlit transformBlitIntArgbPreToSurface =
+            new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre,
+                                        D3DSurfaceData.ST_INT_ARGB_PRE);
         GraphicsPrimitive[] primitives = {
             // prevent D3DSurface -> Screen blits
             new D3DSurfaceToGDIWindowSurfaceBlit(),
@@ -123,8 +125,6 @@
 
             new D3DSwToSurfaceTransform(SurfaceType.IntArgb,
                                         D3DSurfaceData.ST_INT_ARGB),
-            new D3DSwToSurfaceTransform(SurfaceType.IntArgbPre,
-                                        D3DSurfaceData.ST_INT_ARGB_PRE),
             new D3DSwToSurfaceTransform(SurfaceType.IntRgb,
                                         D3DSurfaceData.ST_INT_RGB),
             new D3DSwToSurfaceTransform(SurfaceType.IntBgr,
@@ -140,6 +140,9 @@
             // REMIND: we don't have a native sw loop to back this loop up
 //            new D3DSwToSurfaceTransform(SurfaceType.ByteIndexedBm,
 //                                        D3DSurfaceData.ST_BYTE_INDEXED_BM),
+            transformBlitIntArgbPreToSurface,
+
+            new D3DGeneralTransformedBlit(transformBlitIntArgbPreToSurface),
 
             // texture->surface ops
             new D3DTextureToSurfaceBlit(),
@@ -712,11 +715,11 @@
  * This general Blit implementation converts any source surface to an
  * intermediate IntArgbPre surface, and then uses the more specific
  * IntArgbPre->D3DSurface/Texture loop to get the intermediate
- * (premultiplied) surface down to D3D.
+ * (premultiplied) surface down to D3D using simple blit.
  */
 class D3DGeneralBlit extends Blit {
 
-    private Blit performop;
+    private final Blit performop;
     private WeakReference<SurfaceData> srcTmp;
 
     D3DGeneralBlit(SurfaceType dstType,
@@ -757,6 +760,49 @@
     }
 }
 
+/**
+ * This general TransformedBlit implementation converts any source surface to an
+ * intermediate IntArgbPre surface, and then uses the more specific
+ * IntArgbPre->D3DSurface/Texture loop to get the intermediate
+ * (premultiplied) surface down to D3D using simple transformBlit.
+ */
+final class D3DGeneralTransformedBlit extends TransformBlit {
+
+    private final TransformBlit performop;
+    private WeakReference<SurfaceData> srcTmp;
+
+    D3DGeneralTransformedBlit(final TransformBlit performop) {
+        super(SurfaceType.Any, CompositeType.AnyAlpha,
+                D3DSurfaceData.D3DSurface);
+        this.performop = performop;
+    }
+
+    @Override
+    public synchronized void Transform(SurfaceData src, SurfaceData dst,
+                                       Composite comp, Region clip,
+                                       AffineTransform at, int hint, int srcx,
+                                       int srcy, int dstx, int dsty, int width,
+                                       int height){
+        Blit convertsrc = Blit.getFromCache(src.getSurfaceType(),
+                                            CompositeType.SrcNoEa,
+                                            SurfaceType.IntArgbPre);
+        // use cached intermediate surface, if available
+        final SurfaceData cachedSrc = srcTmp != null ? srcTmp.get() : null;
+        // convert source to IntArgbPre
+        src = convertFrom(convertsrc, src, srcx, srcy, width, height, cachedSrc,
+                          BufferedImage.TYPE_INT_ARGB_PRE);
+
+        // transform IntArgbPre intermediate surface to D3D surface
+        performop.Transform(src, dst, comp, clip, at, hint, 0, 0, dstx, dsty,
+                            width, height);
+
+        if (src != cachedSrc) {
+            // cache the intermediate surface
+            srcTmp = new WeakReference<>(src);
+        }
+    }
+}
+
 /*
  * The following classes prohibit copying D3DSurfaces to the screen
  * (the D3D->sysmem->GDI path is known to be very very slow).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.html	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,21 @@
+<html>
+<!--  
+  @test
+  @bug 4051487 4145670
+  @summary Tests that disposing of an empty Frame or a Frame with a MenuBar
+           while it is being created does not crash the VM.
+  @author dpm area=Threads
+  @run applet/timeout=7200 DisposeStressTest.html
+  -->
+<head>
+<title>DisposeStressTest</title>
+</head>
+<body>
+
+<h1>DisposeStressTest<br>Bug ID: 4051487, 4145670</h1>
+
+<p> This is an AUTOMATIC test, simply wait for completion </p>
+
+<APPLET CODE="DisposeStressTest.class" WIDTH=200 HEIGHT=200></APPLET>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/DisposeStressTest/DisposeStressTest.java	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+
+/*
+  test
+  @bug 4051487 4145670 8062021
+  @summary Tests that disposing of an empty Frame or a Frame with a MenuBar
+           while it is being created does not crash the VM.
+  @author dpm area=Threads
+  @run applet/timeout=7200 DisposeStressTest.html
+*/
+
+// Note there is no @ in front of test above.  This is so that the
+//  harness will not mistake this file as a test file.  It should
+//  only see the html file as a test file. (the harness runs all
+//  valid test files, so it would run this test twice if this file
+//  were valid as well as the html file.)
+// Also, note the area= after Your Name in the author tag.  Here, you
+//  should put which functional area the test falls in.  See the
+//  AWT-core home page -> test areas and/or -> AWT team  for a list of
+//  areas.
+// Note also the 'DisposeStressTest.html' in the run tag.  This should
+//  be changed to the name of the test.
+
+
+/**
+ * DisposeStressTest.java
+ *
+ * summary:
+ */
+
+import java.applet.Applet;
+import java.awt.*;
+
+
+//Automated tests should run as applet tests if possible because they
+// get their environments cleaned up, including AWT threads, any
+// test created threads, and any system resources used by the test
+// such as file descriptors.  (This is normally not a problem as
+// main tests usually run in a separate VM, however on some platforms
+// such as the Mac, separate VMs are not possible and non-applet
+// tests will cause problems).  Also, you don't have to worry about
+// synchronisation stuff in Applet tests they way you do in main
+// tests...
+
+
+public class DisposeStressTest extends Applet
+ {
+   //Declare things used in the test, like buttons and labels here
+
+   public void init()
+    {
+      //Create instructions for the user here, as well as set up
+      // the environment -- set the layout manager, add buttons,
+      // etc.
+
+      this.setLayout (new BorderLayout ());
+
+      String[] instructions =
+       {
+         "This is an AUTOMATIC test",
+         "simply wait until it is done"
+       };
+      Sysout.createDialog( );
+      Sysout.printInstructions( instructions );
+
+    }//End  init()
+
+   public void start ()
+    {
+        for (int i = 0; i < 1000; i++) {
+            Frame f = new Frame();
+            f.setBounds(10, 10, 10, 10);
+            f.show();
+            f.dispose();
+
+            Frame f2 = new Frame();
+            f2.setBounds(10, 10, 100, 100);
+            MenuBar bar = new MenuBar();
+            Menu menu = new Menu();
+            menu.add(new MenuItem("foo"));
+            bar.add(menu);
+            f2.setMenuBar(bar);
+            f2.show();
+            f2.dispose();
+        }
+    }// start()
+
+ }// class DisposeStressTest
+
+
+/****************************************************
+ Standard Test Machinery
+ DO NOT modify anything below -- it's a standard
+  chunk of code whose purpose is to make user
+  interaction uniform, and thereby make it simpler
+  to read and understand someone else's test.
+ ****************************************************/
+
+/**
+ This is part of the standard test machinery.
+ It creates a dialog (with the instructions), and is the interface
+  for sending text messages to the user.
+ To print the instructions, send an array of strings to Sysout.createDialog
+  WithInstructions method.  Put one line of instructions per array entry.
+ To display a message for the tester to see, simply call Sysout.println
+  with the string to be displayed.
+ This mimics System.out.println but works within the test harness as well
+  as standalone.
+ */
+
+class Sysout
+ {
+   private static TestDialog dialog;
+
+   public static void createDialogWithInstructions( String[] instructions )
+    {
+      dialog = new TestDialog( new Frame(), "Instructions" );
+      dialog.printInstructions( instructions );
+      dialog.show();
+      println( "Any messages for the tester will display here." );
+    }
+
+   public static void createDialog( )
+    {
+      dialog = new TestDialog( new Frame(), "Instructions" );
+      String[] defInstr = { "Instructions will appear here. ", "" } ;
+      dialog.printInstructions( defInstr );
+      dialog.show();
+      println( "Any messages for the tester will display here." );
+    }
+
+
+   public static void printInstructions( String[] instructions )
+    {
+      dialog.printInstructions( instructions );
+    }
+
+
+   public static void println( String messageIn )
+    {
+      dialog.displayMessage( messageIn );
+    }
+
+ }// Sysout  class
+
+/**
+  This is part of the standard test machinery.  It provides a place for the
+   test instructions to be displayed, and a place for interactive messages
+   to the user to be displayed.
+  To have the test instructions displayed, see Sysout.
+  To have a message to the user be displayed, see Sysout.
+  Do not call anything in this dialog directly.
+  */
+class TestDialog extends Dialog
+ {
+
+   TextArea instructionsText;
+   TextArea messageText;
+   int maxStringLength = 80;
+
+   //DO NOT call this directly, go through Sysout
+   public TestDialog( Frame frame, String name )
+    {
+      super( frame, name );
+      int scrollBoth = TextArea.SCROLLBARS_BOTH;
+      instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
+      add( "North", instructionsText );
+
+      messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
+      add("South", messageText);
+
+      pack();
+
+      show();
+    }// TestDialog()
+
+   //DO NOT call this directly, go through Sysout
+   public void printInstructions( String[] instructions )
+    {
+      //Clear out any current instructions
+      instructionsText.setText( "" );
+
+      //Go down array of instruction strings
+
+      String printStr, remainingStr;
+      for( int i=0; i < instructions.length; i++ )
+       {
+         //chop up each into pieces maxSringLength long
+         remainingStr = instructions[ i ];
+         while( remainingStr.length() > 0 )
+          {
+            //if longer than max then chop off first max chars to print
+            if( remainingStr.length() >= maxStringLength )
+             {
+               //Try to chop on a word boundary
+               int posOfSpace = remainingStr.
+                  lastIndexOf( ' ', maxStringLength - 1 );
+
+               if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
+
+               printStr = remainingStr.substring( 0, posOfSpace + 1 );
+               remainingStr = remainingStr.substring( posOfSpace + 1 );
+             }
+            //else just print
+            else
+             {
+               printStr = remainingStr;
+               remainingStr = "";
+             }
+
+            instructionsText.append( printStr + "\n" );
+
+          }// while
+
+       }// for
+
+    }//printInstructions()
+
+   //DO NOT call this directly, go through Sysout
+   public void displayMessage( String messageIn )
+    {
+      messageText.append( messageIn + "\n" );
+    }
+
+ }// TestDialog  class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/geom/AffineTransform/GetTypeOptimization.java	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,307 @@
+/*
+ * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 4418285
+ * @summary Tests that transforms modified with degenerate operations
+ *          continue to return their more optimal type from getType().
+ *          This test also confirms that isIdentity() returns the
+ *          optimal value under all histories of modification.
+ * @run main GetTypeOptimization
+ */
+
+import java.awt.geom.AffineTransform;
+import java.util.Random;
+
+public class GetTypeOptimization {
+    static int TYPE_IDENTITY          = AffineTransform.TYPE_IDENTITY;
+    static int TYPE_TRANSLATION       = AffineTransform.TYPE_TRANSLATION;
+    static int TYPE_UNIFORM_SCALE     = AffineTransform.TYPE_UNIFORM_SCALE;
+    static int TYPE_GENERAL_SCALE     = AffineTransform.TYPE_GENERAL_SCALE;
+    static int TYPE_FLIP              = AffineTransform.TYPE_FLIP;
+    static int TYPE_QUADRANT_ROTATION = AffineTransform.TYPE_QUADRANT_ROTATION;
+    static int TYPE_GENERAL_ROTATION  = AffineTransform.TYPE_GENERAL_ROTATION;
+    static int TYPE_GENERAL_TRANSFORM = AffineTransform.TYPE_GENERAL_TRANSFORM;
+
+    public static Random rand = new Random();
+
+    public static boolean verbose;
+    public static int numerrors;
+
+    public static void main(String argv[]) {
+        verbose = (argv.length != 0);
+
+        checkBug4418285();
+
+        checkAtType(new AffineTransform());
+        checkAtType(AffineTransform.getTranslateInstance(0, 0));
+        checkAtType(AffineTransform.getScaleInstance(1, 1));
+        checkAtType(AffineTransform.getShearInstance(0, 0));
+        checkAtType(AffineTransform.getRotateInstance(0));
+        checkAtType(AffineTransform.getRotateInstance(0, 0, 0));
+        for (int i = 90; i <= 360; i += 90) {
+            double angle = Math.toRadians(i);
+            checkAtType(AffineTransform.getRotateInstance(angle));
+            checkAtType(AffineTransform.getRotateInstance(angle, 0, 0));
+        }
+
+        AffineTransform at = new AffineTransform();
+        checkAtType(at);
+
+        at.setToIdentity(); checkAtType(at);
+        at.setToTranslation(0.0, 0.0); checkAtType(at);
+        at.setToScale(1.0, 1.0); checkAtType(at);
+        at.setToShear(0.0, 0.0); checkAtType(at);
+        at.setToRotation(0); checkAtType(at);
+        at.setToRotation(0, 0, 0); checkAtType(at);
+        for (int i = 90; i <= 360; i += 90) {
+            double angle = Math.toRadians(i);
+            at.setToRotation(angle); checkAtType(at);
+            at.setToRotation(angle, 0, 0); checkAtType(at);
+        }
+
+        at.setToIdentity(); at.scale(1, 1); checkAtType(at);
+        at.setToIdentity(); at.translate(0, 0); checkAtType(at);
+        at.setToIdentity(); at.shear(0, 0); checkAtType(at);
+        at.setToIdentity(); at.rotate(0); checkAtType(at);
+        for (int i = 90; i <= 360; i += 90) {
+            double angle = Math.toRadians(i);
+            at.setToIdentity(); at.rotate(angle); checkAtType(at);
+            at.setToIdentity(); at.rotate(angle, 0, 0); checkAtType(at);
+        }
+
+        at.setToIdentity();
+        for (int i = 0; i < 4; i++) {
+            at.rotate(Math.toRadians(90)); checkAtType(at);
+        }
+
+        at.setToIdentity();
+        at.scale(2, 2); checkAtType(at);
+        at.scale(.5, .5); checkAtType(at);
+
+        for (int n = 1; n <= 3; n++) {
+            for (int i = 0; i < 500; i++) {
+                checkAtType(makeRandomTransform(n));
+            }
+        }
+        if (numerrors != 0) {
+            if (!verbose) {
+                System.err.println("Rerun test with an argument for details");
+            }
+            throw new RuntimeException(numerrors+" tests failed!");
+        }
+    }
+
+    public static void checkBug4418285() {
+        AffineTransform id =
+            new AffineTransform ();
+        AffineTransform translate0 =
+            AffineTransform.getTranslateInstance (0, 0);
+        if (id.isIdentity() != translate0.isIdentity() ||
+            id.getType() != translate0.getType())
+        {
+            numerrors++;
+            if (verbose) {
+                System.err.println("id=        " + id         +
+                                   ", isIdentity()=" +
+                                   id.isIdentity());
+                System.err.println("translate0=" + translate0 +
+                                   ", isIdentity()=" +
+                                   translate0.isIdentity());
+                System.err.println("equals="     + id.equals (translate0));
+                System.err.println();
+            }
+        }
+    }
+
+    public static AffineTransform makeRandomTransform(int numops) {
+        AffineTransform at = new AffineTransform();
+        while (--numops >= 0) {
+            switch (rand.nextInt(4)) {
+            case 0:
+                at.scale(rand.nextDouble() * 5 - 2.5,
+                         rand.nextDouble() * 5 - 2.5);
+                break;
+            case 1:
+                at.shear(rand.nextDouble() * 5 - 2.5,
+                         rand.nextDouble() * 5 - 2.5);
+                break;
+            case 2:
+                at.rotate(rand.nextDouble() * Math.PI * 2);
+                break;
+            case 3:
+                at.translate(rand.nextDouble() * 50 - 25,
+                             rand.nextDouble() * 50 - 25);
+                break;
+            default:
+                throw new InternalError("bad case!");
+            }
+        }
+        return at;
+    }
+
+    public static void checkAtType(AffineTransform at) {
+        int reftype = getRefType(at);
+        boolean isident = isIdentity(at);
+        for (int i = 0; i < 5; i++) {
+            boolean atisident = at.isIdentity();
+            int attype = at.getType();
+            if (isident != atisident || reftype != attype) {
+                numerrors++;
+                if (verbose) {
+                    System.err.println(at+".isIdentity() == "+atisident);
+                    System.err.println(at+".getType() == "+attype);
+                    System.err.println("should be "+isident+", "+reftype);
+                    new Throwable().printStackTrace();
+                    System.err.println();
+                }
+                break;
+            }
+        }
+    }
+
+    public static boolean isIdentity(AffineTransform at) {
+        return (at.getScaleX() == 1 &&
+                at.getScaleY() == 1 &&
+                at.getShearX() == 0 &&
+                at.getShearY() == 0 &&
+                at.getTranslateX() == 0 &&
+                at.getTranslateY() == 0);
+
+    }
+
+    public static int getRefType(AffineTransform at) {
+        double m00 = at.getScaleX();
+        double m11 = at.getScaleY();
+        double m01 = at.getShearX();
+        double m10 = at.getShearY();
+        if (m00 * m01 + m10 * m11 != 0) {
+            // Transformed unit vectors are not perpendicular...
+            return TYPE_GENERAL_TRANSFORM;
+        }
+        int type = ((at.getTranslateX() != 0 || at.getTranslateY() != 0)
+                    ? TYPE_TRANSLATION : TYPE_IDENTITY);
+        boolean sgn0, sgn1;
+        if (m01 == 0 && m10 == 0) {
+            sgn0 = (m00 >= 0.0);
+            sgn1 = (m11 >= 0.0);
+            if (sgn0 == sgn1) {
+                if (sgn0) {
+                    // Both scaling factors non-negative - simple scale
+                    if (m00 != m11) {
+                        type |= TYPE_GENERAL_SCALE;
+                    } else if (m00 != 1.0) {
+                        type |= TYPE_UNIFORM_SCALE;
+                    }
+                } else {
+                    // Both scaling factors negative - 180 degree rotation
+                    type |= TYPE_QUADRANT_ROTATION;
+                    if (m00 != m11) {
+                        type |= TYPE_GENERAL_SCALE;
+                    } else if (m00 != -1.0) {
+                        type |= TYPE_UNIFORM_SCALE;
+                    }
+                }
+            } else {
+                // Scaling factor signs different - flip about some axis
+                type |= TYPE_FLIP;
+                if (m00 != -m11) {
+                    type |= TYPE_GENERAL_SCALE;
+                } else if (m00 != 1.0 && m00 != -1.0) {
+                    type |= TYPE_UNIFORM_SCALE;
+                }
+            }
+        } else if (m00 == 0 && m11 == 0) {
+            sgn0 = (m01 >= 0.0);
+            sgn1 = (m10 >= 0.0);
+            if (sgn0 != sgn1) {
+                // Different signs - simple 90 degree rotation
+                if (m01 != -m10) {
+                    type |= (TYPE_QUADRANT_ROTATION | TYPE_GENERAL_SCALE);
+                } else if (m01 != 1.0 && m01 != -1.0) {
+                    type |= (TYPE_QUADRANT_ROTATION | TYPE_UNIFORM_SCALE);
+                } else {
+                    type |= TYPE_QUADRANT_ROTATION;
+                }
+            } else {
+                // Same signs - 90 degree rotation plus an axis flip too
+                if (m01 == m10) {
+                    if (m01 == 0) {
+                        // All four m[01][01] elements are 0
+                        type |= TYPE_UNIFORM_SCALE;
+                    } else {
+                        // Note - shouldn't (1,1) be no scale at all?
+                        type |= (TYPE_QUADRANT_ROTATION |
+                                 TYPE_FLIP |
+                                 TYPE_UNIFORM_SCALE);
+                    }
+                } else {
+                    type |= (TYPE_QUADRANT_ROTATION |
+                             TYPE_FLIP |
+                             TYPE_GENERAL_SCALE);
+                }
+            }
+        } else {
+            if (m00 * m11 >= 0.0) {
+                // sgn(m00) == sgn(m11) therefore sgn(m01) == -sgn(m10)
+                // This is the "unflipped" (right-handed) state
+                if (m00 != m11 || m01 != -m10) {
+                    type |= (TYPE_GENERAL_ROTATION | TYPE_GENERAL_SCALE);
+                } else if (m00 == 0) {
+                    // then m11 == 0 also
+                    if (m01 == -m10) {
+                        type |= (TYPE_QUADRANT_ROTATION | TYPE_UNIFORM_SCALE);
+                    } else {
+                        type |= (TYPE_QUADRANT_ROTATION | TYPE_GENERAL_SCALE);
+                    }
+                } else if (m00 * m11 - m01 * m10 != 1.0) {
+                    type |= (TYPE_GENERAL_ROTATION | TYPE_UNIFORM_SCALE);
+                } else {
+                    type |= TYPE_GENERAL_ROTATION;
+                }
+            } else {
+                // sgn(m00) == -sgn(m11) therefore sgn(m01) == sgn(m10)
+                // This is the "flipped" (left-handed) state
+                if (m00 != -m11 || m01 != m10) {
+                    type |= (TYPE_GENERAL_ROTATION |
+                             TYPE_FLIP |
+                             TYPE_GENERAL_SCALE);
+                } else if (m01 == 0) {
+                    if (m00 == 1.0 || m00 == -1.0) {
+                        type |= TYPE_FLIP;
+                    } else {
+                        type |= (TYPE_FLIP | TYPE_UNIFORM_SCALE);
+                    }
+                } else if (m00 * m11 - m01 * m10 != 1.0) {
+                    type |= (TYPE_GENERAL_ROTATION |
+                             TYPE_FLIP |
+                             TYPE_UNIFORM_SCALE);
+                } else {
+                    type |= (TYPE_GENERAL_ROTATION | TYPE_FLIP);
+                }
+            }
+        }
+        return type;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/geom/AffineTransform/TestInvertMethods.java	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,483 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 4987374
+ * @summary Unit test for inversion methods:
+ *
+ *          AffineTransform.createInverse();
+ *          AffineTransform.invert();
+ *
+ * @author flar
+ * @run main TestInvertMethods
+ */
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.NoninvertibleTransformException;
+
+/*
+ * Instances of the inner class Tester are "nodes" which take an input
+ * AffineTransform (AT), modify it in some way and pass the modified
+ * AT onto another Tester node.
+ *
+ * There is one particular Tester node of note called theVerifier.
+ * This is a leaf node which takes the input AT and tests the various
+ * inversion methods on that matrix.
+ *
+ * Most of the other Tester nodes will perform a single affine operation
+ * on their input, such as a rotate by various angles, or a scale by
+ * various predefined scale  values, and then pass the modified AT on
+ * to the next node in the chain which may be a verifier or another
+ * modifier.
+ *
+ * The Tester instances can also be chained together using the chain
+ * method so that we can test not only matrices modified by some single
+ * affine operation (scale, rotate, etc.) but also composite matrices
+ * that represent multiple operations concatenated together.
+ */
+public class TestInvertMethods {
+    public static boolean verbose;
+
+    public static final double MAX_ULPS = 2.0;
+    public static double MAX_TX_ULPS = MAX_ULPS;
+    public static double maxulps = 0.0;
+    public static double maxtxulps = 0.0;
+    public static int numtests = 0;
+
+    public static void main(String argv[]) {
+        Tester rotate = new Tester.Rotate();
+        Tester scale = new Tester.Scale();
+        Tester shear = new Tester.Shear();
+        Tester translate = new Tester.Translate();
+
+        if (argv.length > 1) {
+            // This next line verifies that chaining works correctly...
+            scale.chain(translate.chain(new Tester.Debug())).test(false);
+            return;
+        }
+
+        verbose = (argv.length > 0);
+
+        new Tester.Identity().test(true);
+        translate.test(true);
+        scale.test(true);
+        rotate.test(true);
+        shear.test(true);
+        scale.chain(translate).test(true);
+        rotate.chain(translate).test(true);
+        shear.chain(translate).test(true);
+        translate.chain(scale).test(true);
+        translate.chain(rotate).test(true);
+        translate.chain(shear).test(true);
+        translate.chain(scale.chain(rotate.chain(shear))).test(false);
+        shear.chain(rotate.chain(scale.chain(translate))).test(false);
+
+        System.out.println(numtests+" tests performed");
+        System.out.println("Max scale and shear difference: "+maxulps+" ulps");
+        System.out.println("Max translate difference: "+maxtxulps+" ulps");
+    }
+
+    public abstract static class Tester {
+        public static AffineTransform IdentityTx = new AffineTransform();
+
+        /*
+         * This is the leaf node that performs inversion testing
+         * on the incoming AffineTransform.
+         */
+        public static final Tester theVerifier = new Tester() {
+            public void test(AffineTransform at, boolean full) {
+                numtests++;
+                AffineTransform inv1, inv2;
+                boolean isinvertible =
+                    (Math.abs(at.getDeterminant()) >= Double.MIN_VALUE);
+                try {
+                    inv1 = at.createInverse();
+                    if (!isinvertible) missingNTE("createInverse", at);
+                } catch (NoninvertibleTransformException e) {
+                    inv1 = null;
+                    if (isinvertible) extraNTE("createInverse", at);
+                }
+                inv2 = new AffineTransform(at);
+                try {
+                    inv2.invert();
+                    if (!isinvertible) missingNTE("invert", at);
+                } catch (NoninvertibleTransformException e) {
+                    if (isinvertible) extraNTE("invert", at);
+                }
+                if (verbose) System.out.println("at = "+at);
+                if (isinvertible) {
+                    if (verbose) System.out.println(" inv1 = "+inv1);
+                    if (verbose) System.out.println(" inv2 = "+inv2);
+                    if (!inv1.equals(inv2)) {
+                        report(at, inv1, inv2,
+                               "invert methods do not agree");
+                    }
+                    inv1.concatenate(at);
+                    inv2.concatenate(at);
+                    // "Fix" some values that don't always behave
+                    // well with all the math that we've done up
+                    // to this point.
+                    // See the note on the concatfix method below.
+                    concatfix(inv1);
+                    concatfix(inv2);
+                    if (verbose) System.out.println("  at*inv1 = "+inv1);
+                    if (verbose) System.out.println("  at*inv2 = "+inv2);
+                    if (!compare(inv1, IdentityTx)) {
+                        report(at, inv1, IdentityTx,
+                               "createInverse() check failed");
+                    }
+                    if (!compare(inv2, IdentityTx)) {
+                        report(at, inv2, IdentityTx,
+                               "invert() check failed");
+                    }
+                } else {
+                    if (verbose) System.out.println(" is not invertible");
+                }
+                if (verbose) System.out.println();
+            }
+
+            void missingNTE(String methodname, AffineTransform at) {
+                throw new RuntimeException("Noninvertible was not "+
+                                           "thrown from "+methodname+
+                                           " for: "+at);
+            }
+
+            void extraNTE(String methodname, AffineTransform at) {
+                throw new RuntimeException("Unexpected Noninvertible "+
+                                           "thrown from "+methodname+
+                                           " for: "+at);
+            }
+        };
+
+        /*
+         * The inversion math may work out fairly exactly, but when
+         * we concatenate the inversions back with the original matrix
+         * in an attempt to restore them to the identity matrix,
+         * then we can end up compounding errors to a fairly high
+         * level, particularly if the component values had mantissas
+         * that were repeating fractions.  This function therefore
+         * "fixes" the results of concatenating the inversions back
+         * with their original matrices to get rid of small variations
+         * in the values that should have ended up being 0.0.
+         */
+        public void concatfix(AffineTransform at) {
+            double m00 = at.getScaleX();
+            double m10 = at.getShearY();
+            double m01 = at.getShearX();
+            double m11 = at.getScaleY();
+            double m02 = at.getTranslateX();
+            double m12 = at.getTranslateY();
+            if (Math.abs(m02) < 1E-10) m02 = 0.0;
+            if (Math.abs(m12) < 1E-10) m12 = 0.0;
+            if (Math.abs(m01) < 1E-15) m01 = 0.0;
+            if (Math.abs(m10) < 1E-15) m10 = 0.0;
+            at.setTransform(m00, m10,
+                            m01, m11,
+                            m02, m12);
+        }
+
+        public void test(boolean full) {
+            test(IdentityTx, full);
+        }
+
+        public void test(AffineTransform init, boolean full) {
+            test(init, theVerifier, full);
+        }
+
+        public void test(AffineTransform init, Tester next, boolean full) {
+            next.test(init, full);
+        }
+
+        public Tester chain(Tester next) {
+            return new Chain(this, next);
+        }
+
+        /*
+         * Utility node used to chain together two other nodes for
+         * implementing the "chain" method.
+         */
+        public static class Chain extends Tester {
+            Tester prev;
+            Tester next;
+
+            public Chain(Tester prev, Tester next) {
+                this.prev = prev;
+                this.next = next;
+            }
+
+            public void test(AffineTransform init, boolean full) {
+                prev.test(init, next, full);
+            }
+
+            public Tester chain(Tester next) {
+                this.next = this.next.chain(next);
+                return this;
+            }
+        }
+
+        /*
+         * Utility node for testing.
+         */
+        public static class Fail extends Tester {
+            public void test(AffineTransform init, Tester next, boolean full) {
+                throw new RuntimeException("Debug: Forcing failure");
+            }
+        }
+
+        /*
+         * Utility node for testing that chaining works.
+         */
+        public static class Debug extends Tester {
+            public void test(AffineTransform init, Tester next, boolean full) {
+                new Throwable().printStackTrace();
+                next.test(init, full);
+            }
+        }
+
+        /*
+         * NOP node.
+         */
+        public static class Identity extends Tester {
+            public void test(AffineTransform init, Tester next, boolean full) {
+                if (verbose) System.out.println("*Identity = "+init);
+                next.test(init, full);
+            }
+        }
+
+        /*
+         * Affine rotation node.
+         */
+        public static class Rotate extends Tester {
+            public void test(AffineTransform init, Tester next, boolean full) {
+                int inc = full ? 10 : 45;
+                for (int i = -720; i <= 720; i += inc) {
+                    AffineTransform at2 = new AffineTransform(init);
+                    at2.rotate(Math.toRadians(i));
+                    if (verbose) System.out.println("*Rotate("+i+") = "+at2);
+                    next.test(at2, full);
+                }
+            }
+        }
+
+        public static final double SMALL_VALUE = .0001;
+        public static final double LARGE_VALUE = 10000;
+
+        /*
+         * Affine scale node.
+         */
+        public static class Scale extends Tester {
+            public double fullvals[] = {
+                // Noninvertibles
+                0.0, 0.0,
+                0.0, 1.0,
+                1.0, 0.0,
+
+                // Invertibles
+                SMALL_VALUE, SMALL_VALUE,
+                SMALL_VALUE, 1.0,
+                1.0, SMALL_VALUE,
+
+                SMALL_VALUE, LARGE_VALUE,
+                LARGE_VALUE, SMALL_VALUE,
+
+                LARGE_VALUE, LARGE_VALUE,
+                LARGE_VALUE, 1.0,
+                1.0, LARGE_VALUE,
+
+                0.5, 0.5,
+                1.0, 1.0,
+                2.0, 2.0,
+                Math.PI, Math.E,
+            };
+            public double abbrevvals[] = {
+                0.0, 0.0,
+                1.0, 1.0,
+                2.0, 3.0,
+            };
+
+            public void test(AffineTransform init, Tester next, boolean full) {
+                double scales[] = (full ? fullvals : abbrevvals);
+                for (int i = 0; i < scales.length; i += 2) {
+                    AffineTransform at2 = new AffineTransform(init);
+                    at2.scale(scales[i], scales[i+1]);
+                    if (verbose) System.out.println("*Scale("+scales[i]+", "+
+                                                    scales[i+1]+") = "+at2);
+                    next.test(at2, full);
+                }
+            }
+        }
+
+        /*
+         * Affine shear node.
+         */
+        public static class Shear extends Tester {
+            public double fullvals[] = {
+                0.0, 0.0,
+                0.0, 1.0,
+                1.0, 0.0,
+
+                // Noninvertible
+                1.0, 1.0,
+
+                SMALL_VALUE, SMALL_VALUE,
+                SMALL_VALUE, LARGE_VALUE,
+                LARGE_VALUE, SMALL_VALUE,
+                LARGE_VALUE, LARGE_VALUE,
+
+                Math.PI, Math.E,
+            };
+            public double abbrevvals[] = {
+                0.0, 0.0,
+                0.0, 1.0,
+                1.0, 0.0,
+
+                // Noninvertible
+                1.0, 1.0,
+            };
+
+            public void test(AffineTransform init, Tester next, boolean full) {
+                double shears[] = (full ? fullvals : abbrevvals);
+                for (int i = 0; i < shears.length; i += 2) {
+                    AffineTransform at2 = new AffineTransform(init);
+                    at2.shear(shears[i], shears[i+1]);
+                    if (verbose) System.out.println("*Shear("+shears[i]+", "+
+                                                    shears[i+1]+") = "+at2);
+                    next.test(at2, full);
+                }
+            }
+        }
+
+        /*
+         * Affine translate node.
+         */
+        public static class Translate extends Tester {
+            public double fullvals[] = {
+                0.0, 0.0,
+                0.0, 1.0,
+                1.0, 0.0,
+
+                SMALL_VALUE, SMALL_VALUE,
+                SMALL_VALUE, LARGE_VALUE,
+                LARGE_VALUE, SMALL_VALUE,
+                LARGE_VALUE, LARGE_VALUE,
+
+                Math.PI, Math.E,
+            };
+            public double abbrevvals[] = {
+                0.0, 0.0,
+                0.0, 1.0,
+                1.0, 0.0,
+                Math.PI, Math.E,
+            };
+
+            public void test(AffineTransform init, Tester next, boolean full) {
+                double translates[] = (full ? fullvals : abbrevvals);
+                for (int i = 0; i < translates.length; i += 2) {
+                    AffineTransform at2 = new AffineTransform(init);
+                    at2.translate(translates[i], translates[i+1]);
+                    if (verbose) System.out.println("*Translate("+
+                                                    translates[i]+", "+
+                                                    translates[i+1]+") = "+at2);
+                    next.test(at2, full);
+                }
+            }
+        }
+    }
+
+    public static void report(AffineTransform orig,
+                              AffineTransform at1, AffineTransform at2,
+                              String message)
+    {
+        System.out.println(orig+", type = "+orig.getType());
+        System.out.println(at1+", type = "+at1.getType());
+        System.out.println(at2+", type = "+at2.getType());
+        System.out.println("ScaleX values differ by "+
+                           ulps(at1.getScaleX(),
+                                at2.getScaleX())+" ulps");
+        System.out.println("ScaleY values differ by "+
+                           ulps(at1.getScaleY(),
+                                at2.getScaleY())+" ulps");
+        System.out.println("ShearX values differ by "+
+                           ulps(at1.getShearX(),
+                                at2.getShearX())+" ulps");
+        System.out.println("ShearY values differ by "+
+                           ulps(at1.getShearY(),
+                                at2.getShearY())+" ulps");
+        System.out.println("TranslateX values differ by "+
+                           ulps(at1.getTranslateX(),
+                                at2.getTranslateX())+" ulps");
+        System.out.println("TranslateY values differ by "+
+                           ulps(at1.getTranslateY(),
+                                at2.getTranslateY())+" ulps");
+        throw new RuntimeException(message);
+    }
+
+    public static boolean compare(AffineTransform at1, AffineTransform at2) {
+        maxulps = Math.max(maxulps, ulps(at1.getScaleX(), at2.getScaleX()));
+        maxulps = Math.max(maxulps, ulps(at1.getScaleY(), at2.getScaleY()));
+        maxulps = Math.max(maxulps, ulps(at1.getShearX(), at2.getShearX()));
+        maxulps = Math.max(maxulps, ulps(at1.getShearY(), at2.getShearY()));
+        maxtxulps = Math.max(maxtxulps,
+                             ulps(at1.getTranslateX(), at2.getTranslateX()));
+        maxtxulps = Math.max(maxtxulps,
+                             ulps(at1.getTranslateY(), at2.getTranslateY()));
+        return (getModifiedType(at1) == getModifiedType(at2) &&
+                (compare(at1.getScaleX(), at2.getScaleX(), MAX_ULPS)) &&
+                (compare(at1.getScaleY(), at2.getScaleY(), MAX_ULPS)) &&
+                (compare(at1.getShearX(), at2.getShearX(), MAX_ULPS)) &&
+                (compare(at1.getShearY(), at2.getShearY(), MAX_ULPS)) &&
+                (compare(at1.getTranslateX(),
+                         at2.getTranslateX(), MAX_TX_ULPS)) &&
+                (compare(at1.getTranslateY(),
+                         at2.getTranslateY(), MAX_TX_ULPS)));
+    }
+
+    public static final int ANY_SCALE_MASK =
+        (AffineTransform.TYPE_UNIFORM_SCALE |
+         AffineTransform.TYPE_GENERAL_SCALE);
+    public static int getModifiedType(AffineTransform at) {
+        int type = at.getType();
+        // Some of the vector methods can introduce a tiny uniform scale
+        // at some angles...
+        if ((type & ANY_SCALE_MASK) != 0) {
+            maxulps = Math.max(maxulps, ulps(at.getDeterminant(), 1.0));
+            if (ulps(at.getDeterminant(), 1.0) <= MAX_ULPS) {
+                // Really tiny - we will ignore it
+                type &= ~ ANY_SCALE_MASK;
+            }
+        }
+        return type;
+    }
+
+    public static boolean compare(double val1, double val2, double maxulps) {
+        if (Math.abs(val1 - val2) < 1E-15) return true;
+        return (ulps(val1, val2) <= maxulps);
+    }
+
+    public static double ulps(double val1, double val2) {
+        double diff = Math.abs(val1 - val2);
+        double ulpmax = Math.min(Math.ulp(val1), Math.ulp(val2));
+        return (diff / ulpmax);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/geom/AffineTransform/TestRotateMethods.java	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 4980035
+ * @summary Unit test for new methods:
+ *
+ *          AffineTransform.getRotateInstance(double x, double y);
+ *          AffineTransform.setToRotation(double x, double y);
+ *          AffineTransform.rotate(double x, double y);
+ *
+ *          AffineTransform.getQuadrantRotateInstance(int numquads);
+ *          AffineTransform.setToQuadrantRotation(int numquads);
+ *          AffineTransform.quadrantRotate(int numquads);
+ *
+ * @author flar
+ * @run main TestRotateMethods
+ */
+
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+
+public class TestRotateMethods {
+    /* The maximum errors allowed, measured in double precision "ulps"
+     * Note that for most fields, the tests are extremely accurate - to
+     * within 3 ulps of the smaller value in the comparison
+     * For the translation components, the tests are still very accurate,
+     * but the absolute number of ulps can be noticeably higher when we
+     * use one of the rotate methods that takes an anchor point.
+     * Since a double precision value has 56 bits of precision, even
+     * 1024 ulps is extremely small as a ratio of the value.
+     */
+    public static final double MAX_ULPS = 3.0;
+    public static final double MAX_ANCHOR_TX_ULPS = 1024.0;
+    public static double MAX_TX_ULPS = MAX_ULPS;
+
+    // Vectors for quadrant rotations
+    public static final double quadxvec[] = {  1.0,  0.0, -1.0,  0.0 };
+    public static final double quadyvec[] = {  0.0,  1.0,  0.0, -1.0 };
+
+    // Run tests once for each type of method:
+    //     tx = AffineTransform.get<Rotate>Instance()
+    //     tx.set<Rotate>()
+    //     tx.<rotate>()
+    public static enum Mode { GET, SET, MOD };
+
+    // Used to accumulate and report largest differences encountered by tests
+    public static double maxulps = 0.0;
+    public static double maxtxulps = 0.0;
+
+    // Sample anchor points for testing.
+    public static Point2D zeropt = new Point2D.Double(0, 0);
+    public static Point2D testtxpts[] = {
+        new Point2D.Double(       5,      5),
+        new Point2D.Double(      20,    -10),
+        new Point2D.Double(-Math.PI, Math.E),
+    };
+
+    public static void main(String argv[]) {
+        test(Mode.GET);
+        test(Mode.SET);
+        test(Mode.MOD);
+
+        System.out.println("Max scale and shear difference: "+maxulps+" ulps");
+        System.out.println("Max translate difference: "+maxtxulps+" ulps");
+    }
+
+    public static void test(Mode mode) {
+        MAX_TX_ULPS = MAX_ULPS; // Stricter tx testing with no anchor point
+        test(mode, 0.5, null);
+        test(mode, 1.0, null);
+        test(mode, 3.0, null);
+
+        // Anchor points make the tx values less reliable
+        MAX_TX_ULPS = MAX_ANCHOR_TX_ULPS;
+        for (int i = 0; i < testtxpts.length; i++) {
+            test(mode, 1.0, testtxpts[i]);
+        }
+        MAX_TX_ULPS = MAX_ULPS; // Restore to default
+    }
+
+    public static void verify(AffineTransform at1, AffineTransform at2,
+                              Mode mode, double vectorscale, Point2D txpt,
+                              String message, double num, String units)
+    {
+        if (!compare(at1, at2)) {
+            System.out.println("mode == "+mode);
+            System.out.println("vectorscale == "+vectorscale);
+            System.out.println("txpt == "+txpt);
+            System.out.println(at1+", type = "+at1.getType());
+            System.out.println(at2+", type = "+at2.getType());
+            System.out.println("ScaleX values differ by "+
+                               ulps(at1.getScaleX(), at2.getScaleX())+" ulps");
+            System.out.println("ScaleY values differ by "+
+                               ulps(at1.getScaleY(), at2.getScaleY())+" ulps");
+            System.out.println("ShearX values differ by "+
+                               ulps(at1.getShearX(), at2.getShearX())+" ulps");
+            System.out.println("ShearY values differ by "+
+                               ulps(at1.getShearY(), at2.getShearY())+" ulps");
+            System.out.println("TranslateX values differ by "+
+                               ulps(at1.getTranslateX(),
+                                    at2.getTranslateX())+" ulps");
+            System.out.println("TranslateY values differ by "+
+                               ulps(at1.getTranslateY(),
+                                    at2.getTranslateY())+" ulps");
+            throw new RuntimeException(message + num + units);
+        }
+    }
+
+    public static void test(Mode mode, double vectorscale, Point2D txpt) {
+        AffineTransform at1, at2, at3;
+
+        for (int deg = -720; deg <= 720; deg++) {
+            if ((deg % 90) == 0) continue;
+            double radians = Math.toRadians(deg);
+            double vecy = Math.sin(radians) * vectorscale;
+            double vecx = Math.cos(radians) * vectorscale;
+
+            at1 = makeAT(mode, txpt, radians);
+            at2 = makeAT(mode, txpt, vecx, vecy);
+            verify(at1, at2, mode, vectorscale, txpt,
+                   "vector and radians do not match for ", deg, " degrees");
+
+            if (txpt == null) {
+                // Make sure output was same as a with a 0,0 anchor point
+                if (vectorscale == 1.0) {
+                    // Only need to test radians method for one scale factor
+                    at3 = makeAT(mode, zeropt, radians);
+                    verify(at1, at3, mode, vectorscale, zeropt,
+                           "radians not invariant with 0,0 translate at ",
+                           deg, " degrees");
+                }
+                // But test vector methods with all scale factors
+                at3 = makeAT(mode, zeropt, vecx, vecy);
+                verify(at2, at3, mode, vectorscale, zeropt,
+                       "vector not invariant with 0,0 translate at ",
+                       deg, " degrees");
+            }
+        }
+
+        for (int quad = -8; quad <= 8; quad++) {
+            double degrees = quad * 90.0;
+            double radians = Math.toRadians(degrees);
+            double vecx = quadxvec[quad & 3] * vectorscale;
+            double vecy = quadyvec[quad & 3] * vectorscale;
+
+            at1 = makeAT(mode, txpt, radians);
+            at2 = makeAT(mode, txpt, vecx, vecy);
+            verify(at1, at2, mode, vectorscale, txpt,
+                   "quadrant vector and radians do not match for ",
+                   degrees, " degrees");
+            at2 = makeQuadAT(mode, txpt, quad);
+            verify(at1, at2, mode, vectorscale, txpt,
+                   "quadrant and radians do not match for ",
+                   quad, " quadrants");
+            if (txpt == null) {
+                at3 = makeQuadAT(mode, zeropt, quad);
+                verify(at2, at3, mode, vectorscale, zeropt,
+                       "quadrant not invariant with 0,0 translate at ",
+                       quad, " quadrants");
+            }
+        }
+    }
+
+    public static AffineTransform makeRandomAT() {
+        AffineTransform at = new AffineTransform();
+        at.scale(Math.random() * -10.0, Math.random() * 100.0);
+        at.rotate(Math.random() * Math.PI);
+        at.shear(Math.random(), Math.random());
+        at.translate(Math.random() * 300.0, Math.random() * -20.0);
+        return at;
+    }
+
+    public static AffineTransform makeAT(Mode mode, Point2D txpt,
+                                         double radians)
+    {
+        AffineTransform at;
+        double tx = (txpt == null) ? 0.0 : txpt.getX();
+        double ty = (txpt == null) ? 0.0 : txpt.getY();
+        switch (mode) {
+        case GET:
+            if (txpt != null) {
+                at = AffineTransform.getRotateInstance(radians, tx, ty);
+            } else {
+                at = AffineTransform.getRotateInstance(radians);
+            }
+            break;
+        case SET:
+            at = makeRandomAT();
+            if (txpt != null) {
+                at.setToRotation(radians, tx, ty);
+            } else {
+                at.setToRotation(radians);
+            }
+            break;
+        case MOD:
+            at = makeRandomAT();
+            at.setToIdentity();
+            if (txpt != null) {
+                at.rotate(radians, tx, ty);
+            } else {
+                at.rotate(radians);
+            }
+            break;
+        default:
+            throw new InternalError("unrecognized mode: "+mode);
+        }
+
+        return at;
+    }
+
+    public static AffineTransform makeAT(Mode mode, Point2D txpt,
+                                         double vx, double vy)
+    {
+        AffineTransform at;
+        double tx = (txpt == null) ? 0.0 : txpt.getX();
+        double ty = (txpt == null) ? 0.0 : txpt.getY();
+        switch (mode) {
+        case GET:
+            if (txpt != null) {
+                at = AffineTransform.getRotateInstance(vx, vy, tx, ty);
+            } else {
+                at = AffineTransform.getRotateInstance(vx, vy);
+            }
+            break;
+        case SET:
+            at = makeRandomAT();
+            if (txpt != null) {
+                at.setToRotation(vx, vy, tx, ty);
+            } else {
+                at.setToRotation(vx, vy);
+            }
+            break;
+        case MOD:
+            at = makeRandomAT();
+            at.setToIdentity();
+            if (txpt != null) {
+                at.rotate(vx, vy, tx, ty);
+            } else {
+                at.rotate(vx, vy);
+            }
+            break;
+        default:
+            throw new InternalError("unrecognized mode: "+mode);
+        }
+
+        return at;
+    }
+
+    public static AffineTransform makeQuadAT(Mode mode, Point2D txpt,
+                                             int quads)
+    {
+        AffineTransform at;
+        double tx = (txpt == null) ? 0.0 : txpt.getX();
+        double ty = (txpt == null) ? 0.0 : txpt.getY();
+        switch (mode) {
+        case GET:
+            if (txpt != null) {
+                at = AffineTransform.getQuadrantRotateInstance(quads, tx, ty);
+            } else {
+                at = AffineTransform.getQuadrantRotateInstance(quads);
+            }
+            break;
+        case SET:
+            at = makeRandomAT();
+            if (txpt != null) {
+                at.setToQuadrantRotation(quads, tx, ty);
+            } else {
+                at.setToQuadrantRotation(quads);
+            }
+            break;
+        case MOD:
+            at = makeRandomAT();
+            at.setToIdentity();
+            if (txpt != null) {
+                at.quadrantRotate(quads, tx, ty);
+            } else {
+                at.quadrantRotate(quads);
+            }
+            break;
+        default:
+            throw new InternalError("unrecognized mode: "+mode);
+        }
+
+        return at;
+    }
+
+    public static boolean compare(AffineTransform at1, AffineTransform at2) {
+        maxulps = Math.max(maxulps, ulps(at1.getScaleX(), at2.getScaleX()));
+        maxulps = Math.max(maxulps, ulps(at1.getScaleY(), at2.getScaleY()));
+        maxulps = Math.max(maxulps, ulps(at1.getShearX(), at2.getShearX()));
+        maxulps = Math.max(maxulps, ulps(at1.getShearY(), at2.getShearY()));
+        maxtxulps = Math.max(maxtxulps,
+                             ulps(at1.getTranslateX(), at2.getTranslateX()));
+        maxtxulps = Math.max(maxtxulps,
+                             ulps(at1.getTranslateY(), at2.getTranslateY()));
+        return (getModifiedType(at1) == getModifiedType(at2) &&
+                (compare(at1.getScaleX(), at2.getScaleX(), MAX_ULPS)) &&
+                (compare(at1.getScaleY(), at2.getScaleY(), MAX_ULPS)) &&
+                (compare(at1.getShearX(), at2.getShearX(), MAX_ULPS)) &&
+                (compare(at1.getShearY(), at2.getShearY(), MAX_ULPS)) &&
+                (compare(at1.getTranslateX(),
+                         at2.getTranslateX(), MAX_TX_ULPS)) &&
+                (compare(at1.getTranslateY(),
+                         at2.getTranslateY(), MAX_TX_ULPS)));
+    }
+
+    public static int getModifiedType(AffineTransform at) {
+        int type = at.getType();
+        // Some of the vector methods can introduce a tiny uniform scale
+        // at some angles...
+        if ((type & AffineTransform.TYPE_UNIFORM_SCALE) != 0) {
+            maxulps = Math.max(maxulps, ulps(at.getDeterminant(), 1.0));
+            if (ulps(at.getDeterminant(), 1.0) <= MAX_ULPS) {
+                // Really tiny - we will ignore it
+                type &= (~AffineTransform.TYPE_UNIFORM_SCALE);
+            }
+        }
+        return type;
+    }
+
+    public static boolean compare(double val1, double val2, double maxulps) {
+        return (ulps(val1, val2) <= maxulps);
+    }
+
+    public static double ulps(double val1, double val2) {
+        double diff = Math.abs(val1 - val2);
+        double ulpmax = Math.min(Math.ulp(val1), Math.ulp(val2));
+        return (diff / ulpmax);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/geom/AffineTransform/TestSerialization.java	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 6213608
+ * @summary Test that AffineTransform can deserialize appropriate versions.
+ * @author flar
+ * @run main TestSerialization
+ */
+
+import java.io.FileInputStream;
+import java.io.ObjectInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.FileOutputStream;
+import java.io.ObjectOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InvalidClassException;
+import java.awt.geom.AffineTransform;
+
+public class TestSerialization {
+    public static void main(String argv[]) {
+        if (argv.length > 0) {
+            System.out.println("Saving from: "+
+                               System.getProperty("java.version"));
+            writeSer(argv[0]);
+            return;
+        }
+        System.out.println("Testing on: "+System.getProperty("java.version"));
+        testReadWrite();
+        readSer("serial.1.2", true);
+    }
+
+    public static AffineTransform testATs[] = {
+        new AffineTransform(),
+        AffineTransform.getScaleInstance(2.5, -3.0),
+        AffineTransform.getRotateInstance(Math.PI / 4.0),
+        AffineTransform.getShearInstance(1.0, -3.0),
+        AffineTransform.getTranslateInstance(25.0, 12.5),
+        makeComplexAT(),
+    };
+
+    public static AffineTransform makeComplexAT() {
+        AffineTransform at = new AffineTransform();
+        at.scale(2.5, -3.0);
+        at.rotate(Math.PI / 4.0);
+        at.shear(1.0, -3.0);
+        at.translate(25.0, 12.5);
+        return at;
+    };
+
+    public static void testReadWrite() {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            testWrite(oos);
+            oos.flush();
+            oos.close();
+            byte buf[] = baos.toByteArray();
+            ByteArrayInputStream bais = new ByteArrayInputStream(buf);
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            testRead(ois, true);
+        } catch (InvalidClassException ice) {
+            throw new RuntimeException("Object read failed from loopback");
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("IOException testing loopback");
+        }
+    }
+
+    public static String resolve(String relfilename) {
+        String dir = System.getProperty("test.src");
+        if (dir == null) {
+            return relfilename;
+        } else {
+            return dir+"/"+relfilename;
+        }
+    }
+
+    public static void readSer(String filename, boolean shouldsucceed) {
+        try {
+            FileInputStream fis = new FileInputStream(resolve(filename));
+            ObjectInputStream ois = new ObjectInputStream(fis);
+            testRead(ois, shouldsucceed);
+        } catch (InvalidClassException ice) {
+            throw new RuntimeException("Object read failed from: "+filename);
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("IOException reading: "+filename);
+        }
+    }
+
+    public static void testRead(ObjectInputStream ois, boolean shouldsucceed)
+        throws IOException
+    {
+        for (int i = 0; i < testATs.length; i++) {
+            AffineTransform at;
+            try {
+                at = (AffineTransform) ois.readObject();
+                if (!shouldsucceed) {
+                    throw new RuntimeException("readObj did not fail");
+                }
+            } catch (ClassNotFoundException e) {
+                // Should never happen, but must catch declared exceptions...
+                throw new RuntimeException("AffineTransform not found!");
+            } catch (InvalidClassException e) {
+                if (shouldsucceed) {
+                    throw e;
+                }
+                continue;
+            }
+            if (!testATs[i].equals(at)) {
+                throw new RuntimeException("wrong AT read from stream");
+            }
+        }
+    }
+
+    public static void writeSer(String filename) {
+        try {
+            FileOutputStream fos = new FileOutputStream(filename);
+            ObjectOutputStream oos = new ObjectOutputStream(fos);
+            testWrite(oos);
+            oos.flush();
+            oos.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+            throw new RuntimeException("IOException writing: "+filename);
+        }
+    }
+
+    public static void testWrite(ObjectOutputStream oos)
+        throws IOException
+    {
+        for (int i = 0; i < testATs.length; i++) {
+            oos.writeObject(testATs[i]);
+        }
+    }
+}
Binary file jdk/test/java/awt/geom/AffineTransform/serial.1.2 has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/DrawImage/DrawImageCoordsTest.java	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+/*
+ * @test
+ * @bug 8028539
+ * @summary Test that drawing a scaled image terminates.
+ * @run main/othervm/timeout=60 DrawImageCoordsTest
+*/
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+
+public class DrawImageCoordsTest {
+
+    public static void main(String[] args) {
+
+        /* Create an image to draw, filled in solid red. */
+        BufferedImage srcImg =
+             new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
+        Graphics srcG = srcImg.createGraphics();
+        srcG.setColor(Color.red);
+        int w = srcImg.getWidth(null);
+        int h = srcImg.getHeight(null);
+        srcG.fillRect(0, 0, w, h);
+
+        /* Create a destination image */
+        BufferedImage dstImage =
+           new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
+        Graphics2D dstG = dstImage.createGraphics();
+        /* draw image under a scaling transform that overflows int */
+        AffineTransform tx = new AffineTransform(0.5, 0, 0, 0.5,
+                                                  0, 5.8658460197478485E9);
+        dstG.setTransform(tx);
+        dstG.drawImage(srcImg, 0, 0, null );
+        /* draw image under the same overflowing transform, cancelling
+         * out the 0.5 scale on the graphics
+         */
+        dstG.drawImage(srcImg, 0, 0, 2*w, 2*h, null);
+        if (Color.red.getRGB() == dstImage.getRGB(w/2, h/2)) {
+             throw new RuntimeException("Unexpected color: clipping failed.");
+        }
+        System.out.println("Test Thread Completed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/image/DrawImage/IncorrectAlphaConversionBicubic.java	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferInt;
+import java.awt.image.DataBufferShort;
+import java.awt.image.VolatileImage;
+
+import static java.awt.Transparency.TRANSLUCENT;
+
+/**
+ * @test
+ * @bug 8062164
+ * @summary We should get correct alpha, when we draw to/from VolatileImage and
+ *          bicubic interpolation is enabled
+ * @author Sergey Bylokhov
+ */
+public final class IncorrectAlphaConversionBicubic {
+
+    private static final Color RGB = new Color(200, 255, 7, 123);
+    private static final int SIZE = 100;
+
+    public static void main(final String[] args) {
+        final GraphicsEnvironment ge =
+                GraphicsEnvironment.getLocalGraphicsEnvironment();
+        final GraphicsDevice gd = ge.getDefaultScreenDevice();
+        final GraphicsConfiguration gc = gd.getDefaultConfiguration();
+        final VolatileImage vi =
+                gc.createCompatibleVolatileImage(SIZE, SIZE, TRANSLUCENT);
+        final BufferedImage bi = makeUnmanagedBI(gc, TRANSLUCENT);
+        final int expected = bi.getRGB(2, 2);
+
+        int attempt = 0;
+        BufferedImage snapshot;
+        while (true) {
+            if (++attempt > 10) {
+                throw new RuntimeException("Too many attempts: " + attempt);
+            }
+            vi.validate(gc);
+            final Graphics2D g2d = vi.createGraphics();
+            g2d.setComposite(AlphaComposite.Src);
+            g2d.scale(2, 2);
+            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
+                                 RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+            g2d.drawImage(bi, 0, 0, null);
+            g2d.dispose();
+
+            snapshot = vi.getSnapshot();
+            if (vi.contentsLost()) {
+                continue;
+            }
+            break;
+        }
+        final int actual = snapshot.getRGB(2, 2);
+        if (actual != expected) {
+            System.err.println("Actual: " + Integer.toHexString(actual));
+            System.err.println("Expected: " + Integer.toHexString(expected));
+            throw new RuntimeException("Test failed");
+        }
+    }
+
+    private static BufferedImage makeUnmanagedBI(GraphicsConfiguration gc,
+                                                 int type) {
+        BufferedImage img = gc.createCompatibleImage(SIZE, SIZE, type);
+        Graphics2D g2d = img.createGraphics();
+        g2d.setColor(RGB);
+        g2d.fillRect(0, 0, SIZE, SIZE);
+        g2d.dispose();
+        final DataBuffer db = img.getRaster().getDataBuffer();
+        if (db instanceof DataBufferInt) {
+            ((DataBufferInt) db).getData();
+        } else if (db instanceof DataBufferShort) {
+            ((DataBufferShort) db).getData();
+        } else if (db instanceof DataBufferByte) {
+            ((DataBufferByte) db).getData();
+        } else {
+            try {
+                img.setAccelerationPriority(0.0f);
+            } catch (final Throwable ignored) {
+            }
+        }
+        return img;
+    }
+}
--- a/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java	Wed Nov 12 10:47:08 2014 +0800
+++ b/jdk/test/java/awt/image/DrawImage/UnmanagedDrawImagePerformance.java	Wed Nov 12 09:20:12 2014 -0800
@@ -41,7 +41,7 @@
 
 /*
  * @test
- * @bug 8029253
+ * @bug 8029253 8059941
  * @summary Unmanaged images should be drawn fast.
  * @author Sergey Bylokhov
  */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JComboBox/8057893/bug8057893.java	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014, 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.
+ *
+ * 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.
+ */
+
+import java.awt.EventQueue;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.WindowConstants;
+import sun.awt.SunToolkit;
+
+/**
+ * @test
+ * @bug 8057893
+ * @author Alexander Scherbatiy
+ * @summary JComboBox actionListener never receives "comboBoxEdited"
+ *   from getActionCommand
+ * @run main bug8057893
+ */
+public class bug8057893 {
+
+    private static volatile boolean isComboBoxEdited = false;
+
+    public static void main(String[] args) throws Exception {
+        Robot robot = new Robot();
+        robot.setAutoDelay(50);
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+        EventQueue.invokeAndWait(() -> {
+            JFrame frame = new JFrame();
+            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
+            JComboBox<String> comboBox = new JComboBox<>(new String[]{"one", "two"});
+            comboBox.setEditable(true);
+            comboBox.addActionListener(new ActionListener() {
+
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    if ("comboBoxEdited".equals(e.getActionCommand())) {
+                        isComboBoxEdited = true;
+                    }
+                }
+            });
+            frame.add(comboBox);
+            frame.pack();
+            frame.setVisible(true);
+            comboBox.requestFocusInWindow();
+        });
+
+        toolkit.realSync();
+
+        robot.keyPress(KeyEvent.VK_A);
+        robot.keyRelease(KeyEvent.VK_A);
+        robot.keyPress(KeyEvent.VK_ENTER);
+        robot.keyRelease(KeyEvent.VK_ENTER);
+        toolkit.realSync();
+
+        if(!isComboBoxEdited){
+            throw new RuntimeException("ComboBoxEdited event is not fired!");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/4222153/bug4222153.html	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,31 @@
+<!--
+ Copyright (c) 1999, 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.
+
+ 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.
+-->
+
+<html>
+<body>
+Click in the upper-left cell and then press TAB two times.
+If table cell selection is not on the left cell of the second row
+then test fails.
+<applet  code="bug4222153.class" width=200 height=200></applet>
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/4222153/bug4222153.java	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1999, 2014, 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.
+ *
+ * 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.
+ */
+
+import javax.swing.JApplet;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+/**
+ * @test
+ * @bug 4222153
+ * @author Konstantin Eremin
+ * @run applet/manual=yesno bug4222153.html
+ */
+public class bug4222153 extends JApplet {
+
+    public void init() {
+        SwingUtilities.invokeLater(() -> {
+            try {
+                UIManager.setLookAndFeel(
+                        "javax.swing.plaf.metal.MetalLookAndFeel");
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+            getContentPane().add(new JTable(2, 2));
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.html	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,43 @@
+<!--
+ Copyright (c) 1999, 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.
+
+ 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.
+-->
+
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+  <head>
+    <title>Keyboard Navigation in JTable</title>
+  </head>
+
+  <body>
+    <h1>Keyboard Navigation in JTable</h1>
+    <applet code=KeyBoardNavigation width=500 height=200>
+    </applet>
+
+    <p>
+      Refer to bug report 4112270 for spec of keyboard navigation. Check all combinations of navigational keys in all four modes shift and control verifying each change to the selection against the spec.
+       If it does, press "pass", otherwise press "fail".
+    <hr>
+    <address><a href="mailto:milne@taller">Philip Milne</a></address>
+
+  </body>
+</html>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/KeyBoardNavigation/KeyBoardNavigation.java	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 1999, 2014, 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.
+ *
+ * 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.
+ */
+
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+
+import javax.swing.DefaultCellEditor;
+import javax.swing.JApplet;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.border.BevelBorder;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
+
+
+/**
+ * @test
+ * @bug 4112270
+ * @summary
+ *     Keyboard Navigation in JTable
+ * @author milne
+ * @run applet/manual=yesno KeyBoardNavigation.html
+ */
+public class KeyBoardNavigation extends JApplet
+{
+    static void initTest(Container contentPane)
+    {
+        // Take the dummy data from SwingSet.
+        final String[] names = {"First Name", "Last Name", "Favorite Color",
+                "Favorite Number", "Vegetarian"};
+        final Object[][] data = {
+                {"Mark", "Andrews", "Red", new Integer(2), new Boolean(true)},
+                {"Tom", "Ball", "Blue", new Integer(99), new Boolean(false)},
+                {"Alan", "Chung", "Green", new Integer(838), new Boolean(false)},
+                {"Jeff", "Dinkins", "Turquois", new Integer(8), new Boolean(true)},
+                {"Amy", "Fowler", "Yellow", new Integer(3), new Boolean(false)},
+                {"Brian", "Gerhold", "Green", new Integer(0), new Boolean(false)},
+                {"James", "Gosling", "Pink", new Integer(21), new Boolean(false)},
+                {"David", "Karlton", "Red", new Integer(1), new Boolean(false)},
+                {"Dave", "Kloba", "Yellow", new Integer(14), new Boolean(false)},
+                {"Peter", "Korn", "Purple", new Integer(12), new Boolean(false)},
+                {"Phil", "Milne", "Purple", new Integer(3), new Boolean(false)},
+                {"Dave", "Moore", "Green", new Integer(88), new Boolean(false)},
+                {"Hans", "Muller", "Maroon", new Integer(5), new Boolean(false)},
+                {"Rick", "Levenson", "Blue", new Integer(2), new Boolean(false)},
+                {"Tim", "Prinzing", "Blue", new Integer(22), new Boolean(false)},
+                {"Chester", "Rose", "Black", new Integer(0), new Boolean(false)},
+                {"Ray", "Ryan", "Gray", new Integer(77), new Boolean(false)},
+                {"Georges", "Saab", "Red", new Integer(4), new Boolean(false)},
+                {"Willie", "Walker", "Phthalo Blue", new Integer(4), new Boolean(false)},
+                {"Kathy", "Walrath", "Blue", new Integer(8), new Boolean(false)},
+                {"Arnaud", "Weber", "Green", new Integer(44), new Boolean(false)}
+        };
+
+        // Create a model of the data.
+        TableModel dataModel = new AbstractTableModel() {
+            // These methods always need to be implemented.
+            public int getColumnCount() { return names.length; }
+            public int getRowCount() { return data.length;}
+            public Object getValueAt(int row, int col) {return data[row][col];}
+
+            // The default implementations of these methods in
+            // AbstractTableModel would work, but we can refine them.
+            public String getColumnName(int column) {return names[column];}
+            public Class getColumnClass(int c) {return getValueAt(0, c).getClass();}
+            public boolean isCellEditable(int row, int col) {return true;}
+            public void setValueAt(Object aValue, int row, int column) {
+                System.out.println("Setting value to: " + aValue);
+                data[row][column] = aValue;
+            }
+        };
+
+        // Create the table
+        JTable tableView = new JTable(dataModel);
+        // Turn off auto-resizing so that we can set column sizes programmatically.
+        // In this mode, all columns will get their preferred widths, as set blow.
+        tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+
+        // Create a combo box to show that you can use one in a table.
+        JComboBox comboBox = new JComboBox();
+        comboBox.addItem("Red");
+        comboBox.addItem("Orange");
+        comboBox.addItem("Yellow");
+        comboBox.addItem("Green");
+        comboBox.addItem("Blue");
+        comboBox.addItem("Indigo");
+        comboBox.addItem("Violet");
+
+        TableColumn colorColumn = tableView.getColumn("Favorite Color");
+        // Use the combo box as the editor in the "Favorite Color" column.
+        colorColumn.setCellEditor(new DefaultCellEditor(comboBox));
+
+        // Set a pink background and tooltip for the Color column renderer.
+        DefaultTableCellRenderer colorColumnRenderer = new DefaultTableCellRenderer();
+        colorColumnRenderer.setBackground(Color.pink);
+        colorColumnRenderer.setToolTipText("Click for combo box");
+        colorColumn.setCellRenderer(colorColumnRenderer);
+
+        // Set a tooltip for the header of the colors column.
+        TableCellRenderer headerRenderer = colorColumn.getHeaderRenderer();
+        if (headerRenderer instanceof DefaultTableCellRenderer)
+            ((DefaultTableCellRenderer)headerRenderer).setToolTipText("Hi Mom!");
+
+        // Set the width of the "Vegetarian" column.
+        TableColumn vegetarianColumn = tableView.getColumn("Vegetarian");
+        vegetarianColumn.setPreferredWidth(100);
+
+        // Show the values in the "Favorite Number" column in different colors.
+        TableColumn numbersColumn = tableView.getColumn("Favorite Number");
+        DefaultTableCellRenderer numberColumnRenderer = new DefaultTableCellRenderer() {
+            public void setValue(Object value) {
+                int cellValue = (value instanceof Number) ? ((Number)value).intValue() : 0;
+                setForeground((cellValue > 30) ? Color.black : Color.red);
+                setText((value == null) ? "" : value.toString());
+            }
+        };
+        numberColumnRenderer.setHorizontalAlignment(JLabel.RIGHT);
+        numbersColumn.setCellRenderer(numberColumnRenderer);
+        numbersColumn.setPreferredWidth(110);
+
+        // Finish setting up the table.
+        JScrollPane scrollpane = new JScrollPane(tableView);
+        scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED));
+        scrollpane.setPreferredSize(new Dimension(430, 200));
+
+        contentPane.add(scrollpane);
+    }
+
+
+    public void init() {
+        SwingUtilities.invokeLater(() -> {
+            try {
+                UIManager.setLookAndFeel(
+                        "javax.swing.plaf.metal.MetalLookAndFeel");
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+
+            initTest(getContentPane());
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/TAB/TAB.html	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,43 @@
+<!--
+ Copyright (c) 1999, 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.
+
+ 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.
+-->
+
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+  <head>
+    <title>Tabbing test</title>
+  </head>
+
+  <body>
+    <h1>Tabbing test</h1>
+    <applet code=TAB width=500 height=200>
+    </applet>
+
+    <p>
+      Select a cell by double clicking it, press tab. Check that the focus moves to the next cell. 
+       If it does, press "pass", otherwise press "fail".
+    <hr>
+    <address><a href="mailto:milne@taller">Philip Milne</a></address>
+
+  </body>
+</html>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/JTable/TAB/TAB.java	Wed Nov 12 09:20:12 2014 -0800
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 1999, 2014, 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.
+ *
+ * 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.
+ */
+
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+
+import javax.swing.DefaultCellEditor;
+import javax.swing.JApplet;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.border.BevelBorder;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
+
+/**
+ * @test
+ * @bug 4128521
+ * @summary
+ *     Tabbing test
+ * @author milne
+ * @run applet/manual=yesno TAB.html
+ */
+public class TAB extends JApplet
+{
+    static void initTest(Container contentPane)
+    {
+        // Take the dummy data from SwingSet.
+        final String[] names = {"First Name", "Last Name", "Favorite Color",
+                "Favorite Number", "Vegetarian"};
+        final Object[][] data = {
+                {"Mark", "Andrews", "Red", new Integer(2), new Boolean(true)},
+                {"Tom", "Ball", "Blue", new Integer(99), new Boolean(false)},
+                {"Alan", "Chung", "Green", new Integer(838), new Boolean(false)},
+                {"Jeff", "Dinkins", "Turquois", new Integer(8), new Boolean(true)},
+                {"Amy", "Fowler", "Yellow", new Integer(3), new Boolean(false)},
+                {"Brian", "Gerhold", "Green", new Integer(0), new Boolean(false)},
+                {"James", "Gosling", "Pink", new Integer(21), new Boolean(false)},
+                {"David", "Karlton", "Red", new Integer(1), new Boolean(false)},
+                {"Dave", "Kloba", "Yellow", new Integer(14), new Boolean(false)},
+                {"Peter", "Korn", "Purple", new Integer(12), new Boolean(false)},
+                {"Phil", "Milne", "Purple", new Integer(3), new Boolean(false)},
+                {"Dave", "Moore", "Green", new Integer(88), new Boolean(false)},
+                {"Hans", "Muller", "Maroon", new Integer(5), new Boolean(false)},
+                {"Rick", "Levenson", "Blue", new Integer(2), new Boolean(false)},
+                {"Tim", "Prinzing", "Blue", new Integer(22), new Boolean(false)},
+                {"Chester", "Rose", "Black", new Integer(0), new Boolean(false)},
+                {"Ray", "Ryan", "Gray", new Integer(77), new Boolean(false)},
+                {"Georges", "Saab", "Red", new Integer(4), new Boolean(false)},
+                {"Willie", "Walker", "Phthalo Blue", new Integer(4), new Boolean(false)},
+                {"Kathy", "Walrath", "Blue", new Integer(8), new Boolean(false)},
+                {"Arnaud", "Weber", "Green", new Integer(44), new Boolean(false)}
+        };
+
+        // Create a model of the data.
+        TableModel dataModel = new AbstractTableModel() {
+            // These methods always need to be implemented.
+            public int getColumnCount() { return names.length; }
+            public int getRowCount() { return data.length;}
+            public Object getValueAt(int row, int col) {return data[row][col];}
+
+            // The default implementations of these methods in
+            // AbstractTableModel would work, but we can refine them.
+            public String getColumnName(int column) {return names[column];}
+            public Class getColumnClass(int c) {return getValueAt(0, c).getClass();}
+            public boolean isCellEditable(int row, int col) {return true;}
+            public void setValueAt(Object aValue, int row, int column) {
+                System.out.println("Setting value to: " + aValue);
+                data[row][column] = aValue;
+            }
+        };
+
+        // Create the table
+        JTable tableView = new JTable(dataModel);
+        // Turn off auto-resizing so that we can set column sizes programmatically.
+        // In this mode, all columns will get their preferred widths, as set blow.
+        tableView.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
+
+        // Create a combo box to show that you can use one in a table.
+        JComboBox comboBox = new JComboBox();
+        comboBox.addItem("Red");
+        comboBox.addItem("Orange");
+        comboBox.addItem("Yellow");
+        comboBox.addItem("Green");
+        comboBox.addItem("Blue");
+        comboBox.addItem("Indigo");
+        comboBox.addItem("Violet");
+
+        TableColumn colorColumn = tableView.getColumn("Favorite Color");
+        // Use the combo box as the editor in the "Favorite Color" column.
+        colorColumn.setCellEditor(new DefaultCellEditor(comboBox));
+
+        // Set a pink background and tooltip for the Color column renderer.
+        DefaultTableCellRenderer colorColumnRenderer = new DefaultTableCellRenderer();
+        colorColumnRenderer.setBackground(Color.pink);
+        colorColumnRenderer.setToolTipText("Click for combo box");
+        colorColumn.setCellRenderer(colorColumnRenderer);
+
+        // Set a tooltip for the header of the colors column.
+        TableCellRenderer headerRenderer = colorColumn.getHeaderRenderer();
+        if (headerRenderer instanceof DefaultTableCellRenderer)
+            ((DefaultTableCellRenderer)headerRenderer).setToolTipText("Hi Mom!");
+
+        // Set the width of the "Vegetarian" column.
+        TableColumn vegetarianColumn = tableView.getColumn("Vegetarian");
+        vegetarianColumn.setPreferredWidth(100);
+
+        // Show the values in the "Favorite Number" column in different colors.
+        TableColumn numbersColumn = tableView.getColumn("Favorite Number");
+        DefaultTableCellRenderer numberColumnRenderer = new DefaultTableCellRenderer() {
+            public void setValue(Object value) {
+                int cellValue = (value instanceof Number) ? ((Number)value).intValue() : 0;
+                setForeground((cellValue > 30) ? Color.black : Color.red);
+                setText((value == null) ? "" : value.toString());
+            }
+        };
+        numberColumnRenderer.setHorizontalAlignment(JLabel.RIGHT);
+        numbersColumn.setCellRenderer(numberColumnRenderer);
+        numbersColumn.setPreferredWidth(110);
+
+        // Finish setting up the table.
+        JScrollPane scrollpane = new JScrollPane(tableView);
+        scrollpane.setBorder(new BevelBorder(BevelBorder.LOWERED));
+        scrollpane.setPreferredSize(new Dimension(430, 200));
+
+        contentPane.add(scrollpane);
+    }
+
+
+    public void init() {
+        SwingUtilities.invokeLater(() -> {
+            try {
+                UIManager.setLookAndFeel(
+                        "javax.swing.plaf.metal.MetalLookAndFeel");
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+
+            initTest(getContentPane());
+        });
+    }
+}
--- a/jdk/test/lib/testlibrary/ExtendedRobot.java	Wed Nov 12 10:47:08 2014 +0800
+++ b/jdk/test/lib/testlibrary/ExtendedRobot.java	Wed Nov 12 09:20:12 2014 -0800
@@ -23,9 +23,6 @@
  * questions.
  */
 
-import sun.awt.ExtendedKeyCodes;
-import sun.awt.SunToolkit;
-
 import java.awt.AWTException;
 import java.awt.Robot;
 import java.awt.GraphicsDevice;
@@ -33,6 +30,7 @@
 import java.awt.Point;
 import java.awt.MouseInfo;
 import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
 
 /**
  * ExtendedRobot is a subclass of {@link java.awt.Robot}. It provides some convenience methods that are
@@ -178,8 +176,7 @@
      *          dispatching thread
      */
     public synchronized void waitForIdle(int delayValue) {
-        SunToolkit.flushPendingEvents();
-        ((SunToolkit) Toolkit.getDefaultToolkit()).realSync();
+        super.waitForIdle();
         delay(delayValue);
     }
 
@@ -382,7 +379,7 @@
      * @see     java.awt.event.KeyEvent
      */
     public void type(char c) {
-        type(ExtendedKeyCodes.getExtendedKeyCodeForChar(c));
+        type(KeyEvent.getExtendedKeyCodeForChar(c));
     }
 
     /**