changeset 29014:d42eb758b048

Merge
author ddehaven
date Tue, 17 Feb 2015 11:44:51 -0800
parents 71fe221460f5 6b20c10ac851
children 82642b0f0945 550dfa936f27
files jdk/make/src/classes/build/tools/module/boot.modules jdk/src/java.desktop/macosx/classes/sun/datatransfer/resources/flavormap.properties jdk/src/java.desktop/share/classes/java/awt/datatransfer/Clipboard.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/ClipboardOwner.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/DataFlavor.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/FlavorEvent.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/FlavorListener.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/FlavorMap.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/FlavorTable.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/MimeType.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/MimeTypeParameterList.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/MimeTypeParseException.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/StringSelection.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/SystemFlavorMap.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/Transferable.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/UnsupportedFlavorException.java jdk/src/java.desktop/share/classes/java/awt/datatransfer/package.html jdk/src/java.desktop/share/classes/sun/datatransfer/DataFlavorUtil.java jdk/src/java.desktop/share/classes/sun/datatransfer/DesktopDatatransferService.java jdk/src/java.desktop/unix/classes/sun/awt/X11/XAWTFormatter.java jdk/src/java.desktop/unix/classes/sun/datatransfer/resources/flavormap.properties jdk/src/java.desktop/windows/classes/sun/datatransfer/resources/flavormap.properties jdk/test/java/awt/color/LoadProfileWithSM.java jdk/test/java/awt/color/LoadStandardProfilesTest.java
diffstat 103 files changed, 8404 insertions(+), 6175 deletions(-) [+]
line wrap: on
line diff
--- a/jdk/make/copy/Copy-java.base.gmk	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/make/copy/Copy-java.base.gmk	Tue Feb 17 11:44:51 2015 -0800
@@ -60,16 +60,28 @@
 endif
 
 ################################################################################
-# Copy msvcrXX.dll on windows
+# Copy the microsoft runtime libraries on windows
+ifeq ($(OPENJDK_TARGET_OS), windows)
 
-ifeq ($(OPENJDK_TARGET_OS), windows)
-  MSVCR_TARGET := $(LIB_DST_DIR)/$(notdir $(MSVCR_DLL))
   # Chmod to avoid permission issues if bundles are unpacked on unix platforms.
-  $(MSVCR_TARGET): $(MSVCR_DLL)
-	$(call install-file)
+  define copy-and-chmod
+	$(install-file)
 	$(CHMOD) a+rx $@
+  endef
 
-  TARGETS += $(MSVCR_TARGET)
+  # Use separate macro calls in case the source files are not in the same
+  # directory.
+  $(eval $(call SetupCopyFiles,COPY_MSVCR, \
+      DEST := $(LIB_DST_DIR), \
+      FILES := $(MSVCR_DLL), \
+      MACRO := copy-and-chmod))
+
+  $(eval $(call SetupCopyFiles,COPY_MSVCP, \
+      DEST := $(LIB_DST_DIR), \
+      FILES := $(MSVCP_DLL), \
+      MACRO := copy-and-chmod))
+
+  TARGETS += $(COPY_MSVCR) $(COPY_MSVCP)
 endif
 
 ################################################################################
--- a/jdk/make/lib/Awt2dLibraries.gmk	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/make/lib/Awt2dLibraries.gmk	Tue Feb 17 11:44:51 2015 -0800
@@ -515,6 +515,77 @@
 
 ################################################################################
 
+ifeq ($(BUILD_HEADLESS), true)
+  # Mac and Windows only use the native AWT lib, do not build libawt_headless
+  ifeq ($(findstring $(OPENJDK_TARGET_OS), windows macosx),)
+
+    LIBAWT_HEADLESS_DIRS := $(JDK_TOPDIR)/src/java.desktop/unix/native/libawt_headless/awt \
+        $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/awt \
+        $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/java2d/opengl \
+        $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/java2d/x11 \
+        $(JDK_TOPDIR)/src/java.desktop/share/native/common/java2d/opengl \
+        $(JDK_TOPDIR)/src/java.desktop/share/native/common/font \
+        #
+
+    LIBAWT_HEADLESS_EXCLUDES := medialib
+    LIBAWT_HEADLESS_CFLAGS := -I$(SUPPORT_OUTPUTDIR)/headers/java.desktop \
+        $(addprefix -I, $(LIBAWT_HEADLESS_DIRS)) \
+        -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d \
+        -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d/loops \
+        -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/awt/image/cvutils \
+        -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d/pipe \
+        -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/awt/image \
+        -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libawt/java2d \
+        -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/font \
+        -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/awt/debug \
+        -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/font \
+        -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libsunwjdga/ \
+        $(LIBJAVA_HEADER_FLAGS) \
+        #
+
+    LIBAWT_HEADLESS_REORDER :=
+    ifeq ($(OPENJDK_TARGET_OS), solaris)
+      ifneq ($(OPENJDK_TARGET_CPU), x86_64)
+        LIBAWT_HEADLESS_REORDER := $(JDK_TOPDIR)/make/mapfiles/libawt_headless/reorder-$(OPENJDK_TARGET_CPU)
+      endif
+    endif
+
+    $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_HEADLESS, \
+        LIBRARY := awt_headless, \
+        OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+        SRC := $(LIBAWT_HEADLESS_DIRS), \
+        EXCLUDES := $(LIBAWT_HEADLESS_EXCLUDES), \
+        LANG := C, \
+        OPTIMIZATION := LOW, \
+        CFLAGS := $(CFLAGS_JDKLIB) \
+            -DHEADLESS=true \
+            -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \
+            $(CUPS_CFLAGS) \
+            $(X_CFLAGS) \
+            $(LIBAWT_HEADLESS_CFLAGS), \
+        MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libawt_headless/mapfile-vers, \
+        LDFLAGS := $(LDFLAGS_JDKLIB) \
+            $(call SET_SHARED_LIBRARY_ORIGIN), \
+        LDFLAGS_unix := -L$(INSTALL_LIBRARIES_HERE), \
+        LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \
+        LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \
+        LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_ORIGIN)., \
+        REORDER := $(LIBAWT_HEADLESS_REORDER), \
+        LDFLAGS_SUFFIX_linux := -ljvm -lawt -lm $(LIBDL) -ljava, \
+        LDFLAGS_SUFFIX_aix := -ljvm -lawt -ljava,\
+        LDFLAGS_SUFFIX_solaris := $(LIBDL) -ljvm -lawt -lm -ljava $(LIBCXX) -lc, \
+        OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libawt_headless, \
+        DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
+
+    $(BUILD_LIBAWT_HEADLESS): $(BUILD_LIBAWT)
+
+    TARGETS += $(BUILD_LIBAWT_HEADLESS)
+
+  endif
+endif
+
+################################################################################
+
 LIBFONTMANAGER_SRC := $(JDK_TOPDIR)/src/java.desktop/share/native/libfontmanager \
     $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libfontmanager
 LIBFONTMANAGER_CFLAGS := \
@@ -562,10 +633,6 @@
   BUILD_LIBFONTMANAGER_ExtensionSubtables.cpp_CXXFLAGS := -fno-strict-aliasing
 endif
 
-# Libfontmanager doesn't actually need X_LIBS to link, but if building
-# on a Solaris machine without X installed, using a devkit, linking
-# to libawt_xawt will fail without the -L parameters from X_LIBS. Filter
-# out the -R parameters since they aren't needed.
 $(eval $(call SetupNativeCompilation,BUILD_LIBFONTMANAGER, \
     LIBRARY := fontmanager, \
     OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
@@ -583,9 +650,8 @@
     LDFLAGS_unix := -L$(INSTALL_LIBRARIES_HERE), \
     LDFLAGS_SUFFIX := $(BUILD_LIBFONTMANAGER_FONTLIB), \
     LDFLAGS_SUFFIX_linux := -lawt $(LIBM) $(LIBCXX) -ljava -ljvm -lc, \
-    LDFLAGS_SUFFIX_solaris := $(filter-out -R%, $(X_LIBS)) \
-        -lawt -lawt_xawt -lc $(LIBM) $(LIBCXX) -ljava -ljvm, \
-    LDFLAGS_SUFFIX_aix := -lawt -lawt_xawt $(LIBM) $(LIBCXX) -ljava -ljvm,\
+    LDFLAGS_SUFFIX_solaris := -lawt -lawt_headless -lc $(LIBM) $(LIBCXX) -ljava -ljvm, \
+    LDFLAGS_SUFFIX_aix := -lawt -lawt_headless $(LIBM) $(LIBCXX) -ljava -ljvm,\
     LDFLAGS_SUFFIX_macosx := -lawt $(LIBM) $(LIBCXX) -undefined dynamic_lookup \
         -ljava -ljvm, \
     LDFLAGS_SUFFIX_windows := $(WIN_JAVA_LIB) advapi32.lib user32.lib gdi32.lib \
@@ -601,7 +667,7 @@
 $(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT)
 
 ifneq (, $(findstring $(OPENJDK_TARGET_OS), solaris aix))
-  $(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT_XAWT)
+  $(BUILD_LIBFONTMANAGER): $(BUILD_LIBAWT_HEADLESS)
 endif
 
 TARGETS += $(BUILD_LIBFONTMANAGER)
@@ -723,77 +789,6 @@
 
 ################################################################################
 
-ifeq ($(BUILD_HEADLESS), true)
-  # Mac and Windows only use the native AWT lib, do not build libawt_headless
-  ifeq ($(findstring $(OPENJDK_TARGET_OS), windows macosx),)
-
-    LIBAWT_HEADLESS_DIRS := $(JDK_TOPDIR)/src/java.desktop/unix/native/libawt_headless/awt \
-        $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/awt \
-        $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/java2d/opengl \
-        $(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/java2d/x11 \
-        $(JDK_TOPDIR)/src/java.desktop/share/native/common/java2d/opengl \
-        $(JDK_TOPDIR)/src/java.desktop/share/native/common/font \
-        #
-
-    LIBAWT_HEADLESS_EXCLUDES := medialib
-    LIBAWT_HEADLESS_CFLAGS := -I$(SUPPORT_OUTPUTDIR)/headers/java.desktop \
-        $(addprefix -I, $(LIBAWT_HEADLESS_DIRS)) \
-        -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d \
-        -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d/loops \
-        -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/awt/image/cvutils \
-        -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/java2d/pipe \
-        -I$(JDK_TOPDIR)/src/java.desktop/share/native/libawt/awt/image \
-        -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libawt/java2d \
-        -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/font \
-        -I$(JDK_TOPDIR)/src/java.desktop/share/native/common/awt/debug \
-        -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/common/font \
-        -I$(JDK_TOPDIR)/src/java.desktop/$(OPENJDK_TARGET_OS_TYPE)/native/libsunwjdga/ \
-        $(LIBJAVA_HEADER_FLAGS) \
-        #
-
-    LIBAWT_HEADLESS_REORDER :=
-    ifeq ($(OPENJDK_TARGET_OS), solaris)
-      ifneq ($(OPENJDK_TARGET_CPU), x86_64)
-        LIBAWT_HEADLESS_REORDER := $(JDK_TOPDIR)/make/mapfiles/libawt_headless/reorder-$(OPENJDK_TARGET_CPU)
-      endif
-    endif
-
-    $(eval $(call SetupNativeCompilation,BUILD_LIBAWT_HEADLESS, \
-        LIBRARY := awt_headless, \
-        OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
-        SRC := $(LIBAWT_HEADLESS_DIRS), \
-        EXCLUDES := $(LIBAWT_HEADLESS_EXCLUDES), \
-        LANG := C, \
-        OPTIMIZATION := LOW, \
-        CFLAGS := $(CFLAGS_JDKLIB) \
-            -DHEADLESS=true \
-            -DPACKAGE_PATH=\"$(PACKAGE_PATH)\" \
-            $(CUPS_CFLAGS) \
-            $(X_CFLAGS) \
-            $(LIBAWT_HEADLESS_CFLAGS), \
-        MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libawt_headless/mapfile-vers, \
-        LDFLAGS := $(LDFLAGS_JDKLIB) \
-            $(call SET_SHARED_LIBRARY_ORIGIN), \
-        LDFLAGS_unix := -L$(INSTALL_LIBRARIES_HERE), \
-        LDFLAGS_linux := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \
-        LDFLAGS_solaris := $(call SET_SHARED_LIBRARY_ORIGIN,/..), \
-        LDFLAGS_macosx := $(call SET_SHARED_LIBRARY_ORIGIN)., \
-        REORDER := $(LIBAWT_HEADLESS_REORDER), \
-        LDFLAGS_SUFFIX_linux := -ljvm -lawt -lm $(LIBDL) -ljava, \
-        LDFLAGS_SUFFIX_aix := -ljvm -lawt -ljava,\
-        LDFLAGS_SUFFIX_solaris := $(LIBDL) -ljvm -lawt -lm -ljava $(LIBCXX) -lc, \
-        OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libawt_headless, \
-        DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
-
-    $(BUILD_LIBAWT_HEADLESS): $(BUILD_LIBAWT)
-
-    TARGETS += $(BUILD_LIBAWT_HEADLESS)
-
-  endif
-endif
-
-################################################################################
-
 ifndef BUILD_HEADLESS_ONLY
 
   LIBSPLASHSCREEN_DIRS := \
--- a/jdk/make/lib/CoreLibraries.gmk	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/make/lib/CoreLibraries.gmk	Tue Feb 17 11:44:51 2015 -0800
@@ -271,6 +271,11 @@
   # Staticically link with c runtime on windows.
   LIBJLI_CFLAGS := $(filter-out -MD, $(LIBJLI_CFLAGS))
   LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)
+  # Supply the name of the C runtime lib.
+  LIBJLI_CFLAGS += -DMSVCR_DLL_NAME='"$(notdir $(MSVCR_DLL))"'
+  ifneq ($(MSVCP_DLL), )
+    LIBJLI_CFLAGS += -DMSVCP_DLL_NAME='"$(notdir $(MSVCP_DLL))"'
+  endif
 else
   LIBJLI_OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE)/jli
 endif
--- a/jdk/make/src/classes/build/tools/module/boot.modules	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/make/src/classes/build/tools/module/boot.modules	Tue Feb 17 11:44:51 2015 -0800
@@ -1,5 +1,6 @@
 java.base
 java.compiler
+java.datatransfer
 java.desktop
 java.instrument
 java.logging
--- a/jdk/src/java.base/windows/native/libjli/java_md.c	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.base/windows/native/libjli/java_md.c	Tue Feb 17 11:44:51 2015 -0800
@@ -265,26 +265,17 @@
          * assumed to be present in the "JRE path" directory.  If it is not found
          * there (or "JRE path" fails to resolve), skip the explicit load and let
          * nature take its course, which is likely to be a failure to execute.
-         * This is clearly completely specific to the exact compiler version
-         * which isn't very nice, but its hardly the only place.
-         * No attempt to look for compiler versions in between 2003 and 2010
-         * as we aren't supporting building with those.
+         * The makefiles will provide the correct lib contained in quotes in the
+         * macro MSVCR_DLL_NAME.
          */
-#ifdef _MSC_VER
-#if _MSC_VER < 1400
-#define CRT_DLL "msvcr71.dll"
-#endif
-#if _MSC_VER >= 1600
-#define CRT_DLL "msvcr100.dll"
-#endif
-#ifdef CRT_DLL
+#ifdef MSVCR_DLL_NAME
         if (GetJREPath(crtpath, MAXPATHLEN)) {
             if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") +
-                    JLI_StrLen(CRT_DLL) >= MAXPATHLEN) {
+                    JLI_StrLen(MSVCR_DLL_NAME) >= MAXPATHLEN) {
                 JLI_ReportErrorMessage(JRE_ERROR11);
                 return JNI_FALSE;
             }
-            (void)JLI_StrCat(crtpath, "\\bin\\" CRT_DLL);   /* Add crt dll */
+            (void)JLI_StrCat(crtpath, "\\bin\\" MSVCR_DLL_NAME);   /* Add crt dll */
             JLI_TraceLauncher("CRT path is %s\n", crtpath);
             if (_access(crtpath, 0) == 0) {
                 if (LoadLibrary(crtpath) == 0) {
@@ -293,8 +284,24 @@
                 }
             }
         }
-#endif /* CRT_DLL */
-#endif /* _MSC_VER */
+#endif /* MSVCR_DLL_NAME */
+#ifdef MSVCP_DLL_NAME
+        if (GetJREPath(crtpath, MAXPATHLEN)) {
+            if (JLI_StrLen(crtpath) + JLI_StrLen("\\bin\\") +
+                    JLI_StrLen(MSVCP_DLL_NAME) >= MAXPATHLEN) {
+                JLI_ReportErrorMessage(JRE_ERROR11);
+                return JNI_FALSE;
+            }
+            (void)JLI_StrCat(crtpath, "\\bin\\" MSVCP_DLL_NAME);   /* Add prt dll */
+            JLI_TraceLauncher("PRT path is %s\n", crtpath);
+            if (_access(crtpath, 0) == 0) {
+                if (LoadLibrary(crtpath) == 0) {
+                    JLI_ReportErrorMessage(DLL_ERROR4, crtpath);
+                    return JNI_FALSE;
+                }
+            }
+        }
+#endif /* MSVCP_DLL_NAME */
         loaded = 1;
     }
     return JNI_TRUE;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/macosx/classes/sun/datatransfer/resources/flavormap.properties	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,76 @@
+#
+# This properties file is used to initialize the default
+# java.awt.datatransfer.SystemFlavorMap. It contains the Mac OS X platform-specific,
+# default mappings between common Mac OS X selection atoms and platform-independent
+# MIME type strings, which will be converted into 
+# java.awt.datatransfer.DataFlavors.
+#
+# The standard format is:
+#
+# <native>=<MIME type>,<MIME type>, ...
+#
+# <native> should be a string identifier that the native platform will
+# recognize as a valid data format. <MIME type> should specify both a MIME
+# primary type and a MIME subtype separated by a '/'. The MIME type may include
+# parameters, where each parameter is a key/value pair separated by '=', and
+# where each parameter to the MIME type is separated by a ';'.
+#
+# Because SystemFlavorMap implements FlavorTable, developers are free to
+# duplicate DataFlavor values and set multiple values for a single native by
+# separating them with ",". If a mapping contains a duplicate key or value,
+# earlier mappings which included this key or value will be preferred.
+#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", and which support the charset parameter, should specify the exact
+# format in which the native platform expects the data. The "charset"
+# parameter specifies the char to byte encoding, the "eoln" parameter
+# specifies the end-of-line marker, and the "terminators" parameter specifies
+# the number of terminating NUL bytes. Note that "eoln" and "terminators"
+# are not standardized MIME type parameters. They are specific to this file
+# format ONLY. They will not appear in any of the DataFlavors returned by the
+# SystemFlavorMap at the Java level.
+#
+# If the "charset" parameter is omitted, or has zero length, the platform
+# default encoding is assumed. If the "eoln" parameter is omitted, or has
+# zero length, "\n" is assumed. If the "terminators" parameter is omitted,
+# or has a value less than zero, zero is assumed.
+#
+# Upon initialization, the data transfer subsystem will record the specified
+# details of the native text format, but the default SystemFlavorMap will
+# present a large set of synthesized DataFlavors which map, in both
+# directions, to the native. After receiving data from the application in one
+# of the synthetic DataFlavors, the data transfer subsystem will transform
+# the data stream into the format specified in this file before passing the
+# transformed stream to the native system.
+#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", but which do not support the charset parameter, will be treated as
+# opaque, 8-bit data. They will not undergo any transformation process, and
+# any "charset", "eoln", or "terminators" parameters specified in this file
+# will be ignored.
+#
+# See java.awt.datatransfer.DataFlavor.selectBestTextFlavor for a list of
+# text flavors which support the charset parameter.
+
+UTF8_STRING=text/plain;charset=UTF-8;eoln="\n";terminators=0
+
+# The COMPOUND_TEXT support for inter-client text transfer is disabled by 
+# default. The reason is that many native applications prefer this format over 
+# other native text formats, but are unable to decode the textual data in this 
+# format properly. This results in java-to-native text transfer failures.
+# To enable the COMPOUND_TEXT support for this JRE installation uncomment 
+# the line below.
+
+# COMPOUND_TEXT=text/plain;charset=x-compound-text;eoln="\n";terminators=0
+
+TEXT=text/plain;eoln="\n";terminators=0
+STRING=text/plain;charset=UTF-8;eoln="\n";terminators=0
+FILE_NAME=application/x-java-file-list;class=java.util.List
+text/uri-list=application/x-java-file-list;class=java.util.List
+PNG=image/x-java-image;class=java.awt.Image
+JFIF=image/x-java-image;class=java.awt.Image
+TIFF=image/x-java-image;class=java.awt.Image
+RICH_TEXT=text/rtf
+HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1
+URL=application/x-java-url;class=java.net.URL,\
+    text/uri-list;eoln="\r\n";terminators=1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 1996, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+import sun.datatransfer.DataFlavorUtil;
+
+import java.util.Objects;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Arrays;
+
+import java.io.IOException;
+
+/**
+ * A class that implements a mechanism to transfer data using
+ * cut/copy/paste operations.
+ * <p>
+ * {@link FlavorListener}s may be registered on an instance of the
+ * Clipboard class to be notified about changes to the set of
+ * {@link DataFlavor}s available on this clipboard (see
+ * {@link #addFlavorListener}).
+ *
+ * @see java.awt.Toolkit#getSystemClipboard
+ * @see java.awt.Toolkit#getSystemSelection
+ *
+ * @author      Amy Fowler
+ * @author      Alexander Gerasimov
+ */
+public class Clipboard {
+
+    String name;
+
+    /**
+     * The owner of the clipboard.
+     */
+    protected ClipboardOwner owner;
+    /**
+     * Contents of the clipboard.
+     */
+    protected Transferable contents;
+
+    /**
+     * An aggregate of flavor listeners registered on this local clipboard.
+     *
+     * @since 1.5
+     */
+    private Set<FlavorListener> flavorListeners;
+
+    /**
+     * A set of <code>DataFlavor</code>s that is available on
+     * this local clipboard. It is used for tracking changes
+     * of <code>DataFlavor</code>s available on this clipboard.
+     *
+     * @since 1.5
+     */
+    private Set<DataFlavor> currentDataFlavors;
+
+    /**
+     * Creates a clipboard object.
+     * @param name for the clipboard
+     * @see java.awt.Toolkit#getSystemClipboard
+     */
+    public Clipboard(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Returns the name of this clipboard object.
+     * @return the name of this clipboard object
+     *
+     * @see java.awt.Toolkit#getSystemClipboard
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets the current contents of the clipboard to the specified
+     * transferable object and registers the specified clipboard owner
+     * as the owner of the new contents.
+     * <p>
+     * If there is an existing owner different from the argument
+     * <code>owner</code>, that owner is notified that it no longer
+     * holds ownership of the clipboard contents via an invocation
+     * of <code>ClipboardOwner.lostOwnership()</code> on that owner.
+     * An implementation of <code>setContents()</code> is free not
+     * to invoke <code>lostOwnership()</code> directly from this method.
+     * For example, <code>lostOwnership()</code> may be invoked later on
+     * a different thread. The same applies to <code>FlavorListener</code>s
+     * registered on this clipboard.
+     * <p>
+     * The method throws <code>IllegalStateException</code> if the clipboard
+     * is currently unavailable. For example, on some platforms, the system
+     * clipboard is unavailable while it is accessed by another application.
+     *
+     * @param contents the transferable object representing the
+     *                 clipboard content
+     * @param owner the object which owns the clipboard content
+     * @throws IllegalStateException if the clipboard is currently unavailable
+     * @see java.awt.Toolkit#getSystemClipboard
+     */
+    public synchronized void setContents(Transferable contents, ClipboardOwner owner) {
+        final ClipboardOwner oldOwner = this.owner;
+        final Transferable oldContents = this.contents;
+
+        this.owner = owner;
+        this.contents = contents;
+
+        if (oldOwner != null && oldOwner != owner) {
+            DataFlavorUtil.getDesktopService().invokeOnEventThread(() ->
+                    oldOwner.lostOwnership(Clipboard.this, oldContents));
+        }
+        fireFlavorsChanged();
+    }
+
+    /**
+     * Returns a transferable object representing the current contents
+     * of the clipboard.  If the clipboard currently has no contents,
+     * it returns <code>null</code>. The parameter Object requestor is
+     * not currently used.  The method throws
+     * <code>IllegalStateException</code> if the clipboard is currently
+     * unavailable.  For example, on some platforms, the system clipboard is
+     * unavailable while it is accessed by another application.
+     *
+     * @param requestor the object requesting the clip data  (not used)
+     * @return the current transferable object on the clipboard
+     * @throws IllegalStateException if the clipboard is currently unavailable
+     * @see java.awt.Toolkit#getSystemClipboard
+     */
+    public synchronized Transferable getContents(Object requestor) {
+        return contents;
+    }
+
+
+    /**
+     * Returns an array of <code>DataFlavor</code>s in which the current
+     * contents of this clipboard can be provided. If there are no
+     * <code>DataFlavor</code>s available, this method returns a zero-length
+     * array.
+     *
+     * @return an array of <code>DataFlavor</code>s in which the current
+     *         contents of this clipboard can be provided
+     *
+     * @throws IllegalStateException if this clipboard is currently unavailable
+     *
+     * @since 1.5
+     */
+    public DataFlavor[] getAvailableDataFlavors() {
+        Transferable cntnts = getContents(null);
+        if (cntnts == null) {
+            return new DataFlavor[0];
+        }
+        return cntnts.getTransferDataFlavors();
+    }
+
+    /**
+     * Returns whether or not the current contents of this clipboard can be
+     * provided in the specified <code>DataFlavor</code>.
+     *
+     * @param flavor the requested <code>DataFlavor</code> for the contents
+     *
+     * @return <code>true</code> if the current contents of this clipboard
+     *         can be provided in the specified <code>DataFlavor</code>;
+     *         <code>false</code> otherwise
+     *
+     * @throws NullPointerException if <code>flavor</code> is <code>null</code>
+     * @throws IllegalStateException if this clipboard is currently unavailable
+     *
+     * @since 1.5
+     */
+    public boolean isDataFlavorAvailable(DataFlavor flavor) {
+        if (flavor == null) {
+            throw new NullPointerException("flavor");
+        }
+
+        Transferable cntnts = getContents(null);
+        if (cntnts == null) {
+            return false;
+        }
+        return cntnts.isDataFlavorSupported(flavor);
+    }
+
+    /**
+     * Returns an object representing the current contents of this clipboard
+     * in the specified <code>DataFlavor</code>.
+     * The class of the object returned is defined by the representation
+     * class of <code>flavor</code>.
+     *
+     * @param flavor the requested <code>DataFlavor</code> for the contents
+     *
+     * @return an object representing the current contents of this clipboard
+     *         in the specified <code>DataFlavor</code>
+     *
+     * @throws NullPointerException if <code>flavor</code> is <code>null</code>
+     * @throws IllegalStateException if this clipboard is currently unavailable
+     * @throws UnsupportedFlavorException if the requested <code>DataFlavor</code>
+     *         is not available
+     * @throws IOException if the data in the requested <code>DataFlavor</code>
+     *         can not be retrieved
+     *
+     * @see DataFlavor#getRepresentationClass
+     *
+     * @since 1.5
+     */
+    public Object getData(DataFlavor flavor)
+        throws UnsupportedFlavorException, IOException {
+        if (flavor == null) {
+            throw new NullPointerException("flavor");
+        }
+
+        Transferable cntnts = getContents(null);
+        if (cntnts == null) {
+            throw new UnsupportedFlavorException(flavor);
+        }
+        return cntnts.getTransferData(flavor);
+    }
+
+
+    /**
+     * Registers the specified <code>FlavorListener</code> to receive
+     * <code>FlavorEvent</code>s from this clipboard.
+     * If <code>listener</code> is <code>null</code>, no exception
+     * is thrown and no action is performed.
+     *
+     * @param listener the listener to be added
+     *
+     * @see #removeFlavorListener
+     * @see #getFlavorListeners
+     * @see FlavorListener
+     * @see FlavorEvent
+     * @since 1.5
+     */
+    public synchronized void addFlavorListener(FlavorListener listener) {
+        if (listener == null) {
+            return;
+        }
+
+        if (flavorListeners == null) {
+            flavorListeners = new HashSet<>();
+            currentDataFlavors = getAvailableDataFlavorSet();
+        }
+
+        flavorListeners.add(listener);
+    }
+
+    /**
+     * Removes the specified <code>FlavorListener</code> so that it no longer
+     * receives <code>FlavorEvent</code>s from this <code>Clipboard</code>.
+     * This method performs no function, nor does it throw an exception, if
+     * the listener specified by the argument was not previously added to this
+     * <code>Clipboard</code>.
+     * If <code>listener</code> is <code>null</code>, no exception
+     * is thrown and no action is performed.
+     *
+     * @param listener the listener to be removed
+     *
+     * @see #addFlavorListener
+     * @see #getFlavorListeners
+     * @see FlavorListener
+     * @see FlavorEvent
+     * @since 1.5
+     */
+    public synchronized void removeFlavorListener(FlavorListener listener) {
+        if (listener == null || flavorListeners == null) {
+            return;
+        }
+        flavorListeners.remove(listener);
+    }
+
+    /**
+     * Returns an array of all the <code>FlavorListener</code>s currently
+     * registered on this <code>Clipboard</code>.
+     *
+     * @return all of this clipboard's <code>FlavorListener</code>s or an empty
+     *         array if no listeners are currently registered
+     * @see #addFlavorListener
+     * @see #removeFlavorListener
+     * @see FlavorListener
+     * @see FlavorEvent
+     * @since 1.5
+     */
+    public synchronized FlavorListener[] getFlavorListeners() {
+        return flavorListeners == null ? new FlavorListener[0] :
+            flavorListeners.toArray(new FlavorListener[flavorListeners.size()]);
+    }
+
+    /**
+     * Checks change of the <code>DataFlavor</code>s and, if necessary,
+     * notifies all listeners that have registered interest for notification
+     * on <code>FlavorEvent</code>s.
+     *
+     * @since 1.5
+     */
+    private void fireFlavorsChanged() {
+        if (flavorListeners == null) {
+            return;
+        }
+
+        Set<DataFlavor> prevDataFlavors = currentDataFlavors;
+        currentDataFlavors = getAvailableDataFlavorSet();
+        if (Objects.equals(prevDataFlavors, currentDataFlavors)) {
+            return;
+        }
+        flavorListeners.forEach(listener ->
+                DataFlavorUtil.getDesktopService().invokeOnEventThread(() ->
+                        listener.flavorsChanged(new FlavorEvent(Clipboard.this))));
+    }
+
+    /**
+     * Returns a set of <code>DataFlavor</code>s currently available
+     * on this clipboard.
+     *
+     * @return a set of <code>DataFlavor</code>s currently available
+     *         on this clipboard
+     *
+     * @since 1.5
+     */
+    private Set<DataFlavor> getAvailableDataFlavorSet() {
+        Set<DataFlavor> set = new HashSet<>();
+        Transferable contents = getContents(null);
+        if (contents != null) {
+            DataFlavor[] flavors = contents.getTransferDataFlavors();
+            if (flavors != null) {
+                set.addAll(Arrays.asList(flavors));
+            }
+        }
+        return set;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/ClipboardOwner.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+/**
+ * Defines the interface for classes that will provide data to
+ * a clipboard. An instance of this interface becomes the owner
+ * of the contents of a clipboard (clipboard owner) if it is
+ * passed as an argument to
+ * {@link java.awt.datatransfer.Clipboard#setContents} method of
+ * the clipboard and this method returns successfully.
+ * The instance remains the clipboard owner until another application
+ * or another object within this application asserts ownership
+ * of this clipboard.
+ *
+ * @see java.awt.datatransfer.Clipboard
+ *
+ * @author      Amy Fowler
+ */
+
+public interface ClipboardOwner {
+
+    /**
+     * Notifies this object that it is no longer the clipboard owner.
+     * This method will be called when another application or another
+     * object within this application asserts ownership of the clipboard.
+     *
+     * @param clipboard the clipboard that is no longer owned
+     * @param contents the contents which this owner had placed on the clipboard
+     */
+    public void lostOwnership(Clipboard clipboard, Transferable contents);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,1431 @@
+/*
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+import sun.datatransfer.DataFlavorUtil;
+import sun.reflect.misc.ReflectUtil;
+
+import java.io.ByteArrayInputStream;
+import java.io.CharArrayReader;
+import java.io.Externalizable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.io.OptionalDataException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Objects;
+
+/**
+ * A {@code DataFlavor} provides meta information about data. {@code DataFlavor}
+ * is typically used to access data on the clipboard, or during
+ * a drag and drop operation.
+ * <p>
+ * An instance of {@code DataFlavor} encapsulates a content type as
+ * defined in <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
+ * and <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC 2046</a>.
+ * A content type is typically referred to as a MIME type.
+ * <p>
+ * A content type consists of a media type (referred
+ * to as the primary type), a subtype, and optional parameters. See
+ * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
+ * for details on the syntax of a MIME type.
+ * <p>
+ * The JRE data transfer implementation interprets the parameter &quot;class&quot;
+ * of a MIME type as <B>a representation class</b>.
+ * The representation class reflects the class of the object being
+ * transferred. In other words, the representation class is the type of
+ * object returned by {@link Transferable#getTransferData}.
+ * For example, the MIME type of {@link #imageFlavor} is
+ * {@code "image/x-java-image;class=java.awt.Image"},
+ * the primary type is {@code image}, the subtype is
+ * {@code x-java-image}, and the representation class is
+ * {@code java.awt.Image}. When {@code getTransferData} is invoked
+ * with a {@code DataFlavor} of {@code imageFlavor}, an instance of
+ * {@code java.awt.Image} is returned.
+ * It's important to note that {@code DataFlavor} does no error checking
+ * against the representation class. It is up to consumers of
+ * {@code DataFlavor}, such as {@code Transferable}, to honor the representation
+ * class.
+ * <br>
+ * Note, if you do not specify a representation class when
+ * creating a {@code DataFlavor}, the default
+ * representation class is used. See appropriate documentation for
+ * {@code DataFlavor}'s constructors.
+ * <p>
+ * Also, {@code DataFlavor} instances with the &quot;text&quot; primary
+ * MIME type may have a &quot;charset&quot; parameter. Refer to
+ * <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC 2046</a> and
+ * {@link #selectBestTextFlavor} for details on &quot;text&quot; MIME types
+ * and the &quot;charset&quot; parameter.
+ * <p>
+ * Equality of {@code DataFlavors} is determined by the primary type,
+ * subtype, and representation class. Refer to {@link #equals(DataFlavor)} for
+ * details. When determining equality, any optional parameters are ignored.
+ * For example, the following produces two {@code DataFlavors} that
+ * are considered identical:
+ * <pre>
+ *   DataFlavor flavor1 = new DataFlavor(Object.class, &quot;X-test/test; class=&lt;java.lang.Object&gt;; foo=bar&quot;);
+ *   DataFlavor flavor2 = new DataFlavor(Object.class, &quot;X-test/test; class=&lt;java.lang.Object&gt;; x=y&quot;);
+ *   // The following returns true.
+ *   flavor1.equals(flavor2);
+ * </pre>
+ * As mentioned, {@code flavor1} and {@code flavor2} are considered identical.
+ * As such, asking a {@code Transferable} for either {@code DataFlavor} returns
+ * the same results.
+ * <p>
+ * For more information on using data transfer with Swing see
+ * the <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
+ * How to Use Drag and Drop and Data Transfer</a>,
+ * section in <em>Java Tutorial</em>.
+ *
+ * @author      Blake Sullivan
+ * @author      Laurence P. G. Cable
+ * @author      Jeff Dunn
+ */
+public class DataFlavor implements Externalizable, Cloneable {
+
+    private static final long serialVersionUID = 8367026044764648243L;
+    private static final Class<InputStream> ioInputStreamClass = InputStream.class;
+
+    /**
+     * Tries to load a class from: the bootstrap loader, the system loader,
+     * the context loader (if one is present) and finally the loader specified.
+     *
+     * @param className the name of the class to be loaded
+     * @param fallback the fallback loader
+     * @return the class loaded
+     * @exception ClassNotFoundException if class is not found
+     */
+    protected final static Class<?> tryToLoadClass(String className,
+                                                   ClassLoader fallback)
+        throws ClassNotFoundException
+    {
+        ReflectUtil.checkPackageAccess(className);
+        try {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                sm.checkPermission(new RuntimePermission("getClassLoader"));
+            }
+            ClassLoader loader = ClassLoader.getSystemClassLoader();
+            try {
+                // bootstrap class loader and system class loader if present
+                return Class.forName(className, true, loader);
+            }
+            catch (ClassNotFoundException exception) {
+                // thread context class loader if and only if present
+                loader = Thread.currentThread().getContextClassLoader();
+                if (loader != null) {
+                    try {
+                        return Class.forName(className, true, loader);
+                    }
+                    catch (ClassNotFoundException e) {
+                        // fallback to user's class loader
+                    }
+                }
+            }
+        } catch (SecurityException exception) {
+            // ignore secured class loaders
+        }
+        return Class.forName(className, true, fallback);
+    }
+
+    /*
+     * private initializer
+     */
+    static private DataFlavor createConstant(Class<?> rc, String prn) {
+        try {
+            return new DataFlavor(rc, prn);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    /*
+     * private initializer
+     */
+    static private DataFlavor createConstant(String mt, String prn) {
+        try {
+            return new DataFlavor(mt, prn);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    /*
+     * private initializer
+     */
+    static private DataFlavor initHtmlDataFlavor(String htmlFlavorType) {
+        try {
+            return new DataFlavor ("text/html; class=java.lang.String;document=" +
+                                       htmlFlavorType + ";charset=Unicode");
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    /**
+     * The <code>DataFlavor</code> representing a Java Unicode String class,
+     * where:
+     * <pre>
+     *     representationClass = java.lang.String
+     *     mimeType           = "application/x-java-serialized-object"
+     * </pre>
+     */
+    public static final DataFlavor stringFlavor = createConstant(java.lang.String.class, "Unicode String");
+
+    /**
+     * The <code>DataFlavor</code> representing a Java Image class,
+     * where:
+     * <pre>
+     *     representationClass = java.awt.Image
+     *     mimeType            = "image/x-java-image"
+     * </pre>
+     */
+    public static final DataFlavor imageFlavor = createConstant("image/x-java-image; class=java.awt.Image", "Image");
+
+    /**
+     * The <code>DataFlavor</code> representing plain text with Unicode
+     * encoding, where:
+     * <pre>
+     *     representationClass = InputStream
+     *     mimeType            = "text/plain; charset=unicode"
+     * </pre>
+     * This <code>DataFlavor</code> has been <b>deprecated</b> because
+     * (1) Its representation is an InputStream, an 8-bit based representation,
+     * while Unicode is a 16-bit character set; and (2) The charset "unicode"
+     * is not well-defined. "unicode" implies a particular platform's
+     * implementation of Unicode, not a cross-platform implementation.
+     *
+     * @deprecated as of 1.3. Use <code>DataFlavor.getReaderForText(Transferable)</code>
+     *             instead of <code>Transferable.getTransferData(DataFlavor.plainTextFlavor)</code>.
+     */
+    @Deprecated
+    public static final DataFlavor plainTextFlavor = createConstant("text/plain; charset=unicode; class=java.io.InputStream", "Plain Text");
+
+    /**
+     * A MIME Content-Type of application/x-java-serialized-object represents
+     * a graph of Java object(s) that have been made persistent.
+     *
+     * The representation class associated with this <code>DataFlavor</code>
+     * identifies the Java type of an object returned as a reference
+     * from an invocation <code>java.awt.datatransfer.getTransferData</code>.
+     */
+    public static final String javaSerializedObjectMimeType = "application/x-java-serialized-object";
+
+    /**
+     * To transfer a list of files to/from Java (and the underlying
+     * platform) a <code>DataFlavor</code> of this type/subtype and
+     * representation class of <code>java.util.List</code> is used.
+     * Each element of the list is required/guaranteed to be of type
+     * <code>java.io.File</code>.
+     */
+    public static final DataFlavor javaFileListFlavor = createConstant("application/x-java-file-list;class=java.util.List", null);
+
+    /**
+     * To transfer a reference to an arbitrary Java object reference that
+     * has no associated MIME Content-type, across a <code>Transferable</code>
+     * interface WITHIN THE SAME JVM, a <code>DataFlavor</code>
+     * with this type/subtype is used, with a <code>representationClass</code>
+     * equal to the type of the class/interface being passed across the
+     * <code>Transferable</code>.
+     * <p>
+     * The object reference returned from
+     * <code>Transferable.getTransferData</code> for a <code>DataFlavor</code>
+     * with this MIME Content-Type is required to be
+     * an instance of the representation Class of the <code>DataFlavor</code>.
+     */
+    public static final String javaJVMLocalObjectMimeType = "application/x-java-jvm-local-objectref";
+
+    /**
+     * In order to pass a live link to a Remote object via a Drag and Drop
+     * <code>ACTION_LINK</code> operation a Mime Content Type of
+     * application/x-java-remote-object should be used,
+     * where the representation class of the <code>DataFlavor</code>
+     * represents the type of the <code>Remote</code> interface to be
+     * transferred.
+     */
+    public static final String javaRemoteObjectMimeType = "application/x-java-remote-object";
+
+    /**
+     * Represents a piece of an HTML markup. The markup consists of the part
+     * selected on the source side. Therefore some tags in the markup may be
+     * unpaired. If the flavor is used to represent the data in
+     * a {@link Transferable} instance, no additional changes will be made.
+     * This DataFlavor instance represents the same HTML markup as DataFlavor
+     * instances which content MIME type does not contain document parameter
+     * and representation class is the String class.
+     * <pre>
+     *     representationClass = String
+     *     mimeType           = "text/html"
+     * </pre>
+     */
+    public static DataFlavor selectionHtmlFlavor = initHtmlDataFlavor("selection");
+
+    /**
+     * Represents a piece of an HTML markup. If possible, the markup received
+     * from a native system is supplemented with pair tags to be
+     * a well-formed HTML markup. If the flavor is used to represent the data in
+     * a {@link Transferable} instance, no additional changes will be made.
+     * <pre>
+     *     representationClass = String
+     *     mimeType           = "text/html"
+     * </pre>
+     */
+    public static DataFlavor fragmentHtmlFlavor = initHtmlDataFlavor("fragment");
+
+    /**
+     * Represents a piece of an HTML markup. If possible, the markup
+     * received from a native system is supplemented with additional
+     * tags to make up a well-formed HTML document. If the flavor is used to
+     * represent the data in a {@link Transferable} instance,
+     * no additional changes will be made.
+     * <pre>
+     *     representationClass = String
+     *     mimeType           = "text/html"
+     * </pre>
+     */
+    public static  DataFlavor allHtmlFlavor = initHtmlDataFlavor("all");
+
+    /**
+     * Constructs a new <code>DataFlavor</code>.  This constructor is
+     * provided only for the purpose of supporting the
+     * <code>Externalizable</code> interface.  It is not
+     * intended for public (client) use.
+     *
+     * @since 1.2
+     */
+    public DataFlavor() {
+        super();
+    }
+
+    /**
+     * Constructs a fully specified <code>DataFlavor</code>.
+     *
+     * @exception NullPointerException if either <code>primaryType</code>,
+     *            <code>subType</code> or <code>representationClass</code> is null
+     */
+    private DataFlavor(String primaryType, String subType, MimeTypeParameterList params, Class<?> representationClass, String humanPresentableName) {
+        super();
+        if (primaryType == null) {
+            throw new NullPointerException("primaryType");
+        }
+        if (subType == null) {
+            throw new NullPointerException("subType");
+        }
+        if (representationClass == null) {
+            throw new NullPointerException("representationClass");
+        }
+
+        if (params == null) params = new MimeTypeParameterList();
+
+        params.set("class", representationClass.getName());
+
+        if (humanPresentableName == null) {
+            humanPresentableName = params.get("humanPresentableName");
+
+            if (humanPresentableName == null)
+                humanPresentableName = primaryType + "/" + subType;
+        }
+
+        try {
+            mimeType = new MimeType(primaryType, subType, params);
+        } catch (MimeTypeParseException mtpe) {
+            throw new IllegalArgumentException("MimeType Parse Exception: " + mtpe.getMessage());
+        }
+
+        this.representationClass  = representationClass;
+        this.humanPresentableName = humanPresentableName;
+
+        mimeType.removeParameter("humanPresentableName");
+    }
+
+    /**
+     * Constructs a <code>DataFlavor</code> that represents a Java class.
+     * <p>
+     * The returned <code>DataFlavor</code> will have the following
+     * characteristics:
+     * <pre>
+     *    representationClass = representationClass
+     *    mimeType            = application/x-java-serialized-object
+     * </pre>
+     * @param representationClass the class used to transfer data in this flavor
+     * @param humanPresentableName the human-readable string used to identify
+     *                 this flavor; if this parameter is <code>null</code>
+     *                 then the value of the MIME Content Type is used
+     * @exception NullPointerException if <code>representationClass</code> is null
+     */
+    public DataFlavor(Class<?> representationClass, String humanPresentableName) {
+        this("application", "x-java-serialized-object", null, representationClass, humanPresentableName);
+        if (representationClass == null) {
+            throw new NullPointerException("representationClass");
+        }
+    }
+
+    /**
+     * Constructs a <code>DataFlavor</code> that represents a
+     * <code>MimeType</code>.
+     * <p>
+     * The returned <code>DataFlavor</code> will have the following
+     * characteristics:
+     * <p>
+     * If the <code>mimeType</code> is
+     * "application/x-java-serialized-object; class=&lt;representation class&gt;",
+     * the result is the same as calling
+     * <code>new DataFlavor(Class.forName(&lt;representation class&gt;)</code>.
+     * <p>
+     * Otherwise:
+     * <pre>
+     *     representationClass = InputStream
+     *     mimeType            = mimeType
+     * </pre>
+     * @param mimeType the string used to identify the MIME type for this flavor;
+     *                 if the <code>mimeType</code> does not specify a
+     *                 "class=" parameter, or if the class is not successfully
+     *                 loaded, then an <code>IllegalArgumentException</code>
+     *                 is thrown
+     * @param humanPresentableName the human-readable string used to identify
+     *                 this flavor; if this parameter is <code>null</code>
+     *                 then the value of the MIME Content Type is used
+     * @exception IllegalArgumentException if <code>mimeType</code> is
+     *                 invalid or if the class is not successfully loaded
+     * @exception NullPointerException if <code>mimeType</code> is null
+     */
+    public DataFlavor(String mimeType, String humanPresentableName) {
+        super();
+        if (mimeType == null) {
+            throw new NullPointerException("mimeType");
+        }
+        try {
+            initialize(mimeType, humanPresentableName, this.getClass().getClassLoader());
+        } catch (MimeTypeParseException mtpe) {
+            throw new IllegalArgumentException("failed to parse:" + mimeType);
+        } catch (ClassNotFoundException cnfe) {
+            throw new IllegalArgumentException("can't find specified class: " + cnfe.getMessage());
+        }
+    }
+
+    /**
+     * Constructs a <code>DataFlavor</code> that represents a
+     * <code>MimeType</code>.
+     * <p>
+     * The returned <code>DataFlavor</code> will have the following
+     * characteristics:
+     * <p>
+     * If the mimeType is
+     * "application/x-java-serialized-object; class=&lt;representation class&gt;",
+     * the result is the same as calling
+     * <code>new DataFlavor(Class.forName(&lt;representation class&gt;)</code>.
+     * <p>
+     * Otherwise:
+     * <pre>
+     *     representationClass = InputStream
+     *     mimeType            = mimeType
+     * </pre>
+     * @param mimeType the string used to identify the MIME type for this flavor
+     * @param humanPresentableName the human-readable string used to
+     *          identify this flavor
+     * @param classLoader the class loader to use
+     * @exception ClassNotFoundException if the class is not loaded
+     * @exception IllegalArgumentException if <code>mimeType</code> is
+     *                 invalid
+     * @exception NullPointerException if <code>mimeType</code> is null
+     */
+    public DataFlavor(String mimeType, String humanPresentableName, ClassLoader classLoader) throws ClassNotFoundException {
+        super();
+        if (mimeType == null) {
+            throw new NullPointerException("mimeType");
+        }
+        try {
+            initialize(mimeType, humanPresentableName, classLoader);
+        } catch (MimeTypeParseException mtpe) {
+            throw new IllegalArgumentException("failed to parse:" + mimeType);
+        }
+    }
+
+    /**
+     * Constructs a <code>DataFlavor</code> from a <code>mimeType</code> string.
+     * The string can specify a "class=&lt;fully specified Java class name&gt;"
+     * parameter to create a <code>DataFlavor</code> with the desired
+     * representation class. If the string does not contain "class=" parameter,
+     * <code>java.io.InputStream</code> is used as default.
+     *
+     * @param mimeType the string used to identify the MIME type for this flavor;
+     *                 if the class specified by "class=" parameter is not
+     *                 successfully loaded, then an
+     *                 <code>ClassNotFoundException</code> is thrown
+     * @exception ClassNotFoundException if the class is not loaded
+     * @exception IllegalArgumentException if <code>mimeType</code> is
+     *                 invalid
+     * @exception NullPointerException if <code>mimeType</code> is null
+     */
+    public DataFlavor(String mimeType) throws ClassNotFoundException {
+        super();
+        if (mimeType == null) {
+            throw new NullPointerException("mimeType");
+        }
+        try {
+            initialize(mimeType, null, this.getClass().getClassLoader());
+        } catch (MimeTypeParseException mtpe) {
+            throw new IllegalArgumentException("failed to parse:" + mimeType);
+        }
+    }
+
+   /**
+    * Common initialization code called from various constructors.
+    *
+    * @param mimeType the MIME Content Type (must have a class= param)
+    * @param humanPresentableName the human Presentable Name or
+    *                 <code>null</code>
+    * @param classLoader the fallback class loader to resolve against
+    *
+    * @throws MimeTypeParseException
+    * @throws ClassNotFoundException
+    * @throws  NullPointerException if <code>mimeType</code> is null
+    *
+    * @see #tryToLoadClass
+    */
+    private void initialize(String mimeType, String humanPresentableName, ClassLoader classLoader) throws MimeTypeParseException, ClassNotFoundException {
+        if (mimeType == null) {
+            throw new NullPointerException("mimeType");
+        }
+
+        this.mimeType = new MimeType(mimeType); // throws
+
+        String rcn = getParameter("class");
+
+        if (rcn == null) {
+            if ("application/x-java-serialized-object".equals(this.mimeType.getBaseType()))
+
+                throw new IllegalArgumentException("no representation class specified for:" + mimeType);
+            else
+                representationClass = java.io.InputStream.class; // default
+        } else { // got a class name
+            representationClass = DataFlavor.tryToLoadClass(rcn, classLoader);
+        }
+
+        this.mimeType.setParameter("class", representationClass.getName());
+
+        if (humanPresentableName == null) {
+            humanPresentableName = this.mimeType.getParameter("humanPresentableName");
+            if (humanPresentableName == null)
+                humanPresentableName = this.mimeType.getPrimaryType() + "/" + this.mimeType.getSubType();
+        }
+
+        this.humanPresentableName = humanPresentableName; // set it.
+
+        this.mimeType.removeParameter("humanPresentableName"); // just in case
+    }
+
+    /**
+     * String representation of this <code>DataFlavor</code> and its
+     * parameters. The resulting <code>String</code> contains the name of
+     * the <code>DataFlavor</code> class, this flavor's MIME type, and its
+     * representation class. If this flavor has a primary MIME type of "text",
+     * supports the charset parameter, and has an encoded representation, the
+     * flavor's charset is also included. See <code>selectBestTextFlavor</code>
+     * for a list of text flavors which support the charset parameter.
+     *
+     * @return  string representation of this <code>DataFlavor</code>
+     * @see #selectBestTextFlavor
+     */
+    public String toString() {
+        String string = getClass().getName();
+        string += "["+paramString()+"]";
+        return string;
+    }
+
+    private String paramString() {
+        String params = "";
+        params += "mimetype=";
+        if (mimeType == null) {
+            params += "null";
+        } else {
+            params += mimeType.getBaseType();
+        }
+        params += ";representationclass=";
+        if (representationClass == null) {
+           params += "null";
+        } else {
+           params += representationClass.getName();
+        }
+        if (DataFlavorUtil.isFlavorCharsetTextType(this) &&
+            (isRepresentationClassInputStream() ||
+             isRepresentationClassByteBuffer() ||
+             byte[].class.equals(representationClass)))
+        {
+            params += ";charset=" + DataFlavorUtil.getTextCharset(this);
+        }
+        return params;
+    }
+
+    /**
+     * Returns a <code>DataFlavor</code> representing plain text with Unicode
+     * encoding, where:
+     * <pre>
+     *     representationClass = java.io.InputStream
+     *     mimeType            = "text/plain;
+     *                            charset=&lt;platform default Unicode encoding&gt;"
+     * </pre>
+     * Sun's implementation for Microsoft Windows uses the encoding <code>utf-16le</code>.
+     * Sun's implementation for Solaris and Linux uses the encoding
+     * <code>iso-10646-ucs-2</code>.
+     *
+     * @return a <code>DataFlavor</code> representing plain text
+     *    with Unicode encoding
+     * @since 1.3
+     */
+    public static final DataFlavor getTextPlainUnicodeFlavor() {
+        return new DataFlavor(
+            "text/plain;charset=" + DataFlavorUtil.getDesktopService().getDefaultUnicodeEncoding()
+            +";class=java.io.InputStream", "Plain Text");
+    }
+
+    /**
+     * Selects the best text <code>DataFlavor</code> from an array of <code>
+     * DataFlavor</code>s. Only <code>DataFlavor.stringFlavor</code>, and
+     * equivalent flavors, and flavors that have a primary MIME type of "text",
+     * are considered for selection.
+     * <p>
+     * Flavors are first sorted by their MIME types in the following order:
+     * <ul>
+     * <li>"text/sgml"
+     * <li>"text/xml"
+     * <li>"text/html"
+     * <li>"text/rtf"
+     * <li>"text/enriched"
+     * <li>"text/richtext"
+     * <li>"text/uri-list"
+     * <li>"text/tab-separated-values"
+     * <li>"text/t140"
+     * <li>"text/rfc822-headers"
+     * <li>"text/parityfec"
+     * <li>"text/directory"
+     * <li>"text/css"
+     * <li>"text/calendar"
+     * <li>"application/x-java-serialized-object"
+     * <li>"text/plain"
+     * <li>"text/&lt;other&gt;"
+     * </ul>
+     * <p>For example, "text/sgml" will be selected over
+     * "text/html", and <code>DataFlavor.stringFlavor</code> will be chosen
+     * over <code>DataFlavor.plainTextFlavor</code>.
+     * <p>
+     * If two or more flavors share the best MIME type in the array, then that
+     * MIME type will be checked to see if it supports the charset parameter.
+     * <p>
+     * The following MIME types support, or are treated as though they support,
+     * the charset parameter:
+     * <ul>
+     * <li>"text/sgml"
+     * <li>"text/xml"
+     * <li>"text/html"
+     * <li>"text/enriched"
+     * <li>"text/richtext"
+     * <li>"text/uri-list"
+     * <li>"text/directory"
+     * <li>"text/css"
+     * <li>"text/calendar"
+     * <li>"application/x-java-serialized-object"
+     * <li>"text/plain"
+     * </ul>
+     * The following MIME types do not support, or are treated as though they
+     * do not support, the charset parameter:
+     * <ul>
+     * <li>"text/rtf"
+     * <li>"text/tab-separated-values"
+     * <li>"text/t140"
+     * <li>"text/rfc822-headers"
+     * <li>"text/parityfec"
+     * </ul>
+     * For "text/&lt;other&gt;" MIME types, the first time the JRE needs to
+     * determine whether the MIME type supports the charset parameter, it will
+     * check whether the parameter is explicitly listed in an arbitrarily
+     * chosen <code>DataFlavor</code> which uses that MIME type. If so, the JRE
+     * will assume from that point on that the MIME type supports the charset
+     * parameter and will not check again. If the parameter is not explicitly
+     * listed, the JRE will assume from that point on that the MIME type does
+     * not support the charset parameter and will not check again. Because
+     * this check is performed on an arbitrarily chosen
+     * <code>DataFlavor</code>, developers must ensure that all
+     * <code>DataFlavor</code>s with a "text/&lt;other&gt;" MIME type specify
+     * the charset parameter if it is supported by that MIME type. Developers
+     * should never rely on the JRE to substitute the platform's default
+     * charset for a "text/&lt;other&gt;" DataFlavor. Failure to adhere to this
+     * restriction will lead to undefined behavior.
+     * <p>
+     * If the best MIME type in the array does not support the charset
+     * parameter, the flavors which share that MIME type will then be sorted by
+     * their representation classes in the following order:
+     * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
+     * <code>[B</code>, &lt;all others&gt;.
+     * <p>
+     * If two or more flavors share the best representation class, or if no
+     * flavor has one of the three specified representations, then one of those
+     * flavors will be chosen non-deterministically.
+     * <p>
+     * If the best MIME type in the array does support the charset parameter,
+     * the flavors which share that MIME type will then be sorted by their
+     * representation classes in the following order:
+     * <code>java.io.Reader</code>, <code>java.lang.String</code>,
+     * <code>java.nio.CharBuffer</code>, <code>[C</code>, &lt;all others&gt;.
+     * <p>
+     * If two or more flavors share the best representation class, and that
+     * representation is one of the four explicitly listed, then one of those
+     * flavors will be chosen non-deterministically. If, however, no flavor has
+     * one of the four specified representations, the flavors will then be
+     * sorted by their charsets. Unicode charsets, such as "UTF-16", "UTF-8",
+     * "UTF-16BE", "UTF-16LE", and their aliases, are considered best. After
+     * them, the platform default charset and its aliases are selected.
+     * "US-ASCII" and its aliases are worst. All other charsets are chosen in
+     * alphabetical order, but only charsets supported by this implementation
+     * of the Java platform will be considered.
+     * <p>
+     * If two or more flavors share the best charset, the flavors will then
+     * again be sorted by their representation classes in the following order:
+     * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
+     * <code>[B</code>, &lt;all others&gt;.
+     * <p>
+     * If two or more flavors share the best representation class, or if no
+     * flavor has one of the three specified representations, then one of those
+     * flavors will be chosen non-deterministically.
+     *
+     * @param availableFlavors an array of available <code>DataFlavor</code>s
+     * @return the best (highest fidelity) flavor according to the rules
+     *         specified above, or <code>null</code>,
+     *         if <code>availableFlavors</code> is <code>null</code>,
+     *         has zero length, or contains no text flavors
+     * @since 1.3
+     */
+    public static final DataFlavor selectBestTextFlavor(
+                                       DataFlavor[] availableFlavors) {
+        if (availableFlavors == null || availableFlavors.length == 0) {
+            return null;
+        }
+
+        DataFlavor bestFlavor = Collections.max(Arrays.asList(availableFlavors),
+                                                DataFlavorUtil.getTextFlavorComparator());
+
+        if (!bestFlavor.isFlavorTextType()) {
+            return null;
+        }
+
+        return bestFlavor;
+    }
+
+    /**
+     * Gets a Reader for a text flavor, decoded, if necessary, for the expected
+     * charset (encoding). The supported representation classes are
+     * <code>java.io.Reader</code>, <code>java.lang.String</code>,
+     * <code>java.nio.CharBuffer</code>, <code>[C</code>,
+     * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
+     * and <code>[B</code>.
+     * <p>
+     * Because text flavors which do not support the charset parameter are
+     * encoded in a non-standard format, this method should not be called for
+     * such flavors. However, in order to maintain backward-compatibility,
+     * if this method is called for such a flavor, this method will treat the
+     * flavor as though it supports the charset parameter and attempt to
+     * decode it accordingly. See <code>selectBestTextFlavor</code> for a list
+     * of text flavors which do not support the charset parameter.
+     *
+     * @param transferable the <code>Transferable</code> whose data will be
+     *        requested in this flavor
+     *
+     * @return a <code>Reader</code> to read the <code>Transferable</code>'s
+     *         data
+     *
+     * @exception IllegalArgumentException if the representation class
+     *            is not one of the seven listed above
+     * @exception IllegalArgumentException if the <code>Transferable</code>
+     *            has <code>null</code> data
+     * @exception NullPointerException if the <code>Transferable</code> is
+     *            <code>null</code>
+     * @exception UnsupportedEncodingException if this flavor's representation
+     *            is <code>java.io.InputStream</code>,
+     *            <code>java.nio.ByteBuffer</code>, or <code>[B</code> and
+     *            this flavor's encoding is not supported by this
+     *            implementation of the Java platform
+     * @exception UnsupportedFlavorException if the <code>Transferable</code>
+     *            does not support this flavor
+     * @exception IOException if the data cannot be read because of an
+     *            I/O error
+     * @see #selectBestTextFlavor
+     * @since 1.3
+     */
+    public Reader getReaderForText(Transferable transferable)
+        throws UnsupportedFlavorException, IOException
+    {
+        Object transferObject = transferable.getTransferData(this);
+        if (transferObject == null) {
+            throw new IllegalArgumentException
+                ("getTransferData() returned null");
+        }
+
+        if (transferObject instanceof Reader) {
+            return (Reader)transferObject;
+        } else if (transferObject instanceof String) {
+            return new StringReader((String)transferObject);
+        } else if (transferObject instanceof CharBuffer) {
+            CharBuffer buffer = (CharBuffer)transferObject;
+            int size = buffer.remaining();
+            char[] chars = new char[size];
+            buffer.get(chars, 0, size);
+            return new CharArrayReader(chars);
+        } else if (transferObject instanceof char[]) {
+            return new CharArrayReader((char[])transferObject);
+        }
+
+        InputStream stream = null;
+
+        if (transferObject instanceof InputStream) {
+            stream = (InputStream)transferObject;
+        } else if (transferObject instanceof ByteBuffer) {
+            ByteBuffer buffer = (ByteBuffer)transferObject;
+            int size = buffer.remaining();
+            byte[] bytes = new byte[size];
+            buffer.get(bytes, 0, size);
+            stream = new ByteArrayInputStream(bytes);
+        } else if (transferObject instanceof byte[]) {
+            stream = new ByteArrayInputStream((byte[])transferObject);
+        }
+
+        if (stream == null) {
+            throw new IllegalArgumentException("transfer data is not Reader, String, CharBuffer, char array, InputStream, ByteBuffer, or byte array");
+        }
+
+        String encoding = getParameter("charset");
+        return (encoding == null)
+            ? new InputStreamReader(stream)
+            : new InputStreamReader(stream, encoding);
+    }
+
+    /**
+     * Returns the MIME type string for this <code>DataFlavor</code>.
+     * @return the MIME type string for this flavor
+     */
+    public String getMimeType() {
+        return (mimeType != null) ? mimeType.toString() : null;
+    }
+
+    /**
+     * Returns the <code>Class</code> which objects supporting this
+     * <code>DataFlavor</code> will return when this <code>DataFlavor</code>
+     * is requested.
+     * @return the <code>Class</code> which objects supporting this
+     * <code>DataFlavor</code> will return when this <code>DataFlavor</code>
+     * is requested
+     */
+    public Class<?> getRepresentationClass() {
+        return representationClass;
+    }
+
+    /**
+     * Returns the human presentable name for the data format that this
+     * <code>DataFlavor</code> represents.  This name would be localized
+     * for different countries.
+     * @return the human presentable name for the data format that this
+     *    <code>DataFlavor</code> represents
+     */
+    public String getHumanPresentableName() {
+        return humanPresentableName;
+    }
+
+    /**
+     * Returns the primary MIME type for this <code>DataFlavor</code>.
+     * @return the primary MIME type of this <code>DataFlavor</code>
+     */
+    public String getPrimaryType() {
+        return (mimeType != null) ? mimeType.getPrimaryType() : null;
+    }
+
+    /**
+     * Returns the sub MIME type of this <code>DataFlavor</code>.
+     * @return the Sub MIME type of this <code>DataFlavor</code>
+     */
+    public String getSubType() {
+        return (mimeType != null) ? mimeType.getSubType() : null;
+    }
+
+    /**
+     * Returns the human presentable name for this <code>DataFlavor</code>
+     * if <code>paramName</code> equals "humanPresentableName".  Otherwise
+     * returns the MIME type value associated with <code>paramName</code>.
+     *
+     * @param paramName the parameter name requested
+     * @return the value of the name parameter, or <code>null</code>
+     *  if there is no associated value
+     */
+    public String getParameter(String paramName) {
+        if (paramName.equals("humanPresentableName")) {
+            return humanPresentableName;
+        } else {
+            return (mimeType != null)
+                ? mimeType.getParameter(paramName) : null;
+        }
+    }
+
+    /**
+     * Sets the human presentable name for the data format that this
+     * <code>DataFlavor</code> represents. This name would be localized
+     * for different countries.
+     * @param humanPresentableName the new human presentable name
+     */
+    public void setHumanPresentableName(String humanPresentableName) {
+        this.humanPresentableName = humanPresentableName;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The equals comparison for the {@code DataFlavor} class is implemented
+     * as follows: Two <code>DataFlavor</code>s are considered equal if and
+     * only if their MIME primary type and subtype and representation class are
+     * equal. Additionally, if the primary type is "text", the subtype denotes
+     * a text flavor which supports the charset parameter, and the
+     * representation class is not <code>java.io.Reader</code>,
+     * <code>java.lang.String</code>, <code>java.nio.CharBuffer</code>, or
+     * <code>[C</code>, the <code>charset</code> parameter must also be equal.
+     * If a charset is not explicitly specified for one or both
+     * <code>DataFlavor</code>s, the platform default encoding is assumed. See
+     * <code>selectBestTextFlavor</code> for a list of text flavors which
+     * support the charset parameter.
+     *
+     * @param o the <code>Object</code> to compare with <code>this</code>
+     * @return <code>true</code> if <code>that</code> is equivalent to this
+     *         <code>DataFlavor</code>; <code>false</code> otherwise
+     * @see #selectBestTextFlavor
+     */
+    public boolean equals(Object o) {
+        return ((o instanceof DataFlavor) && equals((DataFlavor)o));
+    }
+
+    /**
+     * This method has the same behavior as {@link #equals(Object)}.
+     * The only difference being that it takes a {@code DataFlavor} instance
+     * as a parameter.
+     *
+     * @param that the <code>DataFlavor</code> to compare with
+     *        <code>this</code>
+     * @return <code>true</code> if <code>that</code> is equivalent to this
+     *         <code>DataFlavor</code>; <code>false</code> otherwise
+     * @see #selectBestTextFlavor
+     */
+    public boolean equals(DataFlavor that) {
+        if (that == null) {
+            return false;
+        }
+        if (this == that) {
+            return true;
+        }
+
+        if (!Objects.equals(this.getRepresentationClass(), that.getRepresentationClass())) {
+            return false;
+        }
+
+        if (mimeType == null) {
+            if (that.mimeType != null) {
+                return false;
+            }
+        } else {
+            if (!mimeType.match(that.mimeType)) {
+                return false;
+            }
+
+            if ("text".equals(getPrimaryType())) {
+                if (DataFlavorUtil.doesSubtypeSupportCharset(this)
+                        && representationClass != null
+                        && !isStandardTextRepresentationClass()) {
+                    String thisCharset =
+                            DataFlavorUtil.canonicalName(this.getParameter("charset"));
+                    String thatCharset =
+                            DataFlavorUtil.canonicalName(that.getParameter("charset"));
+                    if (!Objects.equals(thisCharset, thatCharset)) {
+                        return false;
+                    }
+                }
+
+                if ("html".equals(getSubType())) {
+                    String thisDocument = this.getParameter("document");
+                    String thatDocument = that.getParameter("document");
+                    if (!Objects.equals(thisDocument, thatDocument)) {
+                        return false;
+                    }
+                }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Compares only the <code>mimeType</code> against the passed in
+     * <code>String</code> and <code>representationClass</code> is
+     * not considered in the comparison.
+     *
+     * If <code>representationClass</code> needs to be compared, then
+     * <code>equals(new DataFlavor(s))</code> may be used.
+     * @deprecated As inconsistent with <code>hashCode()</code> contract,
+     *             use <code>isMimeTypeEqual(String)</code> instead.
+     * @param s the {@code mimeType} to compare.
+     * @return true if the String (MimeType) is equal; false otherwise or if
+     *         {@code s} is {@code null}
+     */
+    @Deprecated
+    public boolean equals(String s) {
+        if (s == null || mimeType == null)
+            return false;
+        return isMimeTypeEqual(s);
+    }
+
+    /**
+     * Returns hash code for this <code>DataFlavor</code>.
+     * For two equal <code>DataFlavor</code>s, hash codes are equal.
+     * For the <code>String</code>
+     * that matches <code>DataFlavor.equals(String)</code>, it is not
+     * guaranteed that <code>DataFlavor</code>'s hash code is equal
+     * to the hash code of the <code>String</code>.
+     *
+     * @return a hash code for this <code>DataFlavor</code>
+     */
+    public int hashCode() {
+        int total = 0;
+
+        if (representationClass != null) {
+            total += representationClass.hashCode();
+        }
+
+        if (mimeType != null) {
+            String primaryType = mimeType.getPrimaryType();
+            if (primaryType != null) {
+                total += primaryType.hashCode();
+            }
+
+            // Do not add subType.hashCode() to the total. equals uses
+            // MimeType.match which reports a match if one or both of the
+            // subTypes is '*', regardless of the other subType.
+
+            if ("text".equals(primaryType)) {
+                if (DataFlavorUtil.doesSubtypeSupportCharset(this)
+                        && representationClass != null
+                        && !isStandardTextRepresentationClass()) {
+                    String charset = DataFlavorUtil.canonicalName(getParameter("charset"));
+                    if (charset != null) {
+                        total += charset.hashCode();
+                    }
+                }
+
+                if ("html".equals(getSubType())) {
+                    String document = this.getParameter("document");
+                    if (document != null) {
+                        total += document.hashCode();
+                    }
+                }
+            }
+        }
+
+        return total;
+    }
+
+    /**
+     * Identical to {@link #equals(DataFlavor)}.
+     *
+     * @param that the <code>DataFlavor</code> to compare with
+     *        <code>this</code>
+     * @return <code>true</code> if <code>that</code> is equivalent to this
+     *         <code>DataFlavor</code>; <code>false</code> otherwise
+     * @see #selectBestTextFlavor
+     * @since 1.3
+     */
+    public boolean match(DataFlavor that) {
+        return equals(that);
+    }
+
+    /**
+     * Returns whether the string representation of the MIME type passed in
+     * is equivalent to the MIME type of this <code>DataFlavor</code>.
+     * Parameters are not included in the comparison.
+     *
+     * @param mimeType the string representation of the MIME type
+     * @return true if the string representation of the MIME type passed in is
+     *         equivalent to the MIME type of this <code>DataFlavor</code>;
+     *         false otherwise
+     * @throws NullPointerException if mimeType is <code>null</code>
+     */
+    public boolean isMimeTypeEqual(String mimeType) {
+        // JCK Test DataFlavor0117: if 'mimeType' is null, throw NPE
+        if (mimeType == null) {
+            throw new NullPointerException("mimeType");
+        }
+        if (this.mimeType == null) {
+            return false;
+        }
+        try {
+            return this.mimeType.match(new MimeType(mimeType));
+        } catch (MimeTypeParseException mtpe) {
+            return false;
+        }
+    }
+
+    /**
+     * Compares the <code>mimeType</code> of two <code>DataFlavor</code>
+     * objects. No parameters are considered.
+     *
+     * @param dataFlavor the <code>DataFlavor</code> to be compared
+     * @return true if the <code>MimeType</code>s are equal,
+     *  otherwise false
+     */
+
+    public final boolean isMimeTypeEqual(DataFlavor dataFlavor) {
+        return isMimeTypeEqual(dataFlavor.mimeType);
+    }
+
+    /**
+     * Compares the <code>mimeType</code> of two <code>DataFlavor</code>
+     * objects.  No parameters are considered.
+     *
+     * @return true if the <code>MimeType</code>s are equal,
+     *  otherwise false
+     */
+
+    private boolean isMimeTypeEqual(MimeType mtype) {
+        if (this.mimeType == null) {
+            return (mtype == null);
+        }
+        return mimeType.match(mtype);
+    }
+
+    /**
+     * Checks if the representation class is one of the standard text
+     * representation classes.
+     *
+     * @return true if the representation class is one of the standard text
+     *              representation classes, otherwise false
+     */
+    private boolean isStandardTextRepresentationClass() {
+        return isRepresentationClassReader()
+                || String.class.equals(representationClass)
+                || isRepresentationClassCharBuffer()
+                || char[].class.equals(representationClass);
+    }
+
+   /**
+    * Does the <code>DataFlavor</code> represent a serialized object?
+    * @return whether or not a serialized object is represented
+    */
+    public boolean isMimeTypeSerializedObject() {
+        return isMimeTypeEqual(javaSerializedObjectMimeType);
+    }
+
+    /**
+     * Returns the default representation class.
+     * @return the default representation class
+     */
+    public final Class<?> getDefaultRepresentationClass() {
+        return ioInputStreamClass;
+    }
+
+    /**
+     * Returns the name of the default representation class.
+     * @return the name of the default representation class
+     */
+    public final String getDefaultRepresentationClassAsString() {
+        return getDefaultRepresentationClass().getName();
+    }
+
+   /**
+    * Does the <code>DataFlavor</code> represent a
+    * <code>java.io.InputStream</code>?
+    * @return whether or not this {@code DataFlavor} represent a
+    * {@code java.io.InputStream}
+    */
+    public boolean isRepresentationClassInputStream() {
+        return ioInputStreamClass.isAssignableFrom(representationClass);
+    }
+
+    /**
+     * Returns whether the representation class for this
+     * <code>DataFlavor</code> is <code>java.io.Reader</code> or a subclass
+     * thereof.
+     * @return whether or not the representation class for this
+     * {@code DataFlavor} is {@code java.io.Reader} or a subclass
+     * thereof
+     *
+     * @since 1.4
+     */
+    public boolean isRepresentationClassReader() {
+        return java.io.Reader.class.isAssignableFrom(representationClass);
+    }
+
+    /**
+     * Returns whether the representation class for this
+     * <code>DataFlavor</code> is <code>java.nio.CharBuffer</code> or a
+     * subclass thereof.
+     * @return whether or not the representation class for this
+     * {@code DataFlavor} is {@code java.nio.CharBuffer} or a subclass
+     * thereof
+     *
+     * @since 1.4
+     */
+    public boolean isRepresentationClassCharBuffer() {
+        return java.nio.CharBuffer.class.isAssignableFrom(representationClass);
+    }
+
+    /**
+     * Returns whether the representation class for this
+     * <code>DataFlavor</code> is <code>java.nio.ByteBuffer</code> or a
+     * subclass thereof.
+     * @return whether or not the representation class for this
+     * {@code DataFlavor} is {@code java.nio.ByteBuffer} or a subclass
+     * thereof
+     *
+     * @since 1.4
+     */
+    public boolean isRepresentationClassByteBuffer() {
+        return java.nio.ByteBuffer.class.isAssignableFrom(representationClass);
+    }
+
+   /**
+    * Returns true if the representation class can be serialized.
+    * @return true if the representation class can be serialized
+    */
+
+    public boolean isRepresentationClassSerializable() {
+        return java.io.Serializable.class.isAssignableFrom(representationClass);
+    }
+
+   /**
+    * Returns true if the representation class is <code>Remote</code>.
+    * @return true if the representation class is <code>Remote</code>
+    */
+    public boolean isRepresentationClassRemote() {
+        return DataFlavorUtil.RMI.isRemote(representationClass);
+    }
+
+   /**
+    * Returns true if the <code>DataFlavor</code> specified represents
+    * a serialized object.
+    * @return true if the <code>DataFlavor</code> specified represents
+    *   a Serialized Object
+    */
+
+    public boolean isFlavorSerializedObjectType() {
+        return isRepresentationClassSerializable() && isMimeTypeEqual(javaSerializedObjectMimeType);
+    }
+
+    /**
+     * Returns true if the <code>DataFlavor</code> specified represents
+     * a remote object.
+     * @return true if the <code>DataFlavor</code> specified represents
+     *  a Remote Object
+     */
+
+    public boolean isFlavorRemoteObjectType() {
+        return isRepresentationClassRemote()
+            && isRepresentationClassSerializable()
+            && isMimeTypeEqual(javaRemoteObjectMimeType);
+    }
+
+
+   /**
+    * Returns true if the <code>DataFlavor</code> specified represents
+    * a list of file objects.
+    * @return true if the <code>DataFlavor</code> specified represents
+    *   a List of File objects
+    */
+
+   public boolean isFlavorJavaFileListType() {
+        if (mimeType == null || representationClass == null)
+            return false;
+        return java.util.List.class.isAssignableFrom(representationClass) &&
+               mimeType.match(javaFileListFlavor.mimeType);
+
+   }
+
+    /**
+     * Returns whether this <code>DataFlavor</code> is a valid text flavor for
+     * this implementation of the Java platform. Only flavors equivalent to
+     * <code>DataFlavor.stringFlavor</code> and <code>DataFlavor</code>s with
+     * a primary MIME type of "text" can be valid text flavors.
+     * <p>
+     * If this flavor supports the charset parameter, it must be equivalent to
+     * <code>DataFlavor.stringFlavor</code>, or its representation must be
+     * <code>java.io.Reader</code>, <code>java.lang.String</code>,
+     * <code>java.nio.CharBuffer</code>, <code>[C</code>,
+     * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>, or
+     * <code>[B</code>. If the representation is
+     * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>, or
+     * <code>[B</code>, then this flavor's <code>charset</code> parameter must
+     * be supported by this implementation of the Java platform. If a charset
+     * is not specified, then the platform default charset, which is always
+     * supported, is assumed.
+     * <p>
+     * If this flavor does not support the charset parameter, its
+     * representation must be <code>java.io.InputStream</code>,
+     * <code>java.nio.ByteBuffer</code>, or <code>[B</code>.
+     * <p>
+     * See <code>selectBestTextFlavor</code> for a list of text flavors which
+     * support the charset parameter.
+     *
+     * @return <code>true</code> if this <code>DataFlavor</code> is a valid
+     *         text flavor as described above; <code>false</code> otherwise
+     * @see #selectBestTextFlavor
+     * @since 1.4
+     */
+    public boolean isFlavorTextType() {
+        return (DataFlavorUtil.isFlavorCharsetTextType(this) ||
+                DataFlavorUtil.isFlavorNoncharsetTextType(this));
+    }
+
+   /**
+    * Serializes this <code>DataFlavor</code>.
+    */
+
+   public synchronized void writeExternal(ObjectOutput os) throws IOException {
+       if (mimeType != null) {
+           mimeType.setParameter("humanPresentableName", humanPresentableName);
+           os.writeObject(mimeType);
+           mimeType.removeParameter("humanPresentableName");
+       } else {
+           os.writeObject(null);
+       }
+
+       os.writeObject(representationClass);
+   }
+
+   /**
+    * Restores this <code>DataFlavor</code> from a Serialized state.
+    */
+
+   public synchronized void readExternal(ObjectInput is) throws IOException , ClassNotFoundException {
+       String rcn = null;
+        mimeType = (MimeType)is.readObject();
+
+        if (mimeType != null) {
+            humanPresentableName =
+                mimeType.getParameter("humanPresentableName");
+            mimeType.removeParameter("humanPresentableName");
+            rcn = mimeType.getParameter("class");
+            if (rcn == null) {
+                throw new IOException("no class parameter specified in: " +
+                                      mimeType);
+            }
+        }
+
+        try {
+            representationClass = (Class)is.readObject();
+        } catch (OptionalDataException ode) {
+            if (!ode.eof || ode.length != 0) {
+                throw ode;
+            }
+            // Ensure backward compatibility.
+            // Old versions didn't write the representation class to the stream.
+            if (rcn != null) {
+                representationClass =
+                    DataFlavor.tryToLoadClass(rcn, getClass().getClassLoader());
+            }
+        }
+   }
+
+   /**
+    * Returns a clone of this <code>DataFlavor</code>.
+    * @return a clone of this <code>DataFlavor</code>
+    */
+
+    public Object clone() throws CloneNotSupportedException {
+        Object newObj = super.clone();
+        if (mimeType != null) {
+            ((DataFlavor)newObj).mimeType = (MimeType)mimeType.clone();
+        }
+        return newObj;
+    } // clone()
+
+   /**
+    * Called on <code>DataFlavor</code> for every MIME Type parameter
+    * to allow <code>DataFlavor</code> subclasses to handle special
+    * parameters like the text/plain <code>charset</code>
+    * parameters, whose values are case insensitive.  (MIME type parameter
+    * values are supposed to be case sensitive.
+    * <p>
+    * This method is called for each parameter name/value pair and should
+    * return the normalized representation of the <code>parameterValue</code>.
+    *
+    * This method is never invoked by this implementation from 1.1 onwards.
+    *
+    * @param parameterName the parameter name
+    * @param parameterValue the parameter value
+    * @return the parameter value
+    * @deprecated
+    */
+    @Deprecated
+    protected String normalizeMimeTypeParameter(String parameterName, String parameterValue) {
+        return parameterValue;
+    }
+
+   /**
+    * Called for each MIME type string to give <code>DataFlavor</code> subtypes
+    * the opportunity to change how the normalization of MIME types is
+    * accomplished.  One possible use would be to add default
+    * parameter/value pairs in cases where none are present in the MIME
+    * type string passed in.
+    *
+    * This method is never invoked by this implementation from 1.1 onwards.
+    *
+    * @param mimeType the mime type
+    * @return the mime type
+    * @deprecated
+    */
+    @Deprecated
+    protected String normalizeMimeType(String mimeType) {
+        return mimeType;
+    }
+
+    /*
+     * fields
+     */
+
+    /* placeholder for caching any platform-specific data for flavor */
+
+    transient int       atom;
+
+    /* Mime Type of DataFlavor */
+
+    MimeType            mimeType;
+
+    private String      humanPresentableName;
+
+    /** Java class of objects this DataFlavor represents **/
+
+    private Class<?>       representationClass;
+
+} // class DataFlavor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/FlavorEvent.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2003, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.awt.datatransfer;
+
+import java.util.EventObject;
+
+
+/**
+ * <code>FlavorEvent</code> is used to notify interested parties
+ * that available {@link DataFlavor}s have changed in the
+ * {@link Clipboard} (the event source).
+ *
+ * @see FlavorListener
+ *
+ * @author Alexander Gerasimov
+ * @since 1.5
+ */
+public class FlavorEvent extends EventObject {
+    private static final long serialVersionUID = -5842664112252414548L;
+
+    /**
+     * Constructs a <code>FlavorEvent</code> object.
+     *
+     * @param source  the <code>Clipboard</code> that is the source of the event
+     *
+     * @throws IllegalArgumentException if the {@code source} is {@code null}
+     */
+    public FlavorEvent(Clipboard source) {
+        super(source);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/FlavorListener.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.awt.datatransfer;
+
+import java.util.EventListener;
+
+
+/**
+ * Defines an object which listens for {@link FlavorEvent}s.
+ *
+ * @author Alexander Gerasimov
+ * @since 1.5
+ */
+public interface FlavorListener extends EventListener {
+    /**
+     * Invoked when the target {@link Clipboard} of the listener
+     * has changed its available {@link DataFlavor}s.
+     * <p>
+     * Some notifications may be redundant &#8212; they are not
+     * caused by a change of the set of DataFlavors available
+     * on the clipboard.
+     * For example, if the clipboard subsystem supposes that
+     * the system clipboard's contents has been changed but it
+     * can't ascertain whether its DataFlavors have been changed
+     * because of some exceptional condition when accessing the
+     * clipboard, the notification is sent to ensure from omitting
+     * a significant notification. Ordinarily, those redundant
+     * notifications should be occasional.
+     *
+     * @param e  a <code>FlavorEvent</code> object
+     */
+    void flavorsChanged(FlavorEvent e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/FlavorMap.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+import java.util.Map;
+
+
+/**
+ * A two-way Map between "natives" (Strings), which correspond to platform-
+ * specific data formats, and "flavors" (DataFlavors), which correspond to
+ * platform-independent MIME types. FlavorMaps need not be symmetric, but
+ * typically are.
+ *
+ *
+ * @since 1.2
+ */
+public interface FlavorMap {
+
+    /**
+     * Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to
+     * their corresponding <code>String</code> native. The returned
+     * <code>Map</code> is a modifiable copy of this <code>FlavorMap</code>'s
+     * internal data. Client code is free to modify the <code>Map</code>
+     * without affecting this object.
+     *
+     * @param flavors an array of <code>DataFlavor</code>s which will be the
+     *        key set of the returned <code>Map</code>. If <code>null</code> is
+     *        specified, a mapping of all <code>DataFlavor</code>s currently
+     *        known to this <code>FlavorMap</code> to their corresponding
+     *        <code>String</code> natives will be returned.
+     * @return a <code>java.util.Map</code> of <code>DataFlavor</code>s to
+     *         <code>String</code> natives
+     */
+    Map<DataFlavor,String> getNativesForFlavors(DataFlavor[] flavors);
+
+    /**
+     * Returns a <code>Map</code> of the specified <code>String</code> natives
+     * to their corresponding <code>DataFlavor</code>. The returned
+     * <code>Map</code> is a modifiable copy of this <code>FlavorMap</code>'s
+     * internal data. Client code is free to modify the <code>Map</code>
+     * without affecting this object.
+     *
+     * @param natives an array of <code>String</code>s which will be the
+     *        key set of the returned <code>Map</code>. If <code>null</code> is
+     *        specified, a mapping of all <code>String</code> natives currently
+     *        known to this <code>FlavorMap</code> to their corresponding
+     *        <code>DataFlavor</code>s will be returned.
+     * @return a <code>java.util.Map</code> of <code>String</code> natives to
+     *         <code>DataFlavor</code>s
+     */
+    Map<String,DataFlavor> getFlavorsForNatives(String[] natives);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/FlavorTable.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+import java.util.List;
+
+
+/**
+ * A FlavorMap which relaxes the traditional 1-to-1 restriction of a Map. A
+ * flavor is permitted to map to any number of natives, and likewise a native
+ * is permitted to map to any number of flavors. FlavorTables need not be
+ * symmetric, but typically are.
+ *
+ * @author David Mendenhall
+ *
+ * @since 1.4
+ */
+public interface FlavorTable extends FlavorMap {
+
+    /**
+     * Returns a <code>List</code> of <code>String</code> natives to which the
+     * specified <code>DataFlavor</code> corresponds. The <code>List</code>
+     * will be sorted from best native to worst. That is, the first native will
+     * best reflect data in the specified flavor to the underlying native
+     * platform. The returned <code>List</code> is a modifiable copy of this
+     * <code>FlavorTable</code>'s internal data. Client code is free to modify
+     * the <code>List</code> without affecting this object.
+     *
+     * @param flav the <code>DataFlavor</code> whose corresponding natives
+     *        should be returned. If <code>null</code> is specified, all
+     *        natives currently known to this <code>FlavorTable</code> are
+     *        returned in a non-deterministic order.
+     * @return a <code>java.util.List</code> of <code>java.lang.String</code>
+     *         objects which are platform-specific representations of platform-
+     *         specific data formats
+     */
+    List<String> getNativesForFlavor(DataFlavor flav);
+
+    /**
+     * Returns a <code>List</code> of <code>DataFlavor</code>s to which the
+     * specified <code>String</code> corresponds. The <code>List</code> will be
+     * sorted from best <code>DataFlavor</code> to worst. That is, the first
+     * <code>DataFlavor</code> will best reflect data in the specified
+     * native to a Java application. The returned <code>List</code> is a
+     * modifiable copy of this <code>FlavorTable</code>'s internal data.
+     * Client code is free to modify the <code>List</code> without affecting
+     * this object.
+     *
+     * @param nat the native whose corresponding <code>DataFlavor</code>s
+     *        should be returned. If <code>null</code> is specified, all
+     *        <code>DataFlavor</code>s currently known to this
+     *        <code>FlavorTable</code> are returned in a non-deterministic
+     *        order.
+     * @return a <code>java.util.List</code> of <code>DataFlavor</code>
+     *         objects into which platform-specific data in the specified,
+     *         platform-specific native can be translated
+     */
+    List<DataFlavor> getFlavorsForNative(String nat);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/MimeType.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,394 @@
+/*
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+import java.io.Externalizable;
+import java.io.ObjectOutput;
+import java.io.ObjectInput;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Locale;
+
+
+/**
+ * A Multipurpose Internet Mail Extension (MIME) type, as defined
+ * in RFC 2045 and 2046.
+ *
+ * THIS IS *NOT* - REPEAT *NOT* - A PUBLIC CLASS! DataFlavor IS
+ * THE PUBLIC INTERFACE, AND THIS IS PROVIDED AS A ***PRIVATE***
+ * (THAT IS AS IN *NOT* PUBLIC) HELPER CLASS!
+ */
+class MimeType implements Externalizable, Cloneable {
+
+    /*
+     * serialization support
+     */
+
+    static final long serialVersionUID = -6568722458793895906L;
+
+    /**
+     * Constructor for externalization; this constructor should not be
+     * called directly by an application, since the result will be an
+     * uninitialized, immutable <code>MimeType</code> object.
+     */
+    public MimeType() {
+    }
+
+    /**
+     * Builds a <code>MimeType</code> from a <code>String</code>.
+     *
+     * @param rawdata text used to initialize the <code>MimeType</code>
+     * @throws NullPointerException if <code>rawdata</code> is null
+     */
+    public MimeType(String rawdata) throws MimeTypeParseException {
+        parse(rawdata);
+    }
+
+    /**
+     * Builds a <code>MimeType</code> with the given primary and sub
+     * type but has an empty parameter list.
+     *
+     * @param primary the primary type of this <code>MimeType</code>
+     * @param sub the subtype of this <code>MimeType</code>
+     * @throws NullPointerException if either <code>primary</code> or
+     *         <code>sub</code> is null
+     */
+    public MimeType(String primary, String sub) throws MimeTypeParseException {
+        this(primary, sub, new MimeTypeParameterList());
+    }
+
+    /**
+     * Builds a <code>MimeType</code> with a pre-defined
+     * and valid (or empty) parameter list.
+     *
+     * @param primary the primary type of this <code>MimeType</code>
+     * @param sub the subtype of this <code>MimeType</code>
+     * @param mtpl the requested parameter list
+     * @throws NullPointerException if either <code>primary</code>,
+     *         <code>sub</code> or <code>mtpl</code> is null
+     */
+    public MimeType(String primary, String sub, MimeTypeParameterList mtpl) throws
+MimeTypeParseException {
+        //    check to see if primary is valid
+        if(isValidToken(primary)) {
+            primaryType = primary.toLowerCase(Locale.ENGLISH);
+        } else {
+            throw new MimeTypeParseException("Primary type is invalid.");
+        }
+
+        //    check to see if sub is valid
+        if(isValidToken(sub)) {
+            subType = sub.toLowerCase(Locale.ENGLISH);
+        } else {
+            throw new MimeTypeParseException("Sub type is invalid.");
+        }
+
+        parameters = (MimeTypeParameterList)mtpl.clone();
+    }
+
+    public int hashCode() {
+
+        // We sum up the hash codes for all of the strings. This
+        // way, the order of the strings is irrelevant
+        int code = 0;
+        code += primaryType.hashCode();
+        code += subType.hashCode();
+        code += parameters.hashCode();
+        return code;
+    } // hashCode()
+
+    /**
+     * <code>MimeType</code>s are equal if their primary types,
+     * subtypes, and  parameters are all equal. No default values
+     * are taken into account.
+     * @param thatObject the object to be evaluated as a
+     *    <code>MimeType</code>
+     * @return <code>true</code> if <code>thatObject</code> is
+     *    a <code>MimeType</code>; otherwise returns <code>false</code>
+     */
+    public boolean equals(Object thatObject) {
+        if (!(thatObject instanceof MimeType)) {
+            return false;
+        }
+        MimeType that = (MimeType)thatObject;
+        boolean isIt =
+            ((this.primaryType.equals(that.primaryType)) &&
+             (this.subType.equals(that.subType)) &&
+             (this.parameters.equals(that.parameters)));
+        return isIt;
+    } // equals()
+
+    /**
+     * A routine for parsing the MIME type out of a String.
+     *
+     * @throws NullPointerException if <code>rawdata</code> is null
+     */
+    private void parse(String rawdata) throws MimeTypeParseException {
+        int slashIndex = rawdata.indexOf('/');
+        int semIndex = rawdata.indexOf(';');
+        if((slashIndex < 0) && (semIndex < 0)) {
+            //    neither character is present, so treat it
+            //    as an error
+            throw new MimeTypeParseException("Unable to find a sub type.");
+        } else if((slashIndex < 0) && (semIndex >= 0)) {
+            //    we have a ';' (and therefore a parameter list),
+            //    but no '/' indicating a sub type is present
+            throw new MimeTypeParseException("Unable to find a sub type.");
+        } else if((slashIndex >= 0) && (semIndex < 0)) {
+            //    we have a primary and sub type but no parameter list
+            primaryType = rawdata.substring(0,slashIndex).
+                trim().toLowerCase(Locale.ENGLISH);
+            subType = rawdata.substring(slashIndex + 1).
+                trim().toLowerCase(Locale.ENGLISH);
+            parameters = new MimeTypeParameterList();
+        } else if (slashIndex < semIndex) {
+            //    we have all three items in the proper sequence
+            primaryType = rawdata.substring(0, slashIndex).
+                trim().toLowerCase(Locale.ENGLISH);
+            subType = rawdata.substring(slashIndex + 1,
+                semIndex).trim().toLowerCase(Locale.ENGLISH);
+            parameters = new
+MimeTypeParameterList(rawdata.substring(semIndex));
+        } else {
+            //    we have a ';' lexically before a '/' which means we have a primary type
+            //    & a parameter list but no sub type
+            throw new MimeTypeParseException("Unable to find a sub type.");
+        }
+
+        //    now validate the primary and sub types
+
+        //    check to see if primary is valid
+        if(!isValidToken(primaryType)) {
+            throw new MimeTypeParseException("Primary type is invalid.");
+        }
+
+        //    check to see if sub is valid
+        if(!isValidToken(subType)) {
+            throw new MimeTypeParseException("Sub type is invalid.");
+        }
+    }
+
+    /**
+     * Retrieve the primary type of this object.
+     */
+    public String getPrimaryType() {
+        return primaryType;
+    }
+
+    /**
+     * Retrieve the sub type of this object.
+     */
+    public String getSubType() {
+        return subType;
+    }
+
+    /**
+     * Retrieve a copy of this object's parameter list.
+     */
+    public MimeTypeParameterList getParameters() {
+        return (MimeTypeParameterList)parameters.clone();
+    }
+
+    /**
+     * Retrieve the value associated with the given name, or null if there
+     * is no current association.
+     */
+    public String getParameter(String name) {
+        return parameters.get(name);
+    }
+
+    /**
+     * Set the value to be associated with the given name, replacing
+     * any previous association.
+     *
+     * @throw IllegalArgumentException if parameter or value is illegal
+     */
+    public void setParameter(String name, String value) {
+        parameters.set(name, value);
+    }
+
+    /**
+     * Remove any value associated with the given name.
+     *
+     * @throw IllegalArgumentException if parameter may not be deleted
+     */
+    public void removeParameter(String name) {
+        parameters.remove(name);
+    }
+
+    /**
+     * Return the String representation of this object.
+     */
+    public String toString() {
+        return getBaseType() + parameters.toString();
+    }
+
+    /**
+     * Return a String representation of this object
+     * without the parameter list.
+     */
+    public String getBaseType() {
+        return primaryType + "/" + subType;
+    }
+
+    /**
+     * Returns <code>true</code> if the primary type and the
+     * subtype of this object are the same as the specified
+     * <code>type</code>; otherwise returns <code>false</code>.
+     *
+     * @param type the type to compare to <code>this</code>'s type
+     * @return <code>true</code> if the primary type and the
+     *    subtype of this object are the same as the
+     *    specified <code>type</code>; otherwise returns
+     *    <code>false</code>
+     */
+    public boolean match(MimeType type) {
+        if (type == null)
+            return false;
+        return primaryType.equals(type.getPrimaryType())
+                    && (subType.equals("*")
+                            || type.getSubType().equals("*")
+                            || (subType.equals(type.getSubType())));
+    }
+
+    /**
+     * Returns <code>true</code> if the primary type and the
+     * subtype of this object are the same as the content type
+     * described in <code>rawdata</code>; otherwise returns
+     * <code>false</code>.
+     *
+     * @param rawdata the raw data to be examined
+     * @return <code>true</code> if the primary type and the
+     *    subtype of this object are the same as the content type
+     *    described in <code>rawdata</code>; otherwise returns
+     *    <code>false</code>; if <code>rawdata</code> is
+     *    <code>null</code>, returns <code>false</code>
+     */
+    public boolean match(String rawdata) throws MimeTypeParseException {
+        if (rawdata == null)
+            return false;
+        return match(new MimeType(rawdata));
+    }
+
+    /**
+     * The object implements the writeExternal method to save its contents
+     * by calling the methods of DataOutput for its primitive values or
+     * calling the writeObject method of ObjectOutput for objects, strings
+     * and arrays.
+     * @exception IOException Includes any I/O exceptions that may occur
+     */
+    public void writeExternal(ObjectOutput out) throws IOException {
+        String s = toString(); // contains ASCII chars only
+        // one-to-one correspondence between ASCII char and byte in UTF string
+        if (s.length() <= 65535) { // 65535 is max length of UTF string
+            out.writeUTF(s);
+        } else {
+            out.writeByte(0);
+            out.writeByte(0);
+            out.writeInt(s.length());
+            out.write(s.getBytes());
+        }
+    }
+
+    /**
+     * The object implements the readExternal method to restore its
+     * contents by calling the methods of DataInput for primitive
+     * types and readObject for objects, strings and arrays.  The
+     * readExternal method must read the values in the same sequence
+     * and with the same types as were written by writeExternal.
+     * @exception ClassNotFoundException If the class for an object being
+     *              restored cannot be found.
+     */
+    public void readExternal(ObjectInput in) throws IOException,
+ClassNotFoundException {
+        String s = in.readUTF();
+        if (s == null || s.length() == 0) { // long mime type
+            byte[] ba = new byte[in.readInt()];
+            in.readFully(ba);
+            s = new String(ba);
+        }
+        try {
+            parse(s);
+        } catch(MimeTypeParseException e) {
+            throw new IOException(e.toString());
+        }
+    }
+
+    /**
+     * Returns a clone of this object.
+     * @return a clone of this object
+     */
+
+    public Object clone() {
+        MimeType newObj = null;
+        try {
+            newObj = (MimeType)super.clone();
+        } catch (CloneNotSupportedException cannotHappen) {
+        }
+        newObj.parameters = (MimeTypeParameterList)parameters.clone();
+        return newObj;
+    }
+
+    private String    primaryType;
+    private String    subType;
+    private MimeTypeParameterList parameters;
+
+    //    below here be scary parsing related things
+
+    /**
+     * Determines whether or not a given character belongs to a legal token.
+     */
+    private static boolean isTokenChar(char c) {
+        return ((c > 040) && (c < 0177)) && (TSPECIALS.indexOf(c) < 0);
+    }
+
+    /**
+     * Determines whether or not a given string is a legal token.
+     *
+     * @throws NullPointerException if <code>s</code> is null
+     */
+    private boolean isValidToken(String s) {
+        int len = s.length();
+        if(len > 0) {
+            for (int i = 0; i < len; ++i) {
+                char c = s.charAt(i);
+                if (!isTokenChar(c)) {
+                    return false;
+                }
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * A string that holds all the special chars.
+     */
+
+    private static final String TSPECIALS = "()<>@,;:\\\"/[]?=";
+
+} // class MimeType
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/MimeTypeParameterList.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * An object that encapsulates the parameter list of a MimeType
+ * as defined in RFC 2045 and 2046.
+ *
+ * @author jeff.dunn@eng.sun.com
+ */
+class MimeTypeParameterList implements Cloneable {
+
+    /**
+     * Default constructor.
+     */
+    public MimeTypeParameterList() {
+        parameters = new Hashtable<>();
+    }
+
+    public MimeTypeParameterList(String rawdata)
+        throws MimeTypeParseException
+    {
+        parameters = new Hashtable<>();
+
+        //    now parse rawdata
+        parse(rawdata);
+    }
+
+    public int hashCode() {
+        int code = Integer.MAX_VALUE/45; // "random" value for empty lists
+        String paramName = null;
+        Enumeration<String> enum_ = this.getNames();
+
+        while (enum_.hasMoreElements()) {
+            paramName = enum_.nextElement();
+            code += paramName.hashCode();
+            code += this.get(paramName).hashCode();
+        }
+
+        return code;
+    } // hashCode()
+
+    /**
+     * Two parameter lists are considered equal if they have exactly
+     * the same set of parameter names and associated values. The
+     * order of the parameters is not considered.
+     */
+    public boolean equals(Object thatObject) {
+        //System.out.println("MimeTypeParameterList.equals("+this+","+thatObject+")");
+        if (!(thatObject instanceof MimeTypeParameterList)) {
+            return false;
+        }
+        MimeTypeParameterList that = (MimeTypeParameterList)thatObject;
+        if (this.size() != that.size()) {
+            return false;
+        }
+        String name = null;
+        String thisValue = null;
+        String thatValue = null;
+        Set<Map.Entry<String, String>> entries = parameters.entrySet();
+        Iterator<Map.Entry<String, String>> iterator = entries.iterator();
+        Map.Entry<String, String> entry = null;
+        while (iterator.hasNext()) {
+            entry = iterator.next();
+            name = entry.getKey();
+            thisValue = entry.getValue();
+            thatValue = that.parameters.get(name);
+            if ((thisValue == null) || (thatValue == null)) {
+                // both null -> equal, only one null -> not equal
+                if (thisValue != thatValue) {
+                    return false;
+                }
+            } else if (!thisValue.equals(thatValue)) {
+                return false;
+            }
+        } // while iterator
+
+        return true;
+    } // equals()
+
+    /**
+     * A routine for parsing the parameter list out of a String.
+     */
+    protected void parse(String rawdata) throws MimeTypeParseException {
+        int length = rawdata.length();
+        if(length > 0) {
+            int currentIndex = skipWhiteSpace(rawdata, 0);
+            int lastIndex = 0;
+
+            if(currentIndex < length) {
+                char currentChar = rawdata.charAt(currentIndex);
+                while ((currentIndex < length) && (currentChar == ';')) {
+                    String name;
+                    String value;
+                    boolean foundit;
+
+                    //    eat the ';'
+                    ++currentIndex;
+
+                    //    now parse the parameter name
+
+                    //    skip whitespace
+                    currentIndex = skipWhiteSpace(rawdata, currentIndex);
+
+                    if(currentIndex < length) {
+                        //    find the end of the token char run
+                        lastIndex = currentIndex;
+                        currentChar = rawdata.charAt(currentIndex);
+                        while((currentIndex < length) && isTokenChar(currentChar)) {
+                            ++currentIndex;
+                            currentChar = rawdata.charAt(currentIndex);
+                        }
+                        name = rawdata.substring(lastIndex, currentIndex).toLowerCase();
+
+                        //    now parse the '=' that separates the name from the value
+
+                        //    skip whitespace
+                        currentIndex = skipWhiteSpace(rawdata, currentIndex);
+
+                        if((currentIndex < length) && (rawdata.charAt(currentIndex) == '='))  {
+                            //    eat it and parse the parameter value
+                            ++currentIndex;
+
+                            //    skip whitespace
+                            currentIndex = skipWhiteSpace(rawdata, currentIndex);
+
+                            if(currentIndex < length) {
+                                //    now find out whether or not we have a quoted value
+                                currentChar = rawdata.charAt(currentIndex);
+                                if(currentChar == '"') {
+                                    //    yup it's quoted so eat it and capture the quoted string
+                                    ++currentIndex;
+                                    lastIndex = currentIndex;
+
+                                    if(currentIndex < length) {
+                                        //    find the next unescaped quote
+                                        foundit = false;
+                                        while((currentIndex < length) && !foundit) {
+                                            currentChar = rawdata.charAt(currentIndex);
+                                            if(currentChar == '\\') {
+                                                //    found an escape sequence so pass this and the next character
+                                                currentIndex += 2;
+                                            } else if(currentChar == '"') {
+                                                //    found it!
+                                                foundit = true;
+                                            } else {
+                                                ++currentIndex;
+                                            }
+                                        }
+                                        if(currentChar == '"') {
+                                            value = unquote(rawdata.substring(lastIndex, currentIndex));
+                                            //    eat the quote
+                                            ++currentIndex;
+                                        } else {
+                                            throw new MimeTypeParseException("Encountered unterminated quoted parameter value.");
+                                        }
+                                    } else {
+                                        throw new MimeTypeParseException("Encountered unterminated quoted parameter value.");
+                                    }
+                                } else if(isTokenChar(currentChar)) {
+                                    //    nope it's an ordinary token so it ends with a non-token char
+                                    lastIndex = currentIndex;
+                                    foundit = false;
+                                    while((currentIndex < length) && !foundit) {
+                                        currentChar = rawdata.charAt(currentIndex);
+
+                                        if(isTokenChar(currentChar)) {
+                                            ++currentIndex;
+                                        } else {
+                                            foundit = true;
+                                        }
+                                    }
+                                    value = rawdata.substring(lastIndex, currentIndex);
+                                } else {
+                                    //    it ain't a value
+                                    throw new MimeTypeParseException("Unexpected character encountered at index " + currentIndex);
+                                }
+
+                                //    now put the data into the hashtable
+                                parameters.put(name, value);
+                            } else {
+                                throw new MimeTypeParseException("Couldn't find a value for parameter named " + name);
+                            }
+                        } else {
+                            throw new MimeTypeParseException("Couldn't find the '=' that separates a parameter name from its value.");
+                        }
+                    } else {
+                        throw new MimeTypeParseException("Couldn't find parameter name");
+                    }
+
+                    //    setup the next iteration
+                    currentIndex = skipWhiteSpace(rawdata, currentIndex);
+                    if(currentIndex < length) {
+                        currentChar = rawdata.charAt(currentIndex);
+                    }
+                }
+                if(currentIndex < length) {
+                    throw new MimeTypeParseException("More characters encountered in input than expected.");
+                }
+            }
+        }
+    }
+
+    /**
+     * return the number of name-value pairs in this list.
+     */
+    public int size() {
+        return parameters.size();
+    }
+
+    /**
+     * Determine whether or not this list is empty.
+     */
+    public boolean isEmpty() {
+        return parameters.isEmpty();
+    }
+
+    /**
+     * Retrieve the value associated with the given name, or null if there
+     * is no current association.
+     */
+    public String get(String name) {
+        return parameters.get(name.trim().toLowerCase());
+    }
+
+    /**
+     * Set the value to be associated with the given name, replacing
+     * any previous association.
+     */
+    public void set(String name, String value) {
+        parameters.put(name.trim().toLowerCase(), value);
+    }
+
+    /**
+     * Remove any value associated with the given name.
+     */
+    public void remove(String name) {
+        parameters.remove(name.trim().toLowerCase());
+    }
+
+    /**
+     * Retrieve an enumeration of all the names in this list.
+     */
+    public Enumeration<String> getNames() {
+        return parameters.keys();
+    }
+
+    public String toString() {
+        // Heuristic: 8 characters per field
+        StringBuilder buffer = new StringBuilder(parameters.size() * 16);
+
+        Enumeration<String> keys = parameters.keys();
+        while(keys.hasMoreElements())
+        {
+            buffer.append("; ");
+
+            String key = keys.nextElement();
+            buffer.append(key);
+            buffer.append('=');
+               buffer.append(quote(parameters.get(key)));
+        }
+
+        return buffer.toString();
+    }
+
+    /**
+     * @return a clone of this object
+     */
+    @SuppressWarnings("unchecked") // Cast from clone
+     public Object clone() {
+         MimeTypeParameterList newObj = null;
+         try {
+             newObj = (MimeTypeParameterList)super.clone();
+         } catch (CloneNotSupportedException cannotHappen) {
+         }
+         newObj.parameters = (Hashtable<String, String>)parameters.clone();
+         return newObj;
+     }
+
+    private Hashtable<String, String> parameters;
+
+    //    below here be scary parsing related things
+
+    /**
+     * Determine whether or not a given character belongs to a legal token.
+     */
+    private static boolean isTokenChar(char c) {
+        return ((c > 040) && (c < 0177)) && (TSPECIALS.indexOf(c) < 0);
+    }
+
+    /**
+     * return the index of the first non white space character in
+     * rawdata at or after index i.
+     */
+    private static int skipWhiteSpace(String rawdata, int i) {
+        int length = rawdata.length();
+        if (i < length) {
+            char c =  rawdata.charAt(i);
+            while ((i < length) && Character.isWhitespace(c)) {
+                ++i;
+                c = rawdata.charAt(i);
+            }
+        }
+
+        return i;
+    }
+
+    /**
+     * A routine that knows how and when to quote and escape the given value.
+     */
+    private static String quote(String value) {
+        boolean needsQuotes = false;
+
+        //    check to see if we actually have to quote this thing
+        int length = value.length();
+        for(int i = 0; (i < length) && !needsQuotes; ++i) {
+            needsQuotes = !isTokenChar(value.charAt(i));
+        }
+
+        if(needsQuotes) {
+            StringBuilder buffer = new StringBuilder((int)(length * 1.5));
+
+            //    add the initial quote
+            buffer.append('"');
+
+            //    add the properly escaped text
+            for(int i = 0; i < length; ++i) {
+                char c = value.charAt(i);
+                if((c == '\\') || (c == '"')) {
+                    buffer.append('\\');
+                }
+                buffer.append(c);
+            }
+
+            //    add the closing quote
+            buffer.append('"');
+
+            return buffer.toString();
+        }
+        else
+        {
+            return value;
+        }
+    }
+
+    /**
+     * A routine that knows how to strip the quotes and escape sequences from the given value.
+     */
+    private static String unquote(String value) {
+        int valueLength = value.length();
+        StringBuilder buffer = new StringBuilder(valueLength);
+
+        boolean escaped = false;
+        for(int i = 0; i < valueLength; ++i) {
+            char currentChar = value.charAt(i);
+            if(!escaped && (currentChar != '\\')) {
+                buffer.append(currentChar);
+            } else if(escaped) {
+                buffer.append(currentChar);
+                escaped = false;
+            } else {
+                escaped = true;
+            }
+        }
+
+        return buffer.toString();
+    }
+
+    /**
+     * A string that holds all the special chars.
+     */
+    private static final String TSPECIALS = "()<>@,;:\\\"/[]?=";
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/MimeTypeParseException.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+
+/**
+ *    A class to encapsulate MimeType parsing related exceptions
+ *
+ * @serial exclude
+ * @since 1.3
+ */
+public class MimeTypeParseException extends Exception {
+
+    // use serialVersionUID from JDK 1.2.2 for interoperability
+    private static final long serialVersionUID = -5604407764691570741L;
+
+    /**
+     * Constructs a MimeTypeParseException with no specified detail message.
+     */
+    public MimeTypeParseException() {
+        super();
+    }
+
+    /**
+     * Constructs a MimeTypeParseException with the specified detail message.
+     *
+     * @param   s   the detail message.
+     */
+    public MimeTypeParseException(String s) {
+        super(s);
+    }
+} // class MimeTypeParseException
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/StringSelection.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1996, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+import java.io.*;
+
+
+/**
+ * A <code>Transferable</code> which implements the capability required
+ * to transfer a <code>String</code>.
+ *
+ * This <code>Transferable</code> properly supports
+ * <code>DataFlavor.stringFlavor</code>
+ * and all equivalent flavors. Support for
+ * <code>DataFlavor.plainTextFlavor</code>
+ * and all equivalent flavors is <b>deprecated</b>. No other
+ * <code>DataFlavor</code>s are supported.
+ *
+ * @see java.awt.datatransfer.DataFlavor#stringFlavor
+ * @see java.awt.datatransfer.DataFlavor#plainTextFlavor
+ */
+public class StringSelection implements Transferable, ClipboardOwner {
+
+    private static final int STRING = 0;
+    private static final int PLAIN_TEXT = 1;
+
+    @SuppressWarnings("deprecation")
+    private static final DataFlavor[] flavors = {
+        DataFlavor.stringFlavor,
+        DataFlavor.plainTextFlavor // deprecated
+    };
+
+    private String data;
+
+    /**
+     * Creates a <code>Transferable</code> capable of transferring
+     * the specified <code>String</code>.
+     * @param data the string to be transferred
+     */
+    public StringSelection(String data) {
+        this.data = data;
+    }
+
+    /**
+     * Returns an array of flavors in which this <code>Transferable</code>
+     * can provide the data. <code>DataFlavor.stringFlavor</code>
+     * is properly supported.
+     * Support for <code>DataFlavor.plainTextFlavor</code> is
+     * <b>deprecated</b>.
+     *
+     * @return an array of length two, whose elements are <code>DataFlavor.
+     *         stringFlavor</code> and <code>DataFlavor.plainTextFlavor</code>
+     */
+    public DataFlavor[] getTransferDataFlavors() {
+        // returning flavors itself would allow client code to modify
+        // our internal behavior
+        return flavors.clone();
+    }
+
+    /**
+     * Returns whether the requested flavor is supported by this
+     * <code>Transferable</code>.
+     *
+     * @param flavor the requested flavor for the data
+     * @return true if <code>flavor</code> is equal to
+     *   <code>DataFlavor.stringFlavor</code> or
+     *   <code>DataFlavor.plainTextFlavor</code>; false if <code>flavor</code>
+     *   is not one of the above flavors
+     * @throws NullPointerException if flavor is <code>null</code>
+     */
+    public boolean isDataFlavorSupported(DataFlavor flavor) {
+        // JCK Test StringSelection0003: if 'flavor' is null, throw NPE
+        for (int i = 0; i < flavors.length; i++) {
+            if (flavor.equals(flavors[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the <code>Transferable</code>'s data in the requested
+     * <code>DataFlavor</code> if possible. If the desired flavor is
+     * <code>DataFlavor.stringFlavor</code>, or an equivalent flavor,
+     * the <code>String</code> representing the selection is
+     * returned. If the desired flavor is
+     * <code>DataFlavor.plainTextFlavor</code>,
+     * or an equivalent flavor, a <code>Reader</code> is returned.
+     * <b>Note:</b> The behavior of this method for
+     * <code>DataFlavor.plainTextFlavor</code>
+     * and equivalent <code>DataFlavor</code>s is inconsistent with the
+     * definition of <code>DataFlavor.plainTextFlavor</code>.
+     *
+     * @param flavor the requested flavor for the data
+     * @return the data in the requested flavor, as outlined above
+     * @throws UnsupportedFlavorException if the requested data flavor is
+     *         not equivalent to either <code>DataFlavor.stringFlavor</code>
+     *         or <code>DataFlavor.plainTextFlavor</code>
+     * @throws IOException if an IOException occurs while retrieving the data.
+     *         By default, StringSelection never throws this exception, but a
+     *         subclass may.
+     * @throws NullPointerException if flavor is <code>null</code>
+     * @see java.io.Reader
+     */
+    public Object getTransferData(DataFlavor flavor)
+        throws UnsupportedFlavorException, IOException
+    {
+        // JCK Test StringSelection0007: if 'flavor' is null, throw NPE
+        if (flavor.equals(flavors[STRING])) {
+            return (Object)data;
+        } else if (flavor.equals(flavors[PLAIN_TEXT])) {
+            return new StringReader(data == null ? "" : data);
+        } else {
+            throw new UnsupportedFlavorException(flavor);
+        }
+    }
+
+    public void lostOwnership(Clipboard clipboard, Transferable contents) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/SystemFlavorMap.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,1094 @@
+/*
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+import sun.datatransfer.DataFlavorUtil;
+import sun.datatransfer.DesktopDatatransferService;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.ref.SoftReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * The SystemFlavorMap is a configurable map between "natives" (Strings), which
+ * correspond to platform-specific data formats, and "flavors" (DataFlavors),
+ * which correspond to platform-independent MIME types. This mapping is used
+ * by the data transfer subsystem to transfer data between Java and native
+ * applications, and between Java applications in separate VMs.
+ *
+ * @since 1.2
+ */
+public final class SystemFlavorMap implements FlavorMap, FlavorTable {
+
+    /**
+     * Constant prefix used to tag Java types converted to native platform
+     * type.
+     */
+    private static String JavaMIME = "JAVA_DATAFLAVOR:";
+
+    private static final Object FLAVOR_MAP_KEY = new Object();
+
+    /**
+     * The list of valid, decoded text flavor representation classes, in order
+     * from best to worst.
+     */
+    private static final String[] UNICODE_TEXT_CLASSES = {
+        "java.io.Reader", "java.lang.String", "java.nio.CharBuffer", "\"[C\""
+    };
+
+    /**
+     * The list of valid, encoded text flavor representation classes, in order
+     * from best to worst.
+     */
+    private static final String[] ENCODED_TEXT_CLASSES = {
+        "java.io.InputStream", "java.nio.ByteBuffer", "\"[B\""
+    };
+
+    /**
+     * A String representing text/plain MIME type.
+     */
+    private static final String TEXT_PLAIN_BASE_TYPE = "text/plain";
+
+    /**
+     * A String representing text/html MIME type.
+     */
+    private static final String HTML_TEXT_BASE_TYPE = "text/html";
+
+    /**
+     * Maps native Strings to Lists of DataFlavors (or base type Strings for
+     * text DataFlavors).
+     * Do not use the field directly, use getNativeToFlavor() instead.
+     */
+    private final Map<String, LinkedHashSet<DataFlavor>> nativeToFlavor = new HashMap<>();
+
+    /**
+     * Accessor to nativeToFlavor map.  Since we use lazy initialization we must
+     * use this accessor instead of direct access to the field which may not be
+     * initialized yet.  This method will initialize the field if needed.
+     *
+     * @return nativeToFlavor
+     */
+    private Map<String, LinkedHashSet<DataFlavor>> getNativeToFlavor() {
+        if (!isMapInitialized) {
+            initSystemFlavorMap();
+        }
+        return nativeToFlavor;
+    }
+
+    /**
+     * Maps DataFlavors (or base type Strings for text DataFlavors) to Lists of
+     * native Strings.
+     * Do not use the field directly, use getFlavorToNative() instead.
+     */
+    private final Map<DataFlavor, LinkedHashSet<String>> flavorToNative = new HashMap<>();
+
+    /**
+     * Accessor to flavorToNative map.  Since we use lazy initialization we must
+     * use this accessor instead of direct access to the field which may not be
+     * initialized yet.  This method will initialize the field if needed.
+     *
+     * @return flavorToNative
+     */
+    private synchronized Map<DataFlavor, LinkedHashSet<String>> getFlavorToNative() {
+        if (!isMapInitialized) {
+            initSystemFlavorMap();
+        }
+        return flavorToNative;
+    }
+
+    /**
+     * Maps a text DataFlavor primary mime-type to the native. Used only to store
+     * standard mappings registered in the flavormap.properties
+     * Do not use this field directly, use getTextTypeToNative() instead.
+     */
+    private Map<String, LinkedHashSet<String>> textTypeToNative = new HashMap<>();
+
+    /**
+     * Shows if the object has been initialized.
+     */
+    private boolean isMapInitialized = false;
+
+    /**
+     * An accessor to textTypeToNative map.  Since we use lazy initialization we
+     * must use this accessor instead of direct access to the field which may not
+     * be initialized yet. This method will initialize the field if needed.
+     *
+     * @return textTypeToNative
+     */
+    private synchronized Map<String, LinkedHashSet<String>> getTextTypeToNative() {
+        if (!isMapInitialized) {
+            initSystemFlavorMap();
+            // From this point the map should not be modified
+            textTypeToNative = Collections.unmodifiableMap(textTypeToNative);
+        }
+        return textTypeToNative;
+    }
+
+    /**
+     * Caches the result of getNativesForFlavor(). Maps DataFlavors to
+     * SoftReferences which reference LinkedHashSet of String natives.
+     */
+    private final SoftCache<DataFlavor, String> nativesForFlavorCache = new SoftCache<>();
+
+    /**
+     * Caches the result getFlavorsForNative(). Maps String natives to
+     * SoftReferences which reference LinkedHashSet of DataFlavors.
+     */
+    private final SoftCache<String, DataFlavor> flavorsForNativeCache = new SoftCache<>();
+
+    /**
+     * Dynamic mapping generation used for text mappings should not be applied
+     * to the DataFlavors and String natives for which the mappings have been
+     * explicitly specified with setFlavorsForNative() or
+     * setNativesForFlavor(). This keeps all such keys.
+     */
+    private Set<Object> disabledMappingGenerationKeys = new HashSet<>();
+
+    /**
+     * Returns the default FlavorMap for this thread's ClassLoader.
+     *
+     * @return the default FlavorMap for this thread's ClassLoader
+     */
+    public static FlavorMap getDefaultFlavorMap() {
+        return DataFlavorUtil.getDesktopService().getFlavorMap(SystemFlavorMap::new);
+    }
+
+    private SystemFlavorMap() {
+    }
+
+    /**
+     * Initializes a SystemFlavorMap by reading flavormap.properties
+     * For thread-safety must be called under lock on this.
+     */
+    private void initSystemFlavorMap() {
+        if (isMapInitialized) {
+            return;
+        }
+        isMapInitialized = true;
+
+        InputStream is = SystemFlavorMap.class.getResourceAsStream("/sun/datatransfer/resources/flavormap.properties");
+        if (is == null) {
+            throw new InternalError("Default flavor mapping not found");
+        }
+
+        try (InputStreamReader isr = new InputStreamReader(is);
+             BufferedReader reader = new BufferedReader(isr)) {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                line = line.trim();
+                if (line.startsWith("#") || line.isEmpty()) continue;
+                while (line.endsWith("\\")) {
+                    line = line.substring(0, line.length() - 1) + reader.readLine().trim();
+                }
+                int delimiterPosition = line.indexOf('=');
+                String key = line.substring(0, delimiterPosition).replace("\\ ", " ");
+                String[] values = line.substring(delimiterPosition + 1, line.length()).split(",");
+                for (String value : values) {
+                    try {
+                        value = loadConvert(value);
+                        MimeType mime = new MimeType(value);
+                        if ("text".equals(mime.getPrimaryType())) {
+                            String charset = mime.getParameter("charset");
+                            if (DataFlavorUtil.doesSubtypeSupportCharset(mime.getSubType(), charset))
+                            {
+                                // We need to store the charset and eoln
+                                // parameters, if any, so that the
+                                // DataTransferer will have this information
+                                // for conversion into the native format.
+                                DesktopDatatransferService desktopService =
+                                        DataFlavorUtil.getDesktopService();
+                                if (desktopService.isDesktopPresent()) {
+                                    desktopService.registerTextFlavorProperties(
+                                            key, charset,
+                                            mime.getParameter("eoln"),
+                                            mime.getParameter("terminators"));
+                                }
+                            }
+
+                            // But don't store any of these parameters in the
+                            // DataFlavor itself for any text natives (even
+                            // non-charset ones). The SystemFlavorMap will
+                            // synthesize the appropriate mappings later.
+                            mime.removeParameter("charset");
+                            mime.removeParameter("class");
+                            mime.removeParameter("eoln");
+                            mime.removeParameter("terminators");
+                            value = mime.toString();
+                        }
+                    } catch (MimeTypeParseException e) {
+                        e.printStackTrace();
+                        continue;
+                    }
+
+                    DataFlavor flavor;
+                    try {
+                        flavor = new DataFlavor(value);
+                    } catch (Exception e) {
+                        try {
+                            flavor = new DataFlavor(value, null);
+                        } catch (Exception ee) {
+                            ee.printStackTrace();
+                            continue;
+                        }
+                    }
+
+                    final LinkedHashSet<DataFlavor> dfs = new LinkedHashSet<>();
+                    dfs.add(flavor);
+
+                    if ("text".equals(flavor.getPrimaryType())) {
+                        dfs.addAll(convertMimeTypeToDataFlavors(value));
+                        store(flavor.mimeType.getBaseType(), key, getTextTypeToNative());
+                    }
+
+                    for (DataFlavor df : dfs) {
+                        store(df, key, getFlavorToNative());
+                        store(key, df, getNativeToFlavor());
+                    }
+                }
+            }
+        } catch (IOException e) {
+            throw new InternalError("Error reading default flavor mapping", e);
+        }
+    }
+
+    // Copied from java.util.Properties
+    private static String loadConvert(String theString) {
+        char aChar;
+        int len = theString.length();
+        StringBuilder outBuffer = new StringBuilder(len);
+
+        for (int x = 0; x < len; ) {
+            aChar = theString.charAt(x++);
+            if (aChar == '\\') {
+                aChar = theString.charAt(x++);
+                if (aChar == 'u') {
+                    // Read the xxxx
+                    int value = 0;
+                    for (int i = 0; i < 4; i++) {
+                        aChar = theString.charAt(x++);
+                        switch (aChar) {
+                            case '0': case '1': case '2': case '3': case '4':
+                            case '5': case '6': case '7': case '8': case '9': {
+                                value = (value << 4) + aChar - '0';
+                                break;
+                            }
+                            case 'a': case 'b': case 'c':
+                            case 'd': case 'e': case 'f': {
+                                value = (value << 4) + 10 + aChar - 'a';
+                                break;
+                            }
+                            case 'A': case 'B': case 'C':
+                            case 'D': case 'E': case 'F': {
+                                value = (value << 4) + 10 + aChar - 'A';
+                                break;
+                            }
+                            default: {
+                                throw new IllegalArgumentException(
+                                        "Malformed \\uxxxx encoding.");
+                            }
+                        }
+                    }
+                    outBuffer.append((char)value);
+                } else {
+                    if (aChar == 't') {
+                        aChar = '\t';
+                    } else if (aChar == 'r') {
+                        aChar = '\r';
+                    } else if (aChar == 'n') {
+                        aChar = '\n';
+                    } else if (aChar == 'f') {
+                        aChar = '\f';
+                    }
+                    outBuffer.append(aChar);
+                }
+            } else {
+                outBuffer.append(aChar);
+            }
+        }
+        return outBuffer.toString();
+    }
+
+    /**
+     * Stores the listed object under the specified hash key in map. Unlike a
+     * standard map, the listed object will not replace any object already at
+     * the appropriate Map location, but rather will be appended to a List
+     * stored in that location.
+     */
+    private <H, L> void store(H hashed, L listed, Map<H, LinkedHashSet<L>> map) {
+        LinkedHashSet<L> list = map.get(hashed);
+        if (list == null) {
+            list = new LinkedHashSet<>(1);
+            map.put(hashed, list);
+        }
+        if (!list.contains(listed)) {
+            list.add(listed);
+        }
+    }
+
+    /**
+     * Semantically equivalent to 'nativeToFlavor.get(nat)'. This method
+     * handles the case where 'nat' is not found in 'nativeToFlavor'. In that
+     * case, a new DataFlavor is synthesized, stored, and returned, if and
+     * only if the specified native is encoded as a Java MIME type.
+     */
+    private LinkedHashSet<DataFlavor> nativeToFlavorLookup(String nat) {
+        LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(nat);
+
+        if (nat != null && !disabledMappingGenerationKeys.contains(nat)) {
+            DesktopDatatransferService desktopService = DataFlavorUtil.getDesktopService();
+            if (desktopService.isDesktopPresent()) {
+                LinkedHashSet<DataFlavor> platformFlavors =
+                        desktopService.getPlatformMappingsForNative(nat);
+                if (!platformFlavors.isEmpty()) {
+                    if (flavors != null) {
+                        // Prepending the platform-specific mappings ensures
+                        // that the flavors added with
+                        // addFlavorForUnencodedNative() are at the end of
+                        // list.
+                        platformFlavors.addAll(flavors);
+                    }
+                    flavors = platformFlavors;
+                }
+            }
+        }
+
+        if (flavors == null && isJavaMIMEType(nat)) {
+            String decoded = decodeJavaMIMEType(nat);
+            DataFlavor flavor = null;
+
+            try {
+                flavor = new DataFlavor(decoded);
+            } catch (Exception e) {
+                System.err.println("Exception \"" + e.getClass().getName() +
+                                   ": " + e.getMessage()  +
+                                   "\"while constructing DataFlavor for: " +
+                                   decoded);
+            }
+
+            if (flavor != null) {
+                flavors = new LinkedHashSet<>(1);
+                getNativeToFlavor().put(nat, flavors);
+                flavors.add(flavor);
+                flavorsForNativeCache.remove(nat);
+
+                LinkedHashSet<String> natives = getFlavorToNative().get(flavor);
+                if (natives == null) {
+                    natives = new LinkedHashSet<>(1);
+                    getFlavorToNative().put(flavor, natives);
+                }
+                natives.add(nat);
+                nativesForFlavorCache.remove(flavor);
+            }
+        }
+
+        return (flavors != null) ? flavors : new LinkedHashSet<>(0);
+    }
+
+    /**
+     * Semantically equivalent to 'flavorToNative.get(flav)'. This method
+     * handles the case where 'flav' is not found in 'flavorToNative' depending
+     * on the value of passes 'synthesize' parameter. If 'synthesize' is
+     * SYNTHESIZE_IF_NOT_FOUND a native is synthesized, stored, and returned by
+     * encoding the DataFlavor's MIME type. Otherwise an empty List is returned
+     * and 'flavorToNative' remains unaffected.
+     */
+    private LinkedHashSet<String> flavorToNativeLookup(final DataFlavor flav,
+                                                       final boolean synthesize) {
+
+        LinkedHashSet<String> natives = getFlavorToNative().get(flav);
+
+        if (flav != null && !disabledMappingGenerationKeys.contains(flav)) {
+            DesktopDatatransferService desktopService = DataFlavorUtil.getDesktopService();
+            if (desktopService.isDesktopPresent()) {
+                LinkedHashSet<String> platformNatives =
+                        desktopService.getPlatformMappingsForFlavor(flav);
+                if (!platformNatives.isEmpty()) {
+                    if (natives != null) {
+                        // Prepend the platform-specific mappings to ensure
+                        // that the natives added with
+                        // addUnencodedNativeForFlavor() are at the end of
+                        // list.
+                        platformNatives.addAll(natives);
+                    }
+                    natives = platformNatives;
+                }
+            }
+        }
+
+        if (natives == null) {
+            if (synthesize) {
+                String encoded = encodeDataFlavor(flav);
+                natives = new LinkedHashSet<>(1);
+                getFlavorToNative().put(flav, natives);
+                natives.add(encoded);
+
+                LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(encoded);
+                if (flavors == null) {
+                    flavors = new LinkedHashSet<>(1);
+                    getNativeToFlavor().put(encoded, flavors);
+                }
+                flavors.add(flav);
+
+                nativesForFlavorCache.remove(flav);
+                flavorsForNativeCache.remove(encoded);
+            } else {
+                natives = new LinkedHashSet<>(0);
+            }
+        }
+
+        return new LinkedHashSet<>(natives);
+    }
+
+    /**
+     * Returns a <code>List</code> of <code>String</code> natives to which the
+     * specified <code>DataFlavor</code> can be translated by the data transfer
+     * subsystem. The <code>List</code> will be sorted from best native to
+     * worst. That is, the first native will best reflect data in the specified
+     * flavor to the underlying native platform.
+     * <p>
+     * If the specified <code>DataFlavor</code> is previously unknown to the
+     * data transfer subsystem and the data transfer subsystem is unable to
+     * translate this <code>DataFlavor</code> to any existing native, then
+     * invoking this method will establish a
+     * mapping in both directions between the specified <code>DataFlavor</code>
+     * and an encoded version of its MIME type as its native.
+     *
+     * @param flav the <code>DataFlavor</code> whose corresponding natives
+     *        should be returned. If <code>null</code> is specified, all
+     *        natives currently known to the data transfer subsystem are
+     *        returned in a non-deterministic order.
+     * @return a <code>java.util.List</code> of <code>java.lang.String</code>
+     *         objects which are platform-specific representations of platform-
+     *         specific data formats
+     *
+     * @see #encodeDataFlavor
+     * @since 1.4
+     */
+    @Override
+    public synchronized List<String> getNativesForFlavor(DataFlavor flav) {
+        LinkedHashSet<String> retval = nativesForFlavorCache.check(flav);
+        if (retval != null) {
+            return new ArrayList<>(retval);
+        }
+
+        if (flav == null) {
+            retval = new LinkedHashSet<>(getNativeToFlavor().keySet());
+        } else if (disabledMappingGenerationKeys.contains(flav)) {
+            // In this case we shouldn't synthesize a native for this flavor,
+            // since its mappings were explicitly specified.
+            retval = flavorToNativeLookup(flav, false);
+        } else if (DataFlavorUtil.isFlavorCharsetTextType(flav)) {
+            retval = new LinkedHashSet<>(0);
+
+            // For text/* flavors, flavor-to-native mappings specified in
+            // flavormap.properties are stored per flavor's base type.
+            if ("text".equals(flav.getPrimaryType())) {
+                LinkedHashSet<String> textTypeNatives =
+                        getTextTypeToNative().get(flav.mimeType.getBaseType());
+                if (textTypeNatives != null) {
+                    retval.addAll(textTypeNatives);
+                }
+            }
+
+            // Also include text/plain natives, but don't duplicate Strings
+            LinkedHashSet<String> textTypeNatives =
+                    getTextTypeToNative().get(TEXT_PLAIN_BASE_TYPE);
+            if (textTypeNatives != null) {
+                retval.addAll(textTypeNatives);
+            }
+
+            if (retval.isEmpty()) {
+                retval = flavorToNativeLookup(flav, true);
+            } else {
+                // In this branch it is guaranteed that natives explicitly
+                // listed for flav's MIME type were added with
+                // addUnencodedNativeForFlavor(), so they have lower priority.
+                retval.addAll(flavorToNativeLookup(flav, false));
+            }
+        } else if (DataFlavorUtil.isFlavorNoncharsetTextType(flav)) {
+            retval = getTextTypeToNative().get(flav.mimeType.getBaseType());
+
+            if (retval == null || retval.isEmpty()) {
+                retval = flavorToNativeLookup(flav, true);
+            } else {
+                // In this branch it is guaranteed that natives explicitly
+                // listed for flav's MIME type were added with
+                // addUnencodedNativeForFlavor(), so they have lower priority.
+                retval.addAll(flavorToNativeLookup(flav, false));
+            }
+        } else {
+            retval = flavorToNativeLookup(flav, true);
+        }
+
+        nativesForFlavorCache.put(flav, retval);
+        // Create a copy, because client code can modify the returned list.
+        return new ArrayList<>(retval);
+    }
+
+    /**
+     * Returns a <code>List</code> of <code>DataFlavor</code>s to which the
+     * specified <code>String</code> native can be translated by the data
+     * transfer subsystem. The <code>List</code> will be sorted from best
+     * <code>DataFlavor</code> to worst. That is, the first
+     * <code>DataFlavor</code> will best reflect data in the specified
+     * native to a Java application.
+     * <p>
+     * If the specified native is previously unknown to the data transfer
+     * subsystem, and that native has been properly encoded, then invoking this
+     * method will establish a mapping in both directions between the specified
+     * native and a <code>DataFlavor</code> whose MIME type is a decoded
+     * version of the native.
+     * <p>
+     * If the specified native is not a properly encoded native and the
+     * mappings for this native have not been altered with
+     * <code>setFlavorsForNative</code>, then the contents of the
+     * <code>List</code> is platform dependent, but <code>null</code>
+     * cannot be returned.
+     *
+     * @param nat the native whose corresponding <code>DataFlavor</code>s
+     *        should be returned. If <code>null</code> is specified, all
+     *        <code>DataFlavor</code>s currently known to the data transfer
+     *        subsystem are returned in a non-deterministic order.
+     * @return a <code>java.util.List</code> of <code>DataFlavor</code>
+     *         objects into which platform-specific data in the specified,
+     *         platform-specific native can be translated
+     *
+     * @see #encodeJavaMIMEType
+     * @since 1.4
+     */
+    @Override
+    public synchronized List<DataFlavor> getFlavorsForNative(String nat) {
+        LinkedHashSet<DataFlavor> returnValue = flavorsForNativeCache.check(nat);
+        if (returnValue != null) {
+            return new ArrayList<>(returnValue);
+        } else {
+            returnValue = new LinkedHashSet<>();
+        }
+
+        if (nat == null) {
+            for (String n : getNativesForFlavor(null)) {
+                returnValue.addAll(getFlavorsForNative(n));
+            }
+        } else {
+            final LinkedHashSet<DataFlavor> flavors = nativeToFlavorLookup(nat);
+            if (disabledMappingGenerationKeys.contains(nat)) {
+                return new ArrayList<>(flavors);
+            }
+
+            final LinkedHashSet<DataFlavor> flavorsWithSynthesized =
+                    nativeToFlavorLookup(nat);
+
+            for (DataFlavor df : flavorsWithSynthesized) {
+                returnValue.add(df);
+                if ("text".equals(df.getPrimaryType())) {
+                    String baseType = df.mimeType.getBaseType();
+                    returnValue.addAll(convertMimeTypeToDataFlavors(baseType));
+                }
+            }
+        }
+        flavorsForNativeCache.put(nat, returnValue);
+        return new ArrayList<>(returnValue);
+    }
+
+    @SuppressWarnings("deprecation")
+    private static Set<DataFlavor> convertMimeTypeToDataFlavors(
+        final String baseType) {
+
+        final Set<DataFlavor> returnValue = new LinkedHashSet<>();
+
+        String subType = null;
+
+        try {
+            final MimeType mimeType = new MimeType(baseType);
+            subType = mimeType.getSubType();
+        } catch (MimeTypeParseException mtpe) {
+            // Cannot happen, since we checked all mappings
+            // on load from flavormap.properties.
+        }
+
+        if (DataFlavorUtil.doesSubtypeSupportCharset(subType, null)) {
+            if (TEXT_PLAIN_BASE_TYPE.equals(baseType))
+            {
+                returnValue.add(DataFlavor.stringFlavor);
+            }
+
+            for (String unicodeClassName : UNICODE_TEXT_CLASSES) {
+                final String mimeType = baseType + ";charset=Unicode;class=" +
+                                            unicodeClassName;
+
+                final LinkedHashSet<String> mimeTypes =
+                    handleHtmlMimeTypes(baseType, mimeType);
+                for (String mt : mimeTypes) {
+                    DataFlavor toAdd = null;
+                    try {
+                        toAdd = new DataFlavor(mt);
+                    } catch (ClassNotFoundException cannotHappen) {
+                    }
+                    returnValue.add(toAdd);
+                }
+            }
+
+            for (String charset : DataFlavorUtil.standardEncodings()) {
+
+                for (String encodedTextClass : ENCODED_TEXT_CLASSES) {
+                    final String mimeType =
+                            baseType + ";charset=" + charset +
+                            ";class=" + encodedTextClass;
+
+                    final LinkedHashSet<String> mimeTypes =
+                        handleHtmlMimeTypes(baseType, mimeType);
+
+                    for (String mt : mimeTypes) {
+
+                        DataFlavor df = null;
+
+                        try {
+                            df = new DataFlavor(mt);
+                            // Check for equality to plainTextFlavor so
+                            // that we can ensure that the exact charset of
+                            // plainTextFlavor, not the canonical charset
+                            // or another equivalent charset with a
+                            // different name, is used.
+                            if (df.equals(DataFlavor.plainTextFlavor)) {
+                                df = DataFlavor.plainTextFlavor;
+                            }
+                        } catch (ClassNotFoundException cannotHappen) {
+                        }
+
+                        returnValue.add(df);
+                    }
+                }
+            }
+
+            if (TEXT_PLAIN_BASE_TYPE.equals(baseType))
+            {
+                returnValue.add(DataFlavor.plainTextFlavor);
+            }
+        } else {
+            // Non-charset text natives should be treated as
+            // opaque, 8-bit data in any of its various
+            // representations.
+            for (String encodedTextClassName : ENCODED_TEXT_CLASSES) {
+                DataFlavor toAdd = null;
+                try {
+                    toAdd = new DataFlavor(baseType +
+                         ";class=" + encodedTextClassName);
+                } catch (ClassNotFoundException cannotHappen) {
+                }
+                returnValue.add(toAdd);
+            }
+        }
+        return returnValue;
+    }
+
+    private static final String [] htmlDocumentTypes =
+            new String [] {"all", "selection", "fragment"};
+
+    private static LinkedHashSet<String> handleHtmlMimeTypes(String baseType,
+                                                             String mimeType) {
+
+        LinkedHashSet<String> returnValues = new LinkedHashSet<>();
+
+        if (HTML_TEXT_BASE_TYPE.equals(baseType)) {
+            for (String documentType : htmlDocumentTypes) {
+                returnValues.add(mimeType + ";document=" + documentType);
+            }
+        } else {
+            returnValues.add(mimeType);
+        }
+
+        return returnValues;
+    }
+
+    /**
+     * Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to
+     * their most preferred <code>String</code> native. Each native value will
+     * be the same as the first native in the List returned by
+     * <code>getNativesForFlavor</code> for the specified flavor.
+     * <p>
+     * If a specified <code>DataFlavor</code> is previously unknown to the
+     * data transfer subsystem, then invoking this method will establish a
+     * mapping in both directions between the specified <code>DataFlavor</code>
+     * and an encoded version of its MIME type as its native.
+     *
+     * @param flavors an array of <code>DataFlavor</code>s which will be the
+     *        key set of the returned <code>Map</code>. If <code>null</code> is
+     *        specified, a mapping of all <code>DataFlavor</code>s known to the
+     *        data transfer subsystem to their most preferred
+     *        <code>String</code> natives will be returned.
+     * @return a <code>java.util.Map</code> of <code>DataFlavor</code>s to
+     *         <code>String</code> natives
+     *
+     * @see #getNativesForFlavor
+     * @see #encodeDataFlavor
+     */
+    @Override
+    public synchronized Map<DataFlavor,String> getNativesForFlavors(DataFlavor[] flavors)
+    {
+        // Use getNativesForFlavor to generate extra natives for text flavors
+        // and stringFlavor
+
+        if (flavors == null) {
+            List<DataFlavor> flavor_list = getFlavorsForNative(null);
+            flavors = new DataFlavor[flavor_list.size()];
+            flavor_list.toArray(flavors);
+        }
+
+        Map<DataFlavor, String> retval = new HashMap<>(flavors.length, 1.0f);
+        for (DataFlavor flavor : flavors) {
+            List<String> natives = getNativesForFlavor(flavor);
+            String nat = (natives.isEmpty()) ? null : natives.get(0);
+            retval.put(flavor, nat);
+        }
+
+        return retval;
+    }
+
+    /**
+     * Returns a <code>Map</code> of the specified <code>String</code> natives
+     * to their most preferred <code>DataFlavor</code>. Each
+     * <code>DataFlavor</code> value will be the same as the first
+     * <code>DataFlavor</code> in the List returned by
+     * <code>getFlavorsForNative</code> for the specified native.
+     * <p>
+     * If a specified native is previously unknown to the data transfer
+     * subsystem, and that native has been properly encoded, then invoking this
+     * method will establish a mapping in both directions between the specified
+     * native and a <code>DataFlavor</code> whose MIME type is a decoded
+     * version of the native.
+     *
+     * @param natives an array of <code>String</code>s which will be the
+     *        key set of the returned <code>Map</code>. If <code>null</code> is
+     *        specified, a mapping of all supported <code>String</code> natives
+     *        to their most preferred <code>DataFlavor</code>s will be
+     *        returned.
+     * @return a <code>java.util.Map</code> of <code>String</code> natives to
+     *         <code>DataFlavor</code>s
+     *
+     * @see #getFlavorsForNative
+     * @see #encodeJavaMIMEType
+     */
+    @Override
+    public synchronized Map<String,DataFlavor> getFlavorsForNatives(String[] natives)
+    {
+        // Use getFlavorsForNative to generate extra flavors for text natives
+        if (natives == null) {
+            List<String> nativesList = getNativesForFlavor(null);
+            natives = new String[nativesList.size()];
+            nativesList.toArray(natives);
+        }
+
+        Map<String, DataFlavor> retval = new HashMap<>(natives.length, 1.0f);
+        for (String aNative : natives) {
+            List<DataFlavor> flavors = getFlavorsForNative(aNative);
+            DataFlavor flav = (flavors.isEmpty())? null : flavors.get(0);
+            retval.put(aNative, flav);
+        }
+        return retval;
+    }
+
+    /**
+     * Adds a mapping from the specified <code>DataFlavor</code> (and all
+     * <code>DataFlavor</code>s equal to the specified <code>DataFlavor</code>)
+     * to the specified <code>String</code> native.
+     * Unlike <code>getNativesForFlavor</code>, the mapping will only be
+     * established in one direction, and the native will not be encoded. To
+     * establish a two-way mapping, call
+     * <code>addFlavorForUnencodedNative</code> as well. The new mapping will
+     * be of lower priority than any existing mapping.
+     * This method has no effect if a mapping from the specified or equal
+     * <code>DataFlavor</code> to the specified <code>String</code> native
+     * already exists.
+     *
+     * @param flav the <code>DataFlavor</code> key for the mapping
+     * @param nat the <code>String</code> native value for the mapping
+     * @throws NullPointerException if flav or nat is <code>null</code>
+     *
+     * @see #addFlavorForUnencodedNative
+     * @since 1.4
+     */
+    public synchronized void addUnencodedNativeForFlavor(DataFlavor flav,
+                                                         String nat) {
+        Objects.requireNonNull(nat, "Null native not permitted");
+        Objects.requireNonNull(flav, "Null flavor not permitted");
+
+        LinkedHashSet<String> natives = getFlavorToNative().get(flav);
+        if (natives == null) {
+            natives = new LinkedHashSet<>(1);
+            getFlavorToNative().put(flav, natives);
+        }
+        natives.add(nat);
+        nativesForFlavorCache.remove(flav);
+    }
+
+    /**
+     * Discards the current mappings for the specified <code>DataFlavor</code>
+     * and all <code>DataFlavor</code>s equal to the specified
+     * <code>DataFlavor</code>, and creates new mappings to the
+     * specified <code>String</code> natives.
+     * Unlike <code>getNativesForFlavor</code>, the mappings will only be
+     * established in one direction, and the natives will not be encoded. To
+     * establish two-way mappings, call <code>setFlavorsForNative</code>
+     * as well. The first native in the array will represent the highest
+     * priority mapping. Subsequent natives will represent mappings of
+     * decreasing priority.
+     * <p>
+     * If the array contains several elements that reference equal
+     * <code>String</code> natives, this method will establish new mappings
+     * for the first of those elements and ignore the rest of them.
+     * <p>
+     * It is recommended that client code not reset mappings established by the
+     * data transfer subsystem. This method should only be used for
+     * application-level mappings.
+     *
+     * @param flav the <code>DataFlavor</code> key for the mappings
+     * @param natives the <code>String</code> native values for the mappings
+     * @throws NullPointerException if flav or natives is <code>null</code>
+     *         or if natives contains <code>null</code> elements
+     *
+     * @see #setFlavorsForNative
+     * @since 1.4
+     */
+    public synchronized void setNativesForFlavor(DataFlavor flav,
+                                                 String[] natives) {
+        Objects.requireNonNull(natives, "Null natives not permitted");
+        Objects.requireNonNull(flav, "Null flavors not permitted");
+
+        getFlavorToNative().remove(flav);
+        for (String aNative : natives) {
+            addUnencodedNativeForFlavor(flav, aNative);
+        }
+        disabledMappingGenerationKeys.add(flav);
+        nativesForFlavorCache.remove(flav);
+    }
+
+    /**
+     * Adds a mapping from a single <code>String</code> native to a single
+     * <code>DataFlavor</code>. Unlike <code>getFlavorsForNative</code>, the
+     * mapping will only be established in one direction, and the native will
+     * not be encoded. To establish a two-way mapping, call
+     * <code>addUnencodedNativeForFlavor</code> as well. The new mapping will
+     * be of lower priority than any existing mapping.
+     * This method has no effect if a mapping from the specified
+     * <code>String</code> native to the specified or equal
+     * <code>DataFlavor</code> already exists.
+     *
+     * @param nat the <code>String</code> native key for the mapping
+     * @param flav the <code>DataFlavor</code> value for the mapping
+     * @throws NullPointerException if nat or flav is <code>null</code>
+     *
+     * @see #addUnencodedNativeForFlavor
+     * @since 1.4
+     */
+    public synchronized void addFlavorForUnencodedNative(String nat,
+                                                         DataFlavor flav) {
+        Objects.requireNonNull(nat, "Null native not permitted");
+        Objects.requireNonNull(flav, "Null flavor not permitted");
+
+        LinkedHashSet<DataFlavor> flavors = getNativeToFlavor().get(nat);
+        if (flavors == null) {
+            flavors = new LinkedHashSet<>(1);
+            getNativeToFlavor().put(nat, flavors);
+        }
+        flavors.add(flav);
+        flavorsForNativeCache.remove(nat);
+    }
+
+    /**
+     * Discards the current mappings for the specified <code>String</code>
+     * native, and creates new mappings to the specified
+     * <code>DataFlavor</code>s. Unlike <code>getFlavorsForNative</code>, the
+     * mappings will only be established in one direction, and the natives need
+     * not be encoded. To establish two-way mappings, call
+     * <code>setNativesForFlavor</code> as well. The first
+     * <code>DataFlavor</code> in the array will represent the highest priority
+     * mapping. Subsequent <code>DataFlavor</code>s will represent mappings of
+     * decreasing priority.
+     * <p>
+     * If the array contains several elements that reference equal
+     * <code>DataFlavor</code>s, this method will establish new mappings
+     * for the first of those elements and ignore the rest of them.
+     * <p>
+     * It is recommended that client code not reset mappings established by the
+     * data transfer subsystem. This method should only be used for
+     * application-level mappings.
+     *
+     * @param nat the <code>String</code> native key for the mappings
+     * @param flavors the <code>DataFlavor</code> values for the mappings
+     * @throws NullPointerException if nat or flavors is <code>null</code>
+     *         or if flavors contains <code>null</code> elements
+     *
+     * @see #setNativesForFlavor
+     * @since 1.4
+     */
+    public synchronized void setFlavorsForNative(String nat,
+                                                 DataFlavor[] flavors) {
+        Objects.requireNonNull(nat, "Null native not permitted");
+        Objects.requireNonNull(flavors, "Null flavors not permitted");
+
+        getNativeToFlavor().remove(nat);
+        for (DataFlavor flavor : flavors) {
+            addFlavorForUnencodedNative(nat, flavor);
+        }
+        disabledMappingGenerationKeys.add(nat);
+        flavorsForNativeCache.remove(nat);
+    }
+
+    /**
+     * Encodes a MIME type for use as a <code>String</code> native. The format
+     * of an encoded representation of a MIME type is implementation-dependent.
+     * The only restrictions are:
+     * <ul>
+     * <li>The encoded representation is <code>null</code> if and only if the
+     * MIME type <code>String</code> is <code>null</code>.</li>
+     * <li>The encoded representations for two non-<code>null</code> MIME type
+     * <code>String</code>s are equal if and only if these <code>String</code>s
+     * are equal according to <code>String.equals(Object)</code>.</li>
+     * </ul>
+     * <p>
+     * The reference implementation of this method returns the specified MIME
+     * type <code>String</code> prefixed with <code>JAVA_DATAFLAVOR:</code>.
+     *
+     * @param mimeType the MIME type to encode
+     * @return the encoded <code>String</code>, or <code>null</code> if
+     *         mimeType is <code>null</code>
+     */
+    public static String encodeJavaMIMEType(String mimeType) {
+        return (mimeType != null)
+            ? JavaMIME + mimeType
+            : null;
+    }
+
+    /**
+     * Encodes a <code>DataFlavor</code> for use as a <code>String</code>
+     * native. The format of an encoded <code>DataFlavor</code> is
+     * implementation-dependent. The only restrictions are:
+     * <ul>
+     * <li>The encoded representation is <code>null</code> if and only if the
+     * specified <code>DataFlavor</code> is <code>null</code> or its MIME type
+     * <code>String</code> is <code>null</code>.</li>
+     * <li>The encoded representations for two non-<code>null</code>
+     * <code>DataFlavor</code>s with non-<code>null</code> MIME type
+     * <code>String</code>s are equal if and only if the MIME type
+     * <code>String</code>s of these <code>DataFlavor</code>s are equal
+     * according to <code>String.equals(Object)</code>.</li>
+     * </ul>
+     * <p>
+     * The reference implementation of this method returns the MIME type
+     * <code>String</code> of the specified <code>DataFlavor</code> prefixed
+     * with <code>JAVA_DATAFLAVOR:</code>.
+     *
+     * @param flav the <code>DataFlavor</code> to encode
+     * @return the encoded <code>String</code>, or <code>null</code> if
+     *         flav is <code>null</code> or has a <code>null</code> MIME type
+     */
+    public static String encodeDataFlavor(DataFlavor flav) {
+        return (flav != null)
+            ? SystemFlavorMap.encodeJavaMIMEType(flav.getMimeType())
+            : null;
+    }
+
+    /**
+     * Returns whether the specified <code>String</code> is an encoded Java
+     * MIME type.
+     *
+     * @param str the <code>String</code> to test
+     * @return <code>true</code> if the <code>String</code> is encoded;
+     *         <code>false</code> otherwise
+     */
+    public static boolean isJavaMIMEType(String str) {
+        return (str != null && str.startsWith(JavaMIME, 0));
+    }
+
+    /**
+     * Decodes a <code>String</code> native for use as a Java MIME type.
+     *
+     * @param nat the <code>String</code> to decode
+     * @return the decoded Java MIME type, or <code>null</code> if nat is not
+     *         an encoded <code>String</code> native
+     */
+    public static String decodeJavaMIMEType(String nat) {
+        return (isJavaMIMEType(nat))
+            ? nat.substring(JavaMIME.length(), nat.length()).trim()
+            : null;
+    }
+
+    /**
+     * Decodes a <code>String</code> native for use as a
+     * <code>DataFlavor</code>.
+     *
+     * @param nat the <code>String</code> to decode
+     * @return the decoded <code>DataFlavor</code>, or <code>null</code> if
+     *         nat is not an encoded <code>String</code> native
+     * @throws ClassNotFoundException if the class of the data flavor
+     * is not loaded
+     */
+    public static DataFlavor decodeDataFlavor(String nat)
+        throws ClassNotFoundException
+    {
+        String retval_str = SystemFlavorMap.decodeJavaMIMEType(nat);
+        return (retval_str != null)
+            ? new DataFlavor(retval_str)
+            : null;
+    }
+
+    private static final class SoftCache<K, V> {
+        Map<K, SoftReference<LinkedHashSet<V>>> cache;
+
+        public void put(K key, LinkedHashSet<V> value) {
+            if (cache == null) {
+                cache = new HashMap<>(1);
+            }
+            cache.put(key, new SoftReference<>(value));
+        }
+
+        public void remove(K key) {
+            if (cache == null) return;
+            cache.remove(null);
+            cache.remove(key);
+        }
+
+        public LinkedHashSet<V> check(K key) {
+            if (cache == null) return null;
+            SoftReference<LinkedHashSet<V>> ref = cache.get(key);
+            if (ref != null) {
+                return ref.get();
+            }
+            return null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/Transferable.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1996, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+import java.io.IOException;
+
+/**
+ * Defines the interface for classes that can be used to provide data
+ * for a transfer operation.
+ * <p>
+ * For information on using data transfer with Swing, see
+ * <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
+ * How to Use Drag and Drop and Data Transfer</a>,
+ * a section in <em>The Java Tutorial</em>, for more information.
+ *
+ * @author      Amy Fowler
+ */
+
+public interface Transferable {
+
+    /**
+     * Returns an array of DataFlavor objects indicating the flavors the data
+     * can be provided in.  The array should be ordered according to preference
+     * for providing the data (from most richly descriptive to least descriptive).
+     * @return an array of data flavors in which this data can be transferred
+     */
+    public DataFlavor[] getTransferDataFlavors();
+
+    /**
+     * Returns whether or not the specified data flavor is supported for
+     * this object.
+     * @param flavor the requested flavor for the data
+     * @return boolean indicating whether or not the data flavor is supported
+     */
+    public boolean isDataFlavorSupported(DataFlavor flavor);
+
+    /**
+     * Returns an object which represents the data to be transferred.  The class
+     * of the object returned is defined by the representation class of the flavor.
+     *
+     * @param flavor the requested flavor for the data
+     * @return an object which represents the data to be transferred
+     * @see DataFlavor#getRepresentationClass
+     * @exception IOException                if the data is no longer available
+     *              in the requested flavor.
+     * @exception UnsupportedFlavorException if the requested data flavor is
+     *              not supported.
+     */
+    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/UnsupportedFlavorException.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 1996, 2000, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.awt.datatransfer;
+
+/**
+ * Signals that the requested data is not supported in this flavor.
+ * @see Transferable#getTransferData
+ *
+ * @author      Amy Fowler
+ */
+public class UnsupportedFlavorException extends Exception {
+
+    /*
+     * JDK 1.1 serialVersionUID
+     */
+    private static final long serialVersionUID = 5383814944251665601L;
+
+    /**
+     * Constructs an UnsupportedFlavorException.
+     *
+     * @param flavor the flavor object which caused the exception. May
+     *        be <code>null</code>.
+     */
+    public UnsupportedFlavorException(DataFlavor flavor) {
+        super((flavor != null) ? flavor.getHumanPresentableName() : null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/package.html	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,64 @@
+<!--
+ Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation.  Oracle designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Oracle in the LICENSE file that accompanied this code.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ or visit www.oracle.com if you need additional information or have any
+ questions.
+-->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head><title></title></head>
+<body bgcolor="white">
+
+Provides interfaces and classes for transferring data
+between and within applications.  It defines the notion of a
+"transferable" object, which is an object capable of being
+transferred between or within applications. An object identifies
+itself as being transferable by implementing the Transferable
+interface.
+<p>
+It also provides a clipboard mechanism, which is an object that
+temporarily holds a transferable object that can be transferred
+between or within an application. The clipboard is typically used
+for copy and paste operations. Although it is possible to create
+a clipboard to use within an application, most applications will
+use the system clipboard to ensure the data can be transferred
+across applications running on the platform.
+
+<!--
+<h2>Package Specification</h2>
+
+##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
+<ul>
+  <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
+</ul>
+
+<h2>Related Documentation</h2>
+
+For overviews, tutorials, examples, guides, and tool documentation, please see:
+<ul>
+  <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
+</ul>
+-->
+
+@since 1.1
+</body>
+</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/sun/datatransfer/DataFlavorUtil.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,841 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.datatransfer;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.FlavorMap;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.StandardCharsets;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.function.Supplier;
+
+
+/**
+ * Utility class with different datatransfer helper functions
+ *
+ * @see 1.9
+ */
+public class DataFlavorUtil {
+
+    private DataFlavorUtil() {
+        // Avoid instantiation
+    }
+
+    private static Comparator<String> getCharsetComparator() {
+       return CharsetComparator.INSTANCE;
+    }
+
+    public static Comparator<DataFlavor> getDataFlavorComparator() {
+       return DataFlavorComparator.INSTANCE;
+    }
+
+    public static Comparator<Long> getIndexOrderComparator(Map<Long, Integer> indexMap) {
+        return new IndexOrderComparator(indexMap);
+    }
+
+    public static Comparator<DataFlavor> getTextFlavorComparator() {
+        return TextFlavorComparator.INSTANCE;
+    }
+
+    /**
+     * Tracks whether a particular text/* MIME type supports the charset
+     * parameter. The Map is initialized with all of the standard MIME types
+     * listed in the DataFlavor.selectBestTextFlavor method comment. Additional
+     * entries may be added during the life of the JRE for text/<other> types.
+     */
+    private static final Map<String, Boolean> textMIMESubtypeCharsetSupport;
+
+    static {
+        Map<String, Boolean> tempMap = new HashMap<>(17);
+        tempMap.put("sgml", Boolean.TRUE);
+        tempMap.put("xml", Boolean.TRUE);
+        tempMap.put("html", Boolean.TRUE);
+        tempMap.put("enriched", Boolean.TRUE);
+        tempMap.put("richtext", Boolean.TRUE);
+        tempMap.put("uri-list", Boolean.TRUE);
+        tempMap.put("directory", Boolean.TRUE);
+        tempMap.put("css", Boolean.TRUE);
+        tempMap.put("calendar", Boolean.TRUE);
+        tempMap.put("plain", Boolean.TRUE);
+        tempMap.put("rtf", Boolean.FALSE);
+        tempMap.put("tab-separated-values", Boolean.FALSE);
+        tempMap.put("t140", Boolean.FALSE);
+        tempMap.put("rfc822-headers", Boolean.FALSE);
+        tempMap.put("parityfec", Boolean.FALSE);
+        textMIMESubtypeCharsetSupport = Collections.synchronizedMap(tempMap);
+    }
+
+    /**
+     * Lazy initialization of Standard Encodings.
+     */
+    private static class StandardEncodingsHolder {
+        private static final SortedSet<String> standardEncodings = load();
+
+        private static SortedSet<String> load() {
+            final SortedSet<String> tempSet = new TreeSet<>(getCharsetComparator().reversed());
+            tempSet.add("US-ASCII");
+            tempSet.add("ISO-8859-1");
+            tempSet.add("UTF-8");
+            tempSet.add("UTF-16BE");
+            tempSet.add("UTF-16LE");
+            tempSet.add("UTF-16");
+            tempSet.add(Charset.defaultCharset().name());
+            return Collections.unmodifiableSortedSet(tempSet);
+        }
+    }
+
+    /**
+     * Returns a {@code SortedSet} of Strings which are a total order of the standard
+     * character sets supported by the JRE. The ordering follows the same principles as
+     * {@link java.awt.datatransfer.DataFlavor#selectBestTextFlavor(java.awt.datatransfer.DataFlavor[])}.
+     * So as to avoid loading all available character converters, optional, non-standard,
+     * character sets are not included.
+     */
+    public static Set<String> standardEncodings() {
+        return StandardEncodingsHolder.standardEncodings;
+    }
+
+    /**
+     * Converts an arbitrary text encoding to its canonical name.
+     */
+    public static String canonicalName(String encoding) {
+        if (encoding == null) {
+            return null;
+        }
+        try {
+            return Charset.forName(encoding).name();
+        } catch (IllegalCharsetNameException icne) {
+            return encoding;
+        } catch (UnsupportedCharsetException uce) {
+            return encoding;
+        }
+    }
+
+    /**
+     * Tests only whether the flavor's MIME type supports the charset
+     * parameter. Must only be called for flavors with a primary type of
+     * "text".
+     */
+    public static boolean doesSubtypeSupportCharset(DataFlavor flavor) {
+        String subType = flavor.getSubType();
+        if (subType == null) {
+            return false;
+        }
+
+        Boolean support = textMIMESubtypeCharsetSupport.get(subType);
+
+        if (support != null) {
+            return support;
+        }
+
+        boolean ret_val = (flavor.getParameter("charset") != null);
+        textMIMESubtypeCharsetSupport.put(subType, ret_val);
+        return ret_val;
+    }
+    public static boolean doesSubtypeSupportCharset(String subType,
+                                                    String charset)
+    {
+        Boolean support = textMIMESubtypeCharsetSupport.get(subType);
+
+        if (support != null) {
+            return support;
+        }
+
+        boolean ret_val = (charset != null);
+        textMIMESubtypeCharsetSupport.put(subType, ret_val);
+        return ret_val;
+    }
+
+
+    /**
+     * Returns whether this flavor is a text type which supports the
+     * 'charset' parameter.
+     */
+    public static boolean isFlavorCharsetTextType(DataFlavor flavor) {
+        // Although stringFlavor doesn't actually support the charset
+        // parameter (because its primary MIME type is not "text"), it should
+        // be treated as though it does. stringFlavor is semantically
+        // equivalent to "text/plain" data.
+        if (DataFlavor.stringFlavor.equals(flavor)) {
+            return true;
+        }
+
+        if (!"text".equals(flavor.getPrimaryType()) ||
+                !doesSubtypeSupportCharset(flavor))
+        {
+            return false;
+        }
+
+        Class<?> rep_class = flavor.getRepresentationClass();
+
+        if (flavor.isRepresentationClassReader() ||
+                String.class.equals(rep_class) ||
+                flavor.isRepresentationClassCharBuffer() ||
+                char[].class.equals(rep_class))
+        {
+            return true;
+        }
+
+        if (!(flavor.isRepresentationClassInputStream() ||
+                flavor.isRepresentationClassByteBuffer() ||
+                byte[].class.equals(rep_class))) {
+            return false;
+        }
+
+        String charset = flavor.getParameter("charset");
+
+        // null equals default encoding which is always supported
+        return (charset == null) || isEncodingSupported(charset);
+    }
+
+    /**
+     * Returns whether this flavor is a text type which does not support the
+     * 'charset' parameter.
+     */
+    public static boolean isFlavorNoncharsetTextType(DataFlavor flavor) {
+        if (!"text".equals(flavor.getPrimaryType()) || doesSubtypeSupportCharset(flavor)) {
+            return false;
+        }
+
+        return (flavor.isRepresentationClassInputStream() ||
+                flavor.isRepresentationClassByteBuffer() ||
+                byte[].class.equals(flavor.getRepresentationClass()));
+    }
+
+    /**
+     * If the specified flavor is a text flavor which supports the "charset"
+     * parameter, then this method returns that parameter, or the default
+     * charset if no such parameter was specified at construction. For non-
+     * text DataFlavors, and for non-charset text flavors, this method returns
+     * null.
+     */
+    public static String getTextCharset(DataFlavor flavor) {
+        if (!isFlavorCharsetTextType(flavor)) {
+            return null;
+        }
+
+        String encoding = flavor.getParameter("charset");
+
+        return (encoding != null) ? encoding : Charset.defaultCharset().name();
+    }
+
+    /**
+     * Determines whether this JRE can both encode and decode text in the
+     * specified encoding.
+     */
+    private static boolean isEncodingSupported(String encoding) {
+        if (encoding == null) {
+            return false;
+        }
+        try {
+            return Charset.isSupported(encoding);
+        } catch (IllegalCharsetNameException icne) {
+            return false;
+        }
+    }
+
+    /**
+     * Helper method to compare two objects by their Integer indices in the
+     * given map. If the map doesn't contain an entry for either of the
+     * objects, the fallback index will be used for the object instead.
+     *
+     * @param indexMap the map which maps objects into Integer indexes.
+     * @param obj1 the first object to be compared.
+     * @param obj2 the second object to be compared.
+     * @param fallbackIndex the Integer to be used as a fallback index.
+     * @return a negative integer, zero, or a positive integer as the
+     *             first object is mapped to a less, equal to, or greater
+     *             index than the second.
+     */
+    static <T> int compareIndices(Map<T, Integer> indexMap,
+                                  T obj1, T obj2,
+                                  Integer fallbackIndex) {
+        Integer index1 = indexMap.getOrDefault(obj1, fallbackIndex);
+        Integer index2 = indexMap.getOrDefault(obj2, fallbackIndex);
+        return index1.compareTo(index2);
+    }
+
+    /**
+     * An IndexedComparator which compares two String charsets. The comparison
+     * follows the rules outlined in DataFlavor.selectBestTextFlavor. In order
+     * to ensure that non-Unicode, non-ASCII, non-default charsets are sorted
+     * in alphabetical order, charsets are not automatically converted to their
+     * canonical forms.
+     */
+    private static class CharsetComparator implements Comparator<String> {
+        static final CharsetComparator INSTANCE = new CharsetComparator();
+
+        private static final Map<String, Integer> charsets;
+
+        private static final Integer DEFAULT_CHARSET_INDEX = 2;
+        private static final Integer OTHER_CHARSET_INDEX = 1;
+        private static final Integer WORST_CHARSET_INDEX = 0;
+        private static final Integer UNSUPPORTED_CHARSET_INDEX = Integer.MIN_VALUE;
+
+        private static final String UNSUPPORTED_CHARSET = "UNSUPPORTED";
+
+        static {
+            Map<String, Integer> charsetsMap = new HashMap<>(8, 1.0f);
+
+            // we prefer Unicode charsets
+            charsetsMap.put(canonicalName("UTF-16LE"), 4);
+            charsetsMap.put(canonicalName("UTF-16BE"), 5);
+            charsetsMap.put(canonicalName("UTF-8"), 6);
+            charsetsMap.put(canonicalName("UTF-16"), 7);
+
+            // US-ASCII is the worst charset supported
+            charsetsMap.put(canonicalName("US-ASCII"), WORST_CHARSET_INDEX);
+
+            charsetsMap.putIfAbsent(Charset.defaultCharset().name(), DEFAULT_CHARSET_INDEX);
+
+            charsetsMap.put(UNSUPPORTED_CHARSET, UNSUPPORTED_CHARSET_INDEX);
+
+            charsets = Collections.unmodifiableMap(charsetsMap);
+        }
+
+        /**
+         * Compares charsets. Returns a negative integer, zero, or a positive
+         * integer as the first charset is worse than, equal to, or better than
+         * the second.
+         * <p>
+         * Charsets are ordered according to the following rules:
+         * <ul>
+         * <li>All unsupported charsets are equal.
+         * <li>Any unsupported charset is worse than any supported charset.
+         * <li>Unicode charsets, such as "UTF-16", "UTF-8", "UTF-16BE" and
+         *     "UTF-16LE", are considered best.
+         * <li>After them, platform default charset is selected.
+         * <li>"US-ASCII" is the worst of supported charsets.
+         * <li>For all other supported charsets, the lexicographically less
+         *     one is considered the better.
+         * </ul>
+         *
+         * @param charset1 the first charset to be compared
+         * @param charset2 the second charset to be compared.
+         * @return a negative integer, zero, or a positive integer as the
+         *             first argument is worse, equal to, or better than the
+         *             second.
+         */
+        public int compare(String charset1, String charset2) {
+            charset1 = getEncoding(charset1);
+            charset2 = getEncoding(charset2);
+
+            int comp = compareIndices(charsets, charset1, charset2, OTHER_CHARSET_INDEX);
+
+            if (comp == 0) {
+                return charset2.compareTo(charset1);
+            }
+
+            return comp;
+        }
+
+        /**
+         * Returns encoding for the specified charset according to the
+         * following rules:
+         * <ul>
+         * <li>If the charset is <code>null</code>, then <code>null</code> will
+         *     be returned.
+         * <li>Iff the charset specifies an encoding unsupported by this JRE,
+         *     <code>UNSUPPORTED_CHARSET</code> will be returned.
+         * <li>If the charset specifies an alias name, the corresponding
+         *     canonical name will be returned iff the charset is a known
+         *     Unicode, ASCII, or default charset.
+         * </ul>
+         *
+         * @param charset the charset.
+         * @return an encoding for this charset.
+         */
+        static String getEncoding(String charset) {
+            if (charset == null) {
+                return null;
+            } else if (!isEncodingSupported(charset)) {
+                return UNSUPPORTED_CHARSET;
+            } else {
+                // Only convert to canonical form if the charset is one
+                // of the charsets explicitly listed in the known charsets
+                // map. This will happen only for Unicode, ASCII, or default
+                // charsets.
+                String canonicalName = canonicalName(charset);
+                return (charsets.containsKey(canonicalName))
+                        ? canonicalName
+                        : charset;
+            }
+        }
+    }
+
+    /**
+     * An IndexedComparator which compares two DataFlavors. For text flavors,
+     * the comparison follows the rules outlined in
+     * DataFlavor.selectBestTextFlavor. For non-text flavors, unknown
+     * application MIME types are preferred, followed by known
+     * application/x-java-* MIME types. Unknown application types are preferred
+     * because if the user provides his own data flavor, it will likely be the
+     * most descriptive one. For flavors which are otherwise equal, the
+     * flavors' string representation are compared in the alphabetical order.
+     */
+    private static class DataFlavorComparator implements Comparator<DataFlavor> {
+
+        static final DataFlavorComparator INSTANCE = new DataFlavorComparator();
+
+        private static final Map<String, Integer> exactTypes;
+        private static final Map<String, Integer> primaryTypes;
+        private static final Map<Class<?>, Integer> nonTextRepresentations;
+        private static final Map<String, Integer> textTypes;
+        private static final Map<Class<?>, Integer> decodedTextRepresentations;
+        private static final Map<Class<?>, Integer> encodedTextRepresentations;
+
+        private static final Integer UNKNOWN_OBJECT_LOSES = Integer.MIN_VALUE;
+        private static final Integer UNKNOWN_OBJECT_WINS = Integer.MAX_VALUE;
+
+        static {
+            {
+                Map<String, Integer> exactTypesMap = new HashMap<>(4, 1.0f);
+
+                // application/x-java-* MIME types
+                exactTypesMap.put("application/x-java-file-list", 0);
+                exactTypesMap.put("application/x-java-serialized-object", 1);
+                exactTypesMap.put("application/x-java-jvm-local-objectref", 2);
+                exactTypesMap.put("application/x-java-remote-object", 3);
+
+                exactTypes = Collections.unmodifiableMap(exactTypesMap);
+            }
+
+            {
+                Map<String, Integer> primaryTypesMap = new HashMap<>(1, 1.0f);
+
+                primaryTypesMap.put("application", 0);
+
+                primaryTypes = Collections.unmodifiableMap(primaryTypesMap);
+            }
+
+            {
+                Map<Class<?>, Integer> nonTextRepresentationsMap = new HashMap<>(3, 1.0f);
+
+                nonTextRepresentationsMap.put(java.io.InputStream.class, 0);
+                nonTextRepresentationsMap.put(java.io.Serializable.class, 1);
+
+                nonTextRepresentationsMap.put(RMI.remoteClass(), 2);
+
+                nonTextRepresentations = Collections.unmodifiableMap(nonTextRepresentationsMap);
+            }
+
+            {
+                Map<String, Integer> textTypesMap = new HashMap<>(16, 1.0f);
+
+                // plain text
+                textTypesMap.put("text/plain", 0);
+
+                // stringFlavor
+                textTypesMap.put("application/x-java-serialized-object", 1);
+
+                // misc
+                textTypesMap.put("text/calendar", 2);
+                textTypesMap.put("text/css", 3);
+                textTypesMap.put("text/directory", 4);
+                textTypesMap.put("text/parityfec", 5);
+                textTypesMap.put("text/rfc822-headers", 6);
+                textTypesMap.put("text/t140", 7);
+                textTypesMap.put("text/tab-separated-values", 8);
+                textTypesMap.put("text/uri-list", 9);
+
+                // enriched
+                textTypesMap.put("text/richtext", 10);
+                textTypesMap.put("text/enriched", 11);
+                textTypesMap.put("text/rtf", 12);
+
+                // markup
+                textTypesMap.put("text/html", 13);
+                textTypesMap.put("text/xml", 14);
+                textTypesMap.put("text/sgml", 15);
+
+                textTypes = Collections.unmodifiableMap(textTypesMap);
+            }
+
+            {
+                Map<Class<?>, Integer> decodedTextRepresentationsMap = new HashMap<>(4, 1.0f);
+
+                decodedTextRepresentationsMap.put(char[].class, 0);
+                decodedTextRepresentationsMap.put(CharBuffer.class, 1);
+                decodedTextRepresentationsMap.put(String.class, 2);
+                decodedTextRepresentationsMap.put(Reader.class, 3);
+
+                decodedTextRepresentations =
+                        Collections.unmodifiableMap(decodedTextRepresentationsMap);
+            }
+
+            {
+                Map<Class<?>, Integer> encodedTextRepresentationsMap = new HashMap<>(3, 1.0f);
+
+                encodedTextRepresentationsMap.put(byte[].class, 0);
+                encodedTextRepresentationsMap.put(ByteBuffer.class, 1);
+                encodedTextRepresentationsMap.put(InputStream.class, 2);
+
+                encodedTextRepresentations =
+                        Collections.unmodifiableMap(encodedTextRepresentationsMap);
+            }
+        }
+
+
+        public int compare(DataFlavor flavor1, DataFlavor flavor2) {
+            if (flavor1.equals(flavor2)) {
+                return 0;
+            }
+
+            int comp;
+
+            String primaryType1 = flavor1.getPrimaryType();
+            String subType1 = flavor1.getSubType();
+            String mimeType1 = primaryType1 + "/" + subType1;
+            Class<?> class1 = flavor1.getRepresentationClass();
+
+            String primaryType2 = flavor2.getPrimaryType();
+            String subType2 = flavor2.getSubType();
+            String mimeType2 = primaryType2 + "/" + subType2;
+            Class<?> class2 = flavor2.getRepresentationClass();
+
+            if (flavor1.isFlavorTextType() && flavor2.isFlavorTextType()) {
+                // First, compare MIME types
+                comp = compareIndices(textTypes, mimeType1, mimeType2, UNKNOWN_OBJECT_LOSES);
+                if (comp != 0) {
+                    return comp;
+                }
+
+                // Only need to test one flavor because they both have the
+                // same MIME type. Also don't need to worry about accidentally
+                // passing stringFlavor because either
+                //   1. Both flavors are stringFlavor, in which case the
+                //      equality test at the top of the function succeeded.
+                //   2. Only one flavor is stringFlavor, in which case the MIME
+                //      type comparison returned a non-zero value.
+                if (doesSubtypeSupportCharset(flavor1)) {
+                    // Next, prefer the decoded text representations of Reader,
+                    // String, CharBuffer, and [C, in that order.
+                    comp = compareIndices(decodedTextRepresentations, class1,
+                            class2, UNKNOWN_OBJECT_LOSES);
+                    if (comp != 0) {
+                        return comp;
+                    }
+
+                    // Next, compare charsets
+                    comp = CharsetComparator.INSTANCE.compare(getTextCharset(flavor1),
+                            getTextCharset(flavor2));
+                    if (comp != 0) {
+                        return comp;
+                    }
+                }
+
+                // Finally, prefer the encoded text representations of
+                // InputStream, ByteBuffer, and [B, in that order.
+                comp = compareIndices(encodedTextRepresentations, class1,
+                        class2, UNKNOWN_OBJECT_LOSES);
+                if (comp != 0) {
+                    return comp;
+                }
+            } else {
+                // First, prefer application types.
+                comp = compareIndices(primaryTypes, primaryType1, primaryType2,
+                        UNKNOWN_OBJECT_LOSES);
+                if (comp != 0) {
+                    return comp;
+                }
+
+                // Next prefer text types
+                if (flavor1.isFlavorTextType()) {
+                    return 1;
+                }
+
+                if (flavor2.isFlavorTextType()) {
+                    return -1;
+                }
+
+                // Next, look for application/x-java-* types. Prefer unknown
+                // MIME types because if the user provides his own data flavor,
+                // it will likely be the most descriptive one.
+                comp = compareIndices(exactTypes, mimeType1, mimeType2,
+                        UNKNOWN_OBJECT_WINS);
+                if (comp != 0) {
+                    return comp;
+                }
+
+                // Finally, prefer the representation classes of Remote,
+                // Serializable, and InputStream, in that order.
+                comp = compareIndices(nonTextRepresentations, class1, class2,
+                        UNKNOWN_OBJECT_LOSES);
+                if (comp != 0) {
+                    return comp;
+                }
+            }
+
+            // The flavours are not equal but still not distinguishable.
+            // Compare String representations in alphabetical order
+            return flavor1.getMimeType().compareTo(flavor2.getMimeType());
+        }
+    }
+
+    /*
+     * Given the Map that maps objects to Integer indices and a boolean value,
+     * this Comparator imposes a direct or reverse order on set of objects.
+     * <p>
+     * If the specified boolean value is SELECT_BEST, the Comparator imposes the
+     * direct index-based order: an object A is greater than an object B if and
+     * only if the index of A is greater than the index of B. An object that
+     * doesn't have an associated index is less or equal than any other object.
+     * <p>
+     * If the specified boolean value is SELECT_WORST, the Comparator imposes the
+     * reverse index-based order: an object A is greater than an object B if and
+     * only if A is less than B with the direct index-based order.
+     */
+    private static class IndexOrderComparator implements Comparator<Long> {
+        private final Map<Long, Integer> indexMap;
+        private static final Integer FALLBACK_INDEX = Integer.MIN_VALUE;
+
+        public IndexOrderComparator(Map<Long, Integer> indexMap) {
+            this.indexMap = indexMap;
+        }
+
+        public int compare(Long obj1, Long obj2) {
+            return compareIndices(indexMap, obj1, obj2, FALLBACK_INDEX);
+        }
+    }
+
+    private static class TextFlavorComparator extends DataFlavorComparator {
+
+        static final TextFlavorComparator INSTANCE = new TextFlavorComparator();
+        /**
+         * Compares two <code>DataFlavor</code> objects. Returns a negative
+         * integer, zero, or a positive integer as the first
+         * <code>DataFlavor</code> is worse than, equal to, or better than the
+         * second.
+         * <p>
+         * <code>DataFlavor</code>s are ordered according to the rules outlined
+         * for <code>selectBestTextFlavor</code>.
+         *
+         * @param flavor1 the first <code>DataFlavor</code> to be compared
+         * @param flavor2 the second <code>DataFlavor</code> to be compared
+         * @return a negative integer, zero, or a positive integer as the first
+         *         argument is worse, equal to, or better than the second
+         * @throws ClassCastException if either of the arguments is not an
+         *         instance of <code>DataFlavor</code>
+         * @throws NullPointerException if either of the arguments is
+         *         <code>null</code>
+         *
+         * @see java.awt.datatransfer.DataFlavor#selectBestTextFlavor
+         */
+        public int compare(DataFlavor flavor1, DataFlavor flavor2) {
+            if (flavor1.isFlavorTextType()) {
+                if (flavor2.isFlavorTextType()) {
+                    return super.compare(flavor1, flavor2);
+                } else {
+                    return 1;
+                }
+            } else if (flavor2.isFlavorTextType()) {
+                return -1;
+            } else {
+                return 0;
+            }
+        }
+    }
+
+    /**
+     * A fallback implementation of {@link sun.datatransfer.DesktopDatatransferService}
+     * used if there is no desktop.
+     */
+    private static final class DefaultDesktopDatatransferService implements DesktopDatatransferService {
+        static final DesktopDatatransferService INSTANCE = getDesktopService();
+
+        private static DesktopDatatransferService getDesktopService() {
+            ServiceLoader<DesktopDatatransferService> loader =
+                    ServiceLoader.load(DesktopDatatransferService.class, null);
+            Iterator<DesktopDatatransferService> iterator = loader.iterator();
+            if (iterator.hasNext()) {
+                return iterator.next();
+            } else {
+                return new DefaultDesktopDatatransferService();
+            }
+        }
+
+        /**
+         * System singleton FlavorTable.
+         * Only used if there is no desktop
+         * to provide an appropriate FlavorMap.
+         */
+        private volatile FlavorMap flavorMap;
+
+        @Override
+        public void invokeOnEventThread(Runnable r) {
+            r.run();
+        }
+
+        @Override
+        public String getDefaultUnicodeEncoding() {
+            return StandardCharsets.UTF_8.name();
+        }
+
+        @Override
+        public FlavorMap getFlavorMap(Supplier<FlavorMap> supplier) {
+            FlavorMap map = flavorMap;
+            if (map == null) {
+                synchronized (this) {
+                    map = flavorMap;
+                    if (map == null) {
+                        flavorMap = map = supplier.get();
+                    }
+                }
+            }
+            return map;
+        }
+
+        @Override
+        public boolean isDesktopPresent() {
+            return false;
+        }
+
+        @Override
+        public LinkedHashSet<DataFlavor> getPlatformMappingsForNative(String nat) {
+            return new LinkedHashSet<>();
+        }
+
+        @Override
+        public LinkedHashSet<String> getPlatformMappingsForFlavor(DataFlavor df) {
+            return new LinkedHashSet<>();
+        }
+
+        @Override
+        public void registerTextFlavorProperties(String nat, String charset,
+                                                 String eoln, String terminators) {
+            // Not needed if desktop module is absent
+        }
+    }
+
+    public static DesktopDatatransferService getDesktopService() {
+        return DefaultDesktopDatatransferService.INSTANCE;
+    }
+
+    /**
+     * A class that provides access to java.rmi.Remote and java.rmi.MarshalledObject
+     * without creating a static dependency.
+     */
+    public static class RMI {
+        private static final Class<?> remoteClass = getClass("java.rmi.Remote");
+        private static final Class<?> marshallObjectClass = getClass("java.rmi.MarshalledObject");
+        private static final Constructor<?> marshallCtor = getConstructor(marshallObjectClass, Object.class);
+        private static final Method marshallGet = getMethod(marshallObjectClass, "get");
+
+        private static Class<?> getClass(String name) {
+            try {
+                return Class.forName(name, true, null);
+            } catch (ClassNotFoundException e) {
+                return null;
+            }
+        }
+
+        private static Constructor<?> getConstructor(Class<?> c, Class<?>... types) {
+            try {
+                return (c == null) ? null : c.getDeclaredConstructor(types);
+            } catch (NoSuchMethodException x) {
+                throw new AssertionError(x);
+            }
+        }
+
+        private static Method getMethod(Class<?> c, String name, Class<?>... types) {
+            try {
+                return (c == null) ? null : c.getMethod(name, types);
+            } catch (NoSuchMethodException e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        /**
+         * Returns java.rmi.Remote.class if RMI is present; otherwise {@code null}.
+         */
+        static Class<?> remoteClass() {
+            return remoteClass;
+        }
+
+        /**
+         * Returns {@code true} if the given class is java.rmi.Remote.
+         */
+        public static boolean isRemote(Class<?> c) {
+            return (remoteClass != null) && remoteClass.isAssignableFrom(c);
+        }
+
+        /**
+         * Returns a new MarshalledObject containing the serialized representation
+         * of the given object.
+         */
+        public static Object newMarshalledObject(Object obj) throws IOException {
+            try {
+                return marshallCtor == null ? null : marshallCtor.newInstance(obj);
+            } catch (InstantiationException | IllegalAccessException x) {
+                throw new AssertionError(x);
+            } catch (InvocationTargetException x) {
+                Throwable cause = x.getCause();
+                if (cause instanceof IOException)
+                    throw (IOException) cause;
+                throw new AssertionError(x);
+            }
+        }
+
+        /**
+         * Returns a new copy of the contained marshalled object.
+         */
+        public static Object getMarshalledObject(Object obj)
+                throws IOException, ClassNotFoundException {
+            try {
+                return marshallGet == null ? null : marshallGet.invoke(obj);
+            } catch (IllegalAccessException x) {
+                throw new AssertionError(x);
+            } catch (InvocationTargetException x) {
+                Throwable cause = x.getCause();
+                if (cause instanceof IOException)
+                    throw (IOException) cause;
+                if (cause instanceof ClassNotFoundException)
+                    throw (ClassNotFoundException) cause;
+                throw new AssertionError(x);
+            }
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/share/classes/sun/datatransfer/DesktopDatatransferService.java	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,106 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.datatransfer;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.FlavorMap;
+import java.util.LinkedHashSet;
+import java.util.function.Supplier;
+
+/**
+ * Contains services which desktop provides to the datatransfer system
+ * to enrich it's functionality
+ *
+ * @author Petr Pchelko
+ * @since 1.9
+ */
+public interface DesktopDatatransferService {
+
+    /**
+     * If desktop is present - invokes a {@code Runnable} on
+     * the event dispatch thread. Otherwise invokes a {@code run()}
+     * method directly.
+     *
+     * @param r a {@code Runnable} to invoke
+     */
+    void invokeOnEventThread(Runnable r);
+
+    /**
+     * Get a platform-dependent default unicode encoding to use in
+     * datatransfer system.
+     *
+     * @return default unicode encoding
+     */
+    String getDefaultUnicodeEncoding();
+
+    /**
+     * Takes an appropriate {@code FlavorMap} from the desktop.
+     * If no appropriate table is found - uses a provided supplier to
+     * instantiate a table. If the desktop is absent - creates and returns
+     * a system singleton.
+     *
+     * @param supplier a constructor that should be used to create a new instance of
+     *                 the {@code FlavorMap}
+     * @return a {@code FlavorMap}
+     */
+    FlavorMap getFlavorMap(Supplier<FlavorMap> supplier);
+
+    /**
+     * Checks if desktop is present
+     *
+     * @return {@code true} is the desktop is present
+     */
+    boolean isDesktopPresent();
+
+    /**
+     * Returns platform-specific mappings for the specified native format.
+     * If there are no platform-specific mappings for this native, the method
+     * returns an empty {@code Set}
+     *
+     * @param nat a native format to return flavors for
+     * @return set of platform-specific mappings for a native format
+     */
+    LinkedHashSet<DataFlavor> getPlatformMappingsForNative(String nat);
+
+    /**
+     * Returns platform-specific mappings for the specified flavor.
+     * If there are no platform-specific mappings for this flavor, the method
+     * returns an empty {@code Set}
+     *
+     * @param df {@code DataFlavor} to return mappings for
+     * @return set of platform-specific mappings for a {@code DataFlavor}
+     */
+    LinkedHashSet<String> getPlatformMappingsForFlavor(DataFlavor df);
+
+    /**
+     * This method is called for text flavor mappings established while parsing
+     * the default flavor mappings file. It stores the "eoln" and "terminators"
+     * parameters which are not officially part of the MIME type. They are
+     * MIME parameters specific to the flavormap.properties file format.
+     */
+    void registerTextFlavorProperties(String nat, String charset,
+                                      String eoln, String terminators);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/unix/classes/sun/datatransfer/resources/flavormap.properties	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,71 @@
+#
+# This properties file is used to initialize the default
+# java.awt.datatransfer.SystemFlavorMap. It contains the X11 platform-specific,
+# default mappings between common X11 selection atoms and platform-independent
+# MIME type strings, which will be converted into
+# java.awt.datatransfer.DataFlavors.
+#
+# The standard format is:
+#
+# <native>=<MIME type>,<MIME type>, ...
+#
+# <native> should be a string identifier that the native platform will
+# recognize as a valid data format. <MIME type> should specify both a MIME
+# primary type and a MIME subtype separated by a '/'. The MIME type may include
+# parameters, where each parameter is a key/value pair separated by '=', and
+# where each parameter to the MIME type is separated by a ';'.
+#
+# Because SystemFlavorMap implements FlavorTable, developers are free to
+# duplicate DataFlavor values and set multiple values for a single native by
+# separating them with ",". If a mapping contains a duplicate key or value,
+# earlier mappings which included this key or value will be preferred.
+#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", and which support the charset parameter, should specify the exact
+# format in which the native platform expects the data. The "charset"
+# parameter specifies the char to byte encoding, the "eoln" parameter
+# specifies the end-of-line marker, and the "terminators" parameter specifies
+# the number of terminating NUL bytes. Note that "eoln" and "terminators"
+# are not standardized MIME type parameters. They are specific to this file
+# format ONLY. They will not appear in any of the DataFlavors returned by the
+# SystemFlavorMap at the Java level.
+#
+# If the "charset" parameter is omitted, or has zero length, the platform
+# default encoding is assumed. If the "eoln" parameter is omitted, or has
+# zero length, "\n" is assumed. If the "terminators" parameter is omitted,
+# or has a value less than zero, zero is assumed.
+#
+# Upon initialization, the data transfer subsystem will record the specified
+# details of the native text format, but the default SystemFlavorMap will
+# present a large set of synthesized DataFlavors which map, in both
+# directions, to the native. After receiving data from the application in one
+# of the synthetic DataFlavors, the data transfer subsystem will transform
+# the data stream into the format specified in this file before passing the
+# transformed stream to the native system.
+#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", but which do not support the charset parameter, will be treated as
+# opaque, 8-bit data. They will not undergo any transformation process, and
+# any "charset", "eoln", or "terminators" parameters specified in this file
+# will be ignored.
+#
+# See java.awt.datatransfer.DataFlavor.selectBestTextFlavor for a list of
+# text flavors which support the charset parameter.
+
+UTF8_STRING=text/plain;charset=UTF-8;eoln="\n";terminators=0
+
+# The COMPOUND_TEXT support for inter-client text transfer is disabled by 
+# default. The reason is that many native applications prefer this format over 
+# other native text formats, but are unable to decode the textual data in this 
+# format properly. This results in java-to-native text transfer failures.
+# To enable the COMPOUND_TEXT support for this JRE installation uncomment 
+# the line below.
+
+# COMPOUND_TEXT=text/plain;charset=x-compound-text;eoln="\n";terminators=0
+
+TEXT=text/plain;eoln="\n";terminators=0
+STRING=text/plain;charset=iso8859-1;eoln="\n";terminators=0
+FILE_NAME=application/x-java-file-list;class=java.util.List
+text/uri-list=application/x-java-file-list;class=java.util.List
+PNG=image/x-java-image;class=java.awt.Image
+JFIF=image/x-java-image;class=java.awt.Image
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/windows/classes/sun/datatransfer/resources/flavormap.properties	Tue Feb 17 11:44:51 2015 -0800
@@ -0,0 +1,69 @@
+#
+# This properties file is used to initialize the default
+# java.awt.datatransfer.SystemFlavorMap. It contains the Win32 platform-
+# specific, default mappings between common Win32 Clipboard atoms and platform-
+# independent MIME type strings, which will be converted into
+# java.awt.datatransfer.DataFlavors.
+#
+# The standard format is:
+#
+# <native>=<MIME type>,<MIME type>, ...
+#
+# <native> should be a string identifier that the native platform will
+# recognize as a valid data format. <MIME type> should specify both a MIME
+# primary type and a MIME subtype separated by a '/'. The MIME type may include
+# parameters, where each parameter is a key/value pair separated by '=', and
+# where each parameter to the MIME type is separated by a ';'.
+#
+# Because SystemFlavorMap implements FlavorTable, developers are free to
+# duplicate DataFlavor values and set multiple values for a single native by
+# separating them with ",". If a mapping contains a duplicate key or value,
+# earlier mappings which included this key or value will be preferred.#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", and which support the charset parameter, should specify the exact
+# format in which the native platform expects the data. The "charset"
+# parameter specifies the char to byte encoding, the "eoln" parameter
+# specifies the end-of-line marker, and the "terminators" parameter specifies
+# the number of terminating NUL bytes. Note that "eoln" and "terminators"
+# are not standardized MIME type parameters. They are specific to this file
+# format ONLY. They will not appear in any of the DataFlavors returned by the
+# SystemFlavorMap at the Java level.
+#
+# If the "charset" parameter is omitted, or has zero length, the platform
+# default encoding is assumed. If the "eoln" parameter is omitted, or has
+# zero length, "\n" is assumed. If the "terminators" parameter is omitted,
+# or has a value less than zero, zero is assumed.
+#
+# Upon initialization, the data transfer subsystem will record the specified
+# details of the native text format, but the default SystemFlavorMap will
+# present a large set of synthesized DataFlavors which map, in both
+# directions, to the native. After receiving data from the application in one
+# of the synthetic DataFlavors, the data transfer subsystem will transform
+# the data stream into the format specified in this file before passing the
+# transformed stream to the native system.
+#
+# Mappings whose values specify DataFlavors with primary MIME types of
+# "text", but which do not support the charset parameter, will be treated as
+# opaque, 8-bit data. They will not undergo any transformation process, and
+# any "charset", "eoln", or "terminators" parameters specified in this file
+# will be ignored.
+#
+# See java.awt.datatransfer.DataFlavor.selectBestTextFlavor for a list of
+# text flavors which support the charset parameter.
+
+UNICODE\ TEXT=text/plain;charset=utf-16le;eoln="\r\n";terminators=2
+TEXT=text/plain;eoln="\r\n";terminators=1
+HTML\ Format=text/html;charset=utf-8;eoln="\r\n";terminators=1
+Rich\ Text\ Format=text/rtf
+HDROP=application/x-java-file-list;class=java.util.List
+PNG=image/x-java-image;class=java.awt.Image
+JFIF=image/x-java-image;class=java.awt.Image
+DIB=image/x-java-image;class=java.awt.Image
+ENHMETAFILE=image/x-java-image;class=java.awt.Image
+METAFILEPICT=image/x-java-image;class=java.awt.Image
+LOCALE=application/x-java-text-encoding;class="[B"
+UniformResourceLocator=application/x-java-url;class=java.net.URL,\
+                       text/uri-list;eoln="\r\n";terminators=1,\
+                       text/plain;eoln="\r\n";terminators=1
+FileGroupDescriptorW=application/x-java-file-list;class=java.util.List
+FileGroupDescriptor=application/x-java-file-list;class=java.util.List
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaBorder.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaBorder.java	Tue Feb 17 11:44:51 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, 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
@@ -68,8 +68,9 @@
         painter.state.set(size);
     }
 
+    @Override
     public Insets getBorderInsets(final Component c) {
-        return sizeVariant.margins;
+        return (Insets) sizeVariant.margins.clone();
     }
 
     protected AquaBorder deriveBorderForSize(final Size size) {
@@ -130,8 +131,10 @@
         return (focusable != null && focusable instanceof JComponent && ((JComponent)focusable).hasFocus());
     }
 
+    @Override
     public boolean isBorderOpaque() { return false; }
 
+    @Override
     public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int w, final int h) {
         painter.paint(g, c, x, y, w, h);
     }
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxUI.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxUI.java	Tue Feb 17 11:44:51 2015 -0800
@@ -275,7 +275,7 @@
 
         actionMap.put("aquaSelectNext", highlightNextAction);
         actionMap.put("aquaSelectPrevious", highlightPreviousAction);
-        actionMap.put("aquaEnterPressed", triggerSelectionAction);
+        actionMap.put("enterPressed", triggerSelectionAction);
         actionMap.put("aquaSpacePressed", toggleSelectionAction);
 
         actionMap.put("aquaSelectHome", highlightFirstAction);
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileChooserUI.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaFileChooserUI.java	Tue Feb 17 11:44:51 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, 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
@@ -1098,8 +1098,15 @@
             super(f);
         }
 
-        public Component getTableCellRendererComponent(final JTable list, final Object value, final boolean isSelected, final boolean cellHasFocus, final int index, final int col) {
-            super.getTableCellRendererComponent(list, value, isSelected, false, index, col); // No focus border, thanks
+        public Component getTableCellRendererComponent(final JTable list,
+                                                       final Object value,
+                                                       final boolean isSelected,
+                                                       final boolean cellHasFocus,
+                                                       final int index,
+                                                       final int col) {
+            super.getTableCellRendererComponent(list, value, isSelected, false,
+                                                index,
+                                                col); // No focus border, thanks
             final File file = (File)value;
             final JFileChooser fc = getFileChooser();
             setText(fc.getName(file));
@@ -1115,8 +1122,14 @@
             super(f);
         }
 
-        public Component getTableCellRendererComponent(final JTable list, final Object value, final boolean isSelected, final boolean cellHasFocus, final int index, final int col) {
-            super.getTableCellRendererComponent(list, value, isSelected, false, index, col);
+        public Component getTableCellRendererComponent(final JTable list,
+                                                       final Object value,
+                                                       final boolean isSelected,
+                                                       final boolean cellHasFocus,
+                                                       final int index,
+                                                       final int col) {
+            super.getTableCellRendererComponent(list, value, isSelected, false,
+                                                index, col);
             final File file = (File)fFileList.getValueAt(index, 0);
             setEnabled(isSelectableInList(file));
             final DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.SHORT);
@@ -1132,14 +1145,17 @@
         }
     }
 
+    @Override
     public Dimension getPreferredSize(final JComponent c) {
-        return PREF_SIZE;
+        return new Dimension(PREF_WIDTH, PREF_HEIGHT);
     }
 
+    @Override
     public Dimension getMinimumSize(final JComponent c) {
-        return MIN_SIZE;
+        return new Dimension(MIN_WIDTH, MIN_HEIGHT);
     }
 
+    @Override
     public Dimension getMaximumSize(final JComponent c) {
         return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
     }
@@ -1819,12 +1835,8 @@
 
     private static final int PREF_WIDTH = 550;
     private static final int PREF_HEIGHT = 400;
-    private static final Dimension PREF_SIZE = new Dimension(PREF_WIDTH, PREF_HEIGHT);
-
     private static final int MIN_WIDTH = 400;
     private static final int MIN_HEIGHT = 250;
-    private static final Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT);
-
     private static final int LIST_MIN_WIDTH = 400;
     private static final int LIST_MIN_HEIGHT = 100;
     private static final Dimension LIST_MIN_SIZE = new Dimension(LIST_MIN_WIDTH, LIST_MIN_HEIGHT);
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaKeyBindings.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaKeyBindings.java	Tue Feb 17 11:44:51 2015 -0800
@@ -214,7 +214,7 @@
             "PAGE_DOWN", "aquaSelectPageDown",
             "HOME", "aquaSelectHome",
             "END", "aquaSelectEnd",
-            "ENTER", "aquaEnterPressed",
+            "ENTER", "enterPressed",
             "UP", "aquaSelectPrevious",
             "KP_UP", "aquaSelectPrevious",
             "DOWN", "aquaSelectNext",
--- a/jdk/src/java.desktop/macosx/classes/sun/datatransfer/resources/flavormap.properties	Tue Feb 17 10:48:24 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-#
-# This properties file is used to initialize the default
-# java.awt.datatransfer.SystemFlavorMap. It contains the Mac OS X platform-specific,
-# default mappings between common Mac OS X selection atoms and platform-independent
-# MIME type strings, which will be converted into 
-# java.awt.datatransfer.DataFlavors.
-#
-# The standard format is:
-#
-# <native>=<MIME type>,<MIME type>, ...
-#
-# <native> should be a string identifier that the native platform will
-# recognize as a valid data format. <MIME type> should specify both a MIME
-# primary type and a MIME subtype separated by a '/'. The MIME type may include
-# parameters, where each parameter is a key/value pair separated by '=', and
-# where each parameter to the MIME type is separated by a ';'.
-#
-# Because SystemFlavorMap implements FlavorTable, developers are free to
-# duplicate DataFlavor values and set multiple values for a single native by
-# separating them with ",". If a mapping contains a duplicate key or value,
-# earlier mappings which included this key or value will be preferred.
-#
-# Mappings whose values specify DataFlavors with primary MIME types of
-# "text", and which support the charset parameter, should specify the exact
-# format in which the native platform expects the data. The "charset"
-# parameter specifies the char to byte encoding, the "eoln" parameter
-# specifies the end-of-line marker, and the "terminators" parameter specifies
-# the number of terminating NUL bytes. Note that "eoln" and "terminators"
-# are not standardized MIME type parameters. They are specific to this file
-# format ONLY. They will not appear in any of the DataFlavors returned by the
-# SystemFlavorMap at the Java level.
-#
-# If the "charset" parameter is omitted, or has zero length, the platform
-# default encoding is assumed. If the "eoln" parameter is omitted, or has
-# zero length, "\n" is assumed. If the "terminators" parameter is omitted,
-# or has a value less than zero, zero is assumed.
-#
-# Upon initialization, the data transfer subsystem will record the specified
-# details of the native text format, but the default SystemFlavorMap will
-# present a large set of synthesized DataFlavors which map, in both
-# directions, to the native. After receiving data from the application in one
-# of the synthetic DataFlavors, the data transfer subsystem will transform
-# the data stream into the format specified in this file before passing the
-# transformed stream to the native system.
-#
-# Mappings whose values specify DataFlavors with primary MIME types of
-# "text", but which do not support the charset parameter, will be treated as
-# opaque, 8-bit data. They will not undergo any transformation process, and
-# any "charset", "eoln", or "terminators" parameters specified in this file
-# will be ignored.
-#
-# See java.awt.datatransfer.DataFlavor.selectBestTextFlavor for a list of
-# text flavors which support the charset parameter.
-
-UTF8_STRING=text/plain;charset=UTF-8;eoln="\n";terminators=0
-
-# The COMPOUND_TEXT support for inter-client text transfer is disabled by 
-# default. The reason is that many native applications prefer this format over 
-# other native text formats, but are unable to decode the textual data in this 
-# format properly. This results in java-to-native text transfer failures.
-# To enable the COMPOUND_TEXT support for this JRE installation uncomment 
-# the line below.
-
-# COMPOUND_TEXT=text/plain;charset=x-compound-text;eoln="\n";terminators=0
-
-TEXT=text/plain;eoln="\n";terminators=0
-STRING=text/plain;charset=UTF-8;eoln="\n";terminators=0
-FILE_NAME=application/x-java-file-list;class=java.util.List
-text/uri-list=application/x-java-file-list;class=java.util.List
-PNG=image/x-java-image;class=java.awt.Image
-JFIF=image/x-java-image;class=java.awt.Image
-TIFF=image/x-java-image;class=java.awt.Image
-RICH_TEXT=text/rtf
-HTML=text/html;charset=utf-8;eoln="\r\n";terminators=1
-URL=application/x-java-url;class=java.net.URL,\
-    text/uri-list;eoln="\r\n";terminators=1
--- a/jdk/src/java.desktop/macosx/classes/sun/font/CFont.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/macosx/classes/sun/font/CFont.java	Tue Feb 17 11:44:51 2015 -0800
@@ -77,14 +77,72 @@
     }
 
     private static native long createNativeFont(final String nativeFontName,
-                                                final int style,
-                                                final boolean isFakeItalic);
+                                                final int style);
     private static native void disposeNativeFont(final long nativeFontPtr);
 
     private boolean isFakeItalic;
     private String nativeFontName;
     private long nativeFontPtr;
 
+    private native float getWidthNative(final long nativeFontPtr);
+    private native float getWeightNative(final long nativeFontPtr);
+
+    private int fontWidth = -1;
+    private int fontWeight = -1;
+
+    @Override
+    public int getWidth() {
+        if (fontWidth == -1) {
+            // Apple use a range of -1 -> +1, where 0.0 is normal
+            // OpenType uses a % range from 50% -> 200% where 100% is normal
+            // and maps these onto the integer values 1->9.
+            // Since that is what Font2D.getWidth() expects, remap to that.
+            float fw = getWidthNative(getNativeFontPtr());
+            if (fw == 0.0) { // short cut the common case
+                fontWidth = Font2D.FWIDTH_NORMAL;
+                return fontWidth;
+            }
+            fw += 1.0; fw *= 100.0;
+            if (fw <= 50.0) {
+                fontWidth = 1;
+            } else if (fw <= 62.5) {
+                fontWidth = 2;
+            } else if (fw <= 75.0) {
+                fontWidth = 3;
+            } else if (fw <= 87.5) {
+                fontWidth = 4;
+            } else if (fw <= 100.0) {
+                fontWidth = 5;
+            } else if (fw <= 112.5) {
+                fontWidth = 6;
+            } else if (fw <= 125.0) {
+                fontWidth = 7;
+            } else if (fw <= 150.0) {
+                fontWidth = 8;
+            } else {
+                fontWidth = 9;
+            }
+        }
+        return fontWidth;
+   }
+
+    @Override
+    public int getWeight() {
+        if (fontWeight == -1) {
+            // Apple use a range of -1 -> +1, where 0 is medium/regular
+            // Map this on to the OpenType range of 100->900 where
+            // 500 is medium/regular.
+            // We'll actually map to 0->1000 but that's close enough.
+            float fw = getWeightNative(getNativeFontPtr());
+            if (fw == 0) {
+               return Font2D.FWEIGHT_NORMAL;
+            }
+            fw += 1.0; fw *= 500;
+            fontWeight = (int)fw;
+          }
+          return fontWeight;
+    }
+
     // this constructor is called from CFontWrapper.m
     public CFont(String name) {
         this(name, name);
@@ -94,10 +152,11 @@
         handle = new Font2DHandle(this);
         fullName = name;
         familyName = inFamilyName;
-        nativeFontName = inFamilyName;
+        nativeFontName = fullName;
         setStyle();
     }
 
+    /* Called from CFontManager too */
     public CFont(CFont other, String logicalFamilyName) {
         handle = new Font2DHandle(this);
         fullName = logicalFamilyName;
@@ -109,6 +168,7 @@
 
     public CFont createItalicVariant() {
         CFont font = new CFont(this, familyName);
+        font.nativeFontName = fullName;
         font.fullName =
             fullName + (style == Font.BOLD ? "" : "-") + "Italic-Derived";
         font.style |= Font.ITALIC;
@@ -118,7 +178,7 @@
 
     protected synchronized long getNativeFontPtr() {
         if (nativeFontPtr == 0L) {
-            nativeFontPtr = createNativeFont(nativeFontName, style, isFakeItalic);
+            nativeFontPtr = createNativeFont(nativeFontName, style);
 }
         return nativeFontPtr;
     }
--- a/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/macosx/classes/sun/font/CFontManager.java	Tue Feb 17 11:44:51 2015 -0800
@@ -252,13 +252,42 @@
         final CFont font = new CFont(fontName, fontFamilyName);
 
         registerGenericFont(font);
+    }
 
-        if ((font.getStyle() & Font.ITALIC) == 0) {
-            registerGenericFont(font.createItalicVariant(), true);
+    void registerItalicDerived() {
+        FontFamily[] famArr = FontFamily.getAllFontFamilies();
+        for (int i=0; i<famArr.length; i++) {
+            FontFamily family = famArr[i];
+
+            Font2D f2dPlain = family.getFont(Font.PLAIN);
+            if (f2dPlain != null && !(f2dPlain instanceof CFont)) continue;
+            Font2D f2dBold = family.getFont(Font.BOLD);
+            if (f2dBold != null && !(f2dBold instanceof CFont)) continue;
+            Font2D f2dItalic = family.getFont(Font.ITALIC);
+            if (f2dItalic != null && !(f2dItalic instanceof CFont)) continue;
+            Font2D f2dBoldItalic = family.getFont(Font.BOLD|Font.ITALIC);
+            if (f2dBoldItalic != null && !(f2dBoldItalic instanceof CFont)) continue;
+
+            CFont plain = (CFont)f2dPlain;
+            CFont bold = (CFont)f2dBold;
+            CFont italic = (CFont)f2dItalic;
+            CFont boldItalic = (CFont)f2dBoldItalic;
+
+            if (bold == null) bold = plain;
+            if (plain == null && bold == null) continue;
+            if (italic != null && boldItalic != null) continue;
+            if (plain != null && italic == null) {
+               registerGenericFont(plain.createItalicVariant(), true);
+            }
+            if (bold != null && boldItalic == null) {
+               registerGenericFont(bold.createItalicVariant(), true);
+            }
         }
     }
 
     Object waitForFontsToBeLoaded  = new Object();
+    private boolean loadedAllFonts = false;
+
     public void loadFonts()
     {
         synchronized(waitForFontsToBeLoaded)
@@ -267,7 +296,11 @@
             java.security.AccessController.doPrivileged(
                 new java.security.PrivilegedAction<Object>() {
                     public Object run() {
-                        loadNativeFonts();
+                        if (!loadedAllFonts) {
+                           loadNativeFonts();
+                           registerItalicDerived();
+                           loadedAllFonts = true;
+                        }
                         return null;
                     }
                 }
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/AWTView.m	Tue Feb 17 11:44:51 2015 -0800
@@ -890,9 +890,9 @@
     // text, or 'text in progress'.  We also need to send the event if we get an insert text out of the blue!
     // (i.e., when the user uses the Character palette or Inkwell), or when the string to insert is a complex
     // Unicode value.
-    NSUInteger utf8Length = [aString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+    NSUInteger utf16Length = [aString lengthOfBytesUsingEncoding:NSUTF16StringEncoding];
 
-    if ([self hasMarkedText] || !fProcessingKeystroke || (utf8Length > 1)) {
+    if ([self hasMarkedText] || !fProcessingKeystroke || (utf16Length > 2)) {
         JNIEnv *env = [ThreadUtilities getJNIEnv];
 
         static JNF_MEMBER_CACHE(jm_selectPreviousGlyph, jc_CInputMethod, "selectPreviousGlyph", "()V");
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/font/AWTFont.m	Tue Feb 17 11:44:51 2015 -0800
@@ -35,15 +35,11 @@
 #import "AWTStrike.h"
 #import "CoreTextSupport.h"
 
-
-#define DEBUG
-
 @implementation AWTFont
 
-- (id) initWithFont:(NSFont *)font isFakeItalic:(BOOL)isFakeItalic {
+- (id) initWithFont:(NSFont *)font {
     self = [super init];
     if (self) {
-        fIsFakeItalic = isFakeItalic;
         fFont = [font retain];
         fNativeCGFont = CTFontCopyGraphicsFont((CTFontRef)font, NULL);
     }
@@ -72,7 +68,6 @@
 
 + (AWTFont *) awtFontForName:(NSString *)name
                        style:(int)style
-                isFakeItalic:(BOOL)isFakeItalic
 {
     // create font with family & size
     NSFont *nsFont = [NSFont fontWithName:name size:1.0];
@@ -95,7 +90,7 @@
         nsFont = [[NSFontManager sharedFontManager] convertFont:nsFont toHaveTrait:NSBoldFontMask];
     }
 
-    return [[[AWTFont alloc] initWithFont:nsFont isFakeItalic:isFakeItalic] autorelease];
+    return [[[AWTFont alloc] initWithFont:nsFont] autorelease];
 }
 
 + (NSFont *) nsFontForJavaFont:(jobject)javaFont env:(JNIEnv *)env {
@@ -354,7 +349,7 @@
 JNIEXPORT jlong JNICALL
 Java_sun_font_CFont_createNativeFont
     (JNIEnv *env, jclass clazz,
-     jstring nativeFontName, jint style, jboolean isFakeItalic)
+     jstring nativeFontName, jint style)
 {
     AWTFont *awtFont = nil;
 
@@ -362,8 +357,7 @@
 
     awtFont =
         [AWTFont awtFontForName:JNFJavaToNSString(env, nativeFontName)
-         style:style
-         isFakeItalic:isFakeItalic]; // autoreleased
+         style:style]; // autoreleased
 
     if (awtFont) {
         CFRetain(awtFont); // GC
@@ -376,6 +370,52 @@
 
 /*
  * Class:     sun_font_CFont
+ * Method:    getWidthNative
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL
+Java_sun_font_CFont_getWidthNative
+    (JNIEnv *env, jobject cfont, jlong awtFontPtr)
+{
+    float widthVal;
+JNF_COCOA_ENTER(env);
+
+    AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
+    NSFont* nsFont = awtFont->fFont;
+    NSFontDescriptor *fontDescriptor = nsFont.fontDescriptor;
+    NSDictionary *fontTraits = [fontDescriptor objectForKey : NSFontTraitsAttribute];
+    NSNumber *width = [fontTraits objectForKey : NSFontWidthTrait];
+    widthVal = (float)[width floatValue];
+
+JNF_COCOA_EXIT(env);
+   return (jfloat)widthVal;
+}
+
+/*
+ * Class:     sun_font_CFont
+ * Method:    getWeightNative
+ * Signature: (J)F
+ */
+JNIEXPORT jfloat JNICALL
+Java_sun_font_CFont_getWeightNative
+    (JNIEnv *env, jobject cfont, jlong awtFontPtr)
+{
+    float weightVal;
+JNF_COCOA_ENTER(env);
+
+    AWTFont *awtFont = (AWTFont *)jlong_to_ptr(awtFontPtr);
+    NSFont* nsFont = awtFont->fFont;
+    NSFontDescriptor *fontDescriptor = nsFont.fontDescriptor;
+    NSDictionary *fontTraits = [fontDescriptor objectForKey : NSFontTraitsAttribute];
+    NSNumber *weight = [fontTraits objectForKey : NSFontWeightTrait];
+    weightVal = (float)[weight floatValue];
+
+JNF_COCOA_EXIT(env);
+   return (jfloat)weightVal;
+}
+
+/*
+ * Class:     sun_font_CFont
  * Method:    disposeNativeFont
  * Signature: (J)V
  */
--- a/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java	Tue Feb 17 11:44:51 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,8 +43,6 @@
 
 import java.awt.image.Raster;
 import java.awt.image.WritableRaster;
-import java.awt.image.SampleModel;
-import java.awt.image.DataBuffer;
 import java.awt.image.DataBufferByte;
 import java.awt.image.ColorModel;
 import java.awt.image.IndexColorModel;
@@ -1048,7 +1046,13 @@
 
         // Call the writer, who will call back for every scanline
 
-        processImageStarted(currentImage);
+        clearAbortRequest();
+        cbLock.lock();
+        try {
+            processImageStarted(currentImage);
+        } finally {
+            cbLock.unlock();
+        }
 
         boolean aborted = false;
 
@@ -1225,6 +1229,23 @@
         }
     }
 
+    @Override
+    protected synchronized void clearAbortRequest() {
+        setThreadLock();
+        try {
+            cbLock.check();
+            if (abortRequested()) {
+                super.clearAbortRequest();
+                // reset C structures
+                resetWriter(structPointer);
+                // reset the native destination
+                setDest(structPointer);
+            }
+        } finally {
+            clearThreadLock();
+        }
+    }
+
     private void resetInternalState() {
         // reset C structures
         resetWriter(structPointer);
@@ -1652,7 +1673,7 @@
         int vsamp0 = specs[0].VsamplingFactor;
         for (int i = 1; i < specs.length; i++) {
             if ((specs[i].HsamplingFactor != hsamp0) ||
-                (specs[i].HsamplingFactor != hsamp0))
+                (specs[i].VsamplingFactor != vsamp0))
                 return true;
         }
         return false;
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKFileChooserUI.java	Tue Feb 17 11:44:51 2015 -0800
@@ -100,7 +100,8 @@
     private static Dimension prefListSize = new Dimension(75, 150);
 
     private static Dimension PREF_SIZE = new Dimension(435, 360);
-    private static Dimension MIN_SIZE = new Dimension(200, 300);
+    private static final int MIN_WIDTH = 200;
+    private static final int MIN_HEIGHT = 300;
 
     private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);
 
@@ -1052,6 +1053,7 @@
         }
     }
 
+    @Override
     public Dimension getPreferredSize(JComponent c) {
         Dimension prefSize = new Dimension(PREF_SIZE);
         JComponent accessory = getFileChooser().getAccessory();
@@ -1067,10 +1069,12 @@
         }
     }
 
-    public Dimension getMinimumSize(JComponent x)  {
-        return new Dimension(MIN_SIZE);
+    @Override
+    public Dimension getMinimumSize(JComponent x) {
+        return new Dimension(MIN_WIDTH, MIN_HEIGHT);
     }
 
+    @Override
     public Dimension getMaximumSize(JComponent x) {
         return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
     }
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java	Tue Feb 17 11:44:51 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,8 +65,8 @@
 
     private static Dimension WITH_ACCELERATOR_PREF_SIZE = new Dimension(650, 450);
     private static Dimension PREF_SIZE = new Dimension(350, 450);
-    private static Dimension MIN_SIZE = new Dimension(200, 300);
-
+    private static final int MIN_WIDTH = 200;
+    private static final int MIN_HEIGHT = 300;
     private static Dimension PREF_ACC_SIZE = new Dimension(10, 10);
     private static Dimension ZERO_ACC_SIZE = new Dimension(1, 1);
 
@@ -628,6 +628,7 @@
         return scrollpane;
     }
 
+    @Override
     public Dimension getPreferredSize(JComponent c) {
         Dimension prefSize =
             (getFileChooser().getAccessory() != null) ? WITH_ACCELERATOR_PREF_SIZE : PREF_SIZE;
@@ -640,10 +641,12 @@
         }
     }
 
-    public Dimension getMinimumSize(JComponent x)  {
-        return MIN_SIZE;
+    @Override
+    public Dimension getMinimumSize(JComponent x) {
+        return new Dimension(MIN_WIDTH, MIN_HEIGHT);
     }
 
+    @Override
     public Dimension getMaximumSize(JComponent x) {
         return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
     }
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java	Tue Feb 17 11:44:51 2015 -0800
@@ -93,7 +93,6 @@
 
     private static int MIN_WIDTH = 425;
     private static int MIN_HEIGHT = 245;
-    private static Dimension MIN_SIZE = new Dimension(MIN_WIDTH, MIN_HEIGHT);
 
     private static int LIST_PREF_WIDTH = 444;
     private static int LIST_PREF_HEIGHT = 138;
@@ -642,6 +641,7 @@
      * @return   a <code>Dimension</code> specifying the preferred
      *           width and height of the file chooser
      */
+    @Override
     public Dimension getPreferredSize(JComponent c) {
         int prefWidth = PREF_SIZE.width;
         Dimension d = c.getLayout().preferredLayoutSize(c);
@@ -660,8 +660,9 @@
      * @return   a <code>Dimension</code> specifying the minimum
      *           width and height of the file chooser
      */
+    @Override
     public Dimension getMinimumSize(JComponent c) {
-        return MIN_SIZE;
+        return new Dimension(MIN_WIDTH, MIN_HEIGHT);
     }
 
     /**
@@ -671,6 +672,7 @@
      * @return   a <code>Dimension</code> specifying the maximum
      *           width and height of the file chooser
      */
+    @Override
     public Dimension getMaximumSize(JComponent c) {
         return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
     }
--- a/jdk/src/java.desktop/share/classes/java/awt/Component.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/java/awt/Component.java	Tue Feb 17 11:44:51 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, 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
@@ -1690,15 +1690,6 @@
         /* do nothing */
     }
 
-    /*
-     * Delete references from LightweightDispatcher of a heavyweight parent
-     */
-    void clearLightweightDispatcherOnRemove(Component removedComponent) {
-        if (parent != null) {
-            parent.clearLightweightDispatcherOnRemove(removedComponent);
-        }
-    }
-
     /**
      * @deprecated As of JDK version 1.1,
      * replaced by <code>setVisible(boolean)</code>.
@@ -6242,7 +6233,7 @@
     /**
      * Indicates whether a class or its superclasses override coalesceEvents.
      * Must be called with lock on coalesceMap and privileged.
-     * @see checkCoalsecing
+     * @see checkCoalescing
      */
     private static boolean isCoalesceEventsOverriden(Class<?> clazz) {
         assert Thread.holdsLock(coalesceMap);
@@ -7083,8 +7074,6 @@
         }
 
         synchronized (getTreeLock()) {
-            clearLightweightDispatcherOnRemove(this);
-
             if (isFocusOwner() && KeyboardFocusManager.isAutoFocusTransferEnabledFor(this)) {
                 transferFocus(true);
             }
--- a/jdk/src/java.desktop/share/classes/java/awt/Container.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/java/awt/Container.java	Tue Feb 17 11:44:51 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,7 @@
 import java.io.PrintStream;
 import java.io.PrintWriter;
 
+import java.lang.ref.WeakReference;
 import java.security.AccessController;
 
 import java.util.EventListener;
@@ -3321,16 +3322,6 @@
         }
     }
 
-    @Override
-    void clearLightweightDispatcherOnRemove(Component removedComponent) {
-        if (dispatcher != null) {
-            dispatcher.removeReferences(removedComponent);
-        } else {
-            //It is a Lightweight Container, should clear parent`s Dispatcher
-            super.clearLightweightDispatcherOnRemove(removedComponent);
-        }
-    }
-
     final Container getTraversalRoot() {
         if (isFocusCycleRoot()) {
             return findTraversalRoot();
@@ -4431,7 +4422,9 @@
 
     LightweightDispatcher(Container nativeContainer) {
         this.nativeContainer = nativeContainer;
-        mouseEventTarget = null;
+        mouseEventTarget = new WeakReference<>(null);
+        targetLastEntered = new WeakReference<>(null);
+        targetLastEnteredDT = new WeakReference<>(null);
         eventMask = 0;
     }
 
@@ -4442,9 +4435,9 @@
     void dispose() {
         //System.out.println("Disposing lw dispatcher");
         stopListeningForOtherDrags();
-        mouseEventTarget = null;
-        targetLastEntered = null;
-        targetLastEnteredDT = null;
+        mouseEventTarget.clear();
+        targetLastEntered.clear();
+        targetLastEnteredDT.clear();
     }
 
     /**
@@ -4531,65 +4524,62 @@
 
         trackMouseEnterExit(mouseOver, e);
 
-    // 4508327 : MOUSE_CLICKED should only go to the recipient of
-    // the accompanying MOUSE_PRESSED, so don't reset mouseEventTarget on a
-    // MOUSE_CLICKED.
-    if (!isMouseGrab(e) && id != MouseEvent.MOUSE_CLICKED) {
-            mouseEventTarget = (mouseOver != nativeContainer) ? mouseOver: null;
-            isCleaned = false;
+        Component met = mouseEventTarget.get();
+        // 4508327 : MOUSE_CLICKED should only go to the recipient of
+        // the accompanying MOUSE_PRESSED, so don't reset mouseEventTarget on a
+        // MOUSE_CLICKED.
+        if (!isMouseGrab(e) && id != MouseEvent.MOUSE_CLICKED) {
+            met = (mouseOver != nativeContainer) ? mouseOver : null;
+            mouseEventTarget = new WeakReference<>(met);
         }
 
-        if (mouseEventTarget != null) {
+        if (met != null) {
             switch (id) {
-            case MouseEvent.MOUSE_ENTERED:
-            case MouseEvent.MOUSE_EXITED:
-                break;
-            case MouseEvent.MOUSE_PRESSED:
-                retargetMouseEvent(mouseEventTarget, id, e);
-                break;
-        case MouseEvent.MOUSE_RELEASED:
-            retargetMouseEvent(mouseEventTarget, id, e);
-        break;
-        case MouseEvent.MOUSE_CLICKED:
-        // 4508327: MOUSE_CLICKED should never be dispatched to a Component
-        // other than that which received the MOUSE_PRESSED event.  If the
-        // mouse is now over a different Component, don't dispatch the event.
-        // The previous fix for a similar problem was associated with bug
-        // 4155217.
-        if (mouseOver == mouseEventTarget) {
-            retargetMouseEvent(mouseOver, id, e);
-        }
-        break;
-            case MouseEvent.MOUSE_MOVED:
-                retargetMouseEvent(mouseEventTarget, id, e);
-                break;
-        case MouseEvent.MOUSE_DRAGGED:
-            if (isMouseGrab(e)) {
-                retargetMouseEvent(mouseEventTarget, id, e);
-            }
-                break;
-        case MouseEvent.MOUSE_WHEEL:
-            // This may send it somewhere that doesn't have MouseWheelEvents
-            // enabled.  In this case, Component.dispatchEventImpl() will
-            // retarget the event to a parent that DOES have the events enabled.
-            if (eventLog.isLoggable(PlatformLogger.Level.FINEST) && (mouseOver != null)) {
-                eventLog.finest("retargeting mouse wheel to " +
+                case MouseEvent.MOUSE_ENTERED:
+                case MouseEvent.MOUSE_EXITED:
+                    break;
+                case MouseEvent.MOUSE_PRESSED:
+                    retargetMouseEvent(met, id, e);
+                    break;
+                case MouseEvent.MOUSE_RELEASED:
+                    retargetMouseEvent(met, id, e);
+                    break;
+                case MouseEvent.MOUSE_CLICKED:
+                    // 4508327: MOUSE_CLICKED should never be dispatched to a Component
+                    // other than that which received the MOUSE_PRESSED event.  If the
+                    // mouse is now over a different Component, don't dispatch the event.
+                    // The previous fix for a similar problem was associated with bug
+                    // 4155217.
+                    if (mouseOver == met) {
+                        retargetMouseEvent(mouseOver, id, e);
+                    }
+                    break;
+                case MouseEvent.MOUSE_MOVED:
+                    retargetMouseEvent(met, id, e);
+                    break;
+                case MouseEvent.MOUSE_DRAGGED:
+                    if (isMouseGrab(e)) {
+                        retargetMouseEvent(met, id, e);
+                    }
+                    break;
+                case MouseEvent.MOUSE_WHEEL:
+                    // This may send it somewhere that doesn't have MouseWheelEvents
+                    // enabled.  In this case, Component.dispatchEventImpl() will
+                    // retarget the event to a parent that DOES have the events enabled.
+                    if (eventLog.isLoggable(PlatformLogger.Level.FINEST) && (mouseOver != null)) {
+                        eventLog.finest("retargeting mouse wheel to " +
                                 mouseOver.getName() + ", " +
                                 mouseOver.getClass());
+                    }
+                    retargetMouseEvent(mouseOver, id, e);
+                    break;
             }
-            retargetMouseEvent(mouseOver, id, e);
-        break;
+            //Consuming of wheel events is implemented in "retargetMouseEvent".
+            if (id != MouseEvent.MOUSE_WHEEL) {
+                e.consume();
             }
-        //Consuming of wheel events is implemented in "retargetMouseEvent".
-        if (id != MouseEvent.MOUSE_WHEEL) {
-            e.consume();
         }
-    } else if (isCleaned && id != MouseEvent.MOUSE_WHEEL) {
-        //After mouseEventTarget was removed and cleaned should consume all events
-        //until new mouseEventTarget is found
-        e.consume();
-    }
-    return e.isConsumed();
+        return e.isConsumed();
     }
 
     private boolean processDropTargetEvent(SunDropTargetEvent e) {
@@ -4646,15 +4636,16 @@
             // drag has an associated drop target. MOUSE_ENTERED comes when the
             // mouse is in the native container already. To propagate this event
             // properly we should null out targetLastEntered.
-            targetLastEnteredDT = null;
+            targetLastEnteredDT.clear();
         } else if (id == MouseEvent.MOUSE_ENTERED) {
             isMouseDTInNativeContainer = true;
         } else if (id == MouseEvent.MOUSE_EXITED) {
             isMouseDTInNativeContainer = false;
         }
-        targetLastEnteredDT = retargetMouseEnterExit(targetOver, e,
-                                                     targetLastEnteredDT,
+        Component tle = retargetMouseEnterExit(targetOver, e,
+                                                     targetLastEnteredDT.get(),
                                                      isMouseDTInNativeContainer);
+        targetLastEnteredDT = new WeakReference<>(tle);
     }
 
     /*
@@ -4680,9 +4671,10 @@
             isMouseInNativeContainer = false;
             stopListeningForOtherDrags();
         }
-        targetLastEntered = retargetMouseEnterExit(targetOver, e,
-                                                   targetLastEntered,
+        Component tle = retargetMouseEnterExit(targetOver, e,
+                                                   targetLastEntered.get(),
                                                    isMouseInNativeContainer);
+        targetLastEntered = new WeakReference<>(tle);
     }
 
     private Component retargetMouseEnterExit(Component targetOver, MouseEvent e,
@@ -4944,22 +4936,17 @@
      * is null, there are currently no events being forwarded to
      * a subcomponent.
      */
-    private transient Component mouseEventTarget;
+    private transient WeakReference<Component> mouseEventTarget;
 
     /**
      * The last component entered by the {@code MouseEvent}.
      */
-    private transient Component targetLastEntered;
+    private transient  WeakReference<Component> targetLastEntered;
 
     /**
      * The last component entered by the {@code SunDropTargetEvent}.
      */
-    private transient Component targetLastEnteredDT;
-
-    /**
-     * Indicates whether {@code mouseEventTarget} was removed and nulled
-     */
-    private transient boolean isCleaned;
+    private transient  WeakReference<Component> targetLastEnteredDT;
 
     /**
      * Is the mouse over the native container.
@@ -5000,17 +4987,4 @@
         AWTEvent.MOUSE_EVENT_MASK |
         AWTEvent.MOUSE_MOTION_EVENT_MASK |
         AWTEvent.MOUSE_WHEEL_EVENT_MASK;
-
-    void removeReferences(Component removedComponent) {
-        if (mouseEventTarget == removedComponent) {
-            isCleaned = true;
-            mouseEventTarget = null;
-        }
-        if (targetLastEntered == removedComponent) {
-            targetLastEntered = null;
-        }
-        if (targetLastEnteredDT == removedComponent) {
-            targetLastEnteredDT = null;
-        }
-    }
 }
--- a/jdk/src/java.desktop/share/classes/java/awt/EventQueue.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/java/awt/EventQueue.java	Tue Feb 17 11:44:51 2015 -0800
@@ -182,7 +182,14 @@
 
     private FwDispatcher fwDispatcher;
 
-    private static final PlatformLogger eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue");
+    private static volatile PlatformLogger eventLog;
+
+    private static final PlatformLogger getEventLog() {
+        if(eventLog == null) {
+            eventLog = PlatformLogger.getLogger("java.awt.event.EventQueue");
+        }
+        return eventLog;
+    }
 
     static {
         AWTAccessor.setEventQueueAccessor(
@@ -762,8 +769,8 @@
                 dispatchThread.stopDispatching();
             }
         } else {
-            if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
-                eventLog.fine("Unable to dispatch event: " + event);
+            if (getEventLog().isLoggable(PlatformLogger.Level.FINE)) {
+                getEventLog().fine("Unable to dispatch event: " + event);
             }
         }
     }
@@ -860,8 +867,8 @@
      * @since           1.2
      */
     public void push(EventQueue newEventQueue) {
-        if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
-            eventLog.fine("EventQueue.push(" + newEventQueue + ")");
+        if (getEventLog().isLoggable(PlatformLogger.Level.FINE)) {
+            getEventLog().fine("EventQueue.push(" + newEventQueue + ")");
         }
 
         pushPopLock.lock();
@@ -886,8 +893,8 @@
                     // Use getNextEventPrivate() as it doesn't call flushPendingEvents()
                     newEventQueue.postEventPrivate(topQueue.getNextEventPrivate());
                 } catch (InterruptedException ie) {
-                    if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
-                        eventLog.fine("Interrupted push", ie);
+                    if (getEventLog().isLoggable(PlatformLogger.Level.FINE)) {
+                        getEventLog().fine("Interrupted push", ie);
                     }
                 }
             }
@@ -925,8 +932,8 @@
      * @since           1.2
      */
     protected void pop() throws EmptyStackException {
-        if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
-            eventLog.fine("EventQueue.pop(" + this + ")");
+        if (getEventLog().isLoggable(PlatformLogger.Level.FINE)) {
+            getEventLog().fine("EventQueue.pop(" + this + ")");
         }
 
         pushPopLock.lock();
@@ -948,8 +955,8 @@
                 try {
                     prevQueue.postEventPrivate(topQueue.getNextEventPrivate());
                 } catch (InterruptedException ie) {
-                    if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
-                        eventLog.fine("Interrupted pop", ie);
+                    if (getEventLog().isLoggable(PlatformLogger.Level.FINE)) {
+                        getEventLog().fine("Interrupted pop", ie);
                     }
                 }
             }
--- a/jdk/src/java.desktop/share/classes/java/awt/MenuBar.java	Tue Feb 17 10:48:24 2015 -0800
+++ b/jdk/src/java.desktop/share/classes/java/awt/MenuBar.java	Tue Feb 17 11:44:51 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2015, 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
@@ -181,7 +181,7 @@
      * removed from the menu bar, and replaced with the specified menu.
      * @param m    the menu to be set as the help menu
      */
-    public void setHelpMenu(Menu m) {
+    public void setHelpMenu(final Menu m) {
         synchronized (getTreeLock()) {
             if (helpMenu == m) {
                 return;
@@ -189,11 +189,11 @@
             if (helpMenu != null) {
                 remove(helpMenu);
             }
-            if (m.parent != this) {
-                add(m);
-            }
             helpMenu = m;
             if (m != null) {
+                if (m.parent != this) {
+                    add(m);
+                }
                 m.isHelpMenu = true;
                 m.parent = this;
                 MenuBarPeer peer = (MenuBarPeer)this.peer;
@@ -242,7 +242,7 @@
      * @param        index   the position of the menu to be removed.
      * @see          java.awt.MenuBar#add(java.awt.Menu)
      */
-    public void remove(int index) {
+    public void remove(final int index) {
         synchronized (getTreeLock()) {
             Menu m = getMenu(index);
             menus.removeElementAt(index);
@@ -252,6 +252,10 @@
                 m.parent = null;
                 peer.delMenu(index);
             }
+            if (helpMenu == m) {
+                helpMenu = null;
+                m.isHelpMenu = false;
+            }
         }
     }
 
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/Clipboard.java	Tue Feb 17 10:48:24 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,352 +0,0 @@
-/*
- * Copyright (c) 1996, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.awt.datatransfer;
-
-import sun.datatransfer.DataFlavorUtil;
-
-import java.util.Objects;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Arrays;
-
-import java.io.IOException;
-
-/**
- * A class that implements a mechanism to transfer data using
- * cut/copy/paste operations.
- * <p>
- * {@link FlavorListener}s may be registered on an instance of the
- * Clipboard class to be notified about changes to the set of
- * {@link DataFlavor}s available on this clipboard (see
- * {@link #addFlavorListener}).
- *
- * @see java.awt.Toolkit#getSystemClipboard
- * @see java.awt.Toolkit#getSystemSelection
- *
- * @author      Amy Fowler
- * @author      Alexander Gerasimov
- */
-public class Clipboard {
-
-    String name;
-
-    /**
-     * The owner of the clipboard.
-     */
-    protected ClipboardOwner owner;
-    /**
-     * Contents of the clipboard.
-     */
-    protected Transferable contents;
-
-    /**
-     * An aggregate of flavor listeners registered on this local clipboard.
-     *
-     * @since 1.5
-     */
-    private Set<FlavorListener> flavorListeners;
-
-    /**
-     * A set of <code>DataFlavor</code>s that is available on
-     * this local clipboard. It is used for tracking changes
-     * of <code>DataFlavor</code>s available on this clipboard.
-     *
-     * @since 1.5
-     */
-    private Set<DataFlavor> currentDataFlavors;
-
-    /**
-     * Creates a clipboard object.
-     * @param name for the clipboard
-     * @see java.awt.Toolkit#getSystemClipboard
-     */
-    public Clipboard(String name) {
-        this.name = name;
-    }
-
-    /**
-     * Returns the name of this clipboard object.
-     * @return the name of this clipboard object
-     *
-     * @see java.awt.Toolkit#getSystemClipboard
-     */
-    public String getName() {
-        return name;
-    }
-
-    /**
-     * Sets the current contents of the clipboard to the specified
-     * transferable object and registers the specified clipboard owner
-     * as the owner of the new contents.
-     * <p>
-     * If there is an existing owner different from the argument
-     * <code>owner</code>, that owner is notified that it no longer
-     * holds ownership of the clipboard contents via an invocation
-     * of <code>ClipboardOwner.lostOwnership()</code> on that owner.
-     * An implementation of <code>setContents()</code> is free not
-     * to invoke <code>lostOwnership()</code> directly from this method.
-     * For example, <code>lostOwnership()</code> may be invoked later on
-     * a different thread. The same applies to <code>FlavorListener</code>s
-     * registered on this clipboard.
-     * <p>
-     * The method throws <code>IllegalStateException</code> if the clipboard
-     * is currently unavailable. For example, on some platforms, the system
-     * clipboard is unavailable while it is accessed by another application.
-     *
-     * @param contents the transferable object representing the
-     *                 clipboard content
-     * @param owner the object which owns the clipboard content
-     * @throws IllegalStateException if the clipboard is currently unavailable
-     * @see java.awt.Toolkit#getSystemClipboard
-     */
-    public synchronized void setContents(Transferable contents, ClipboardOwner owner) {
-        final ClipboardOwner oldOwner = this.owner;
-        final Transferable oldContents = this.contents;
-
-        this.owner = owner;
-        this.contents = contents;
-
-        if (oldOwner != null && oldOwner != owner) {
-            DataFlavorUtil.getDesktopService().invokeOnEventThread(() ->
-                    oldOwner.lostOwnership(Clipboard.this, oldContents));
-        }
-        fireFlavorsChanged();
-    }
-
-    /**
-     * Returns a transferable object representing the current contents
-     * of the clipboard.  If the clipboard currently has no contents,
-     * it returns <code>null</code>. The parameter Object requestor is
-     * not currently used.  The method throws
-     * <code>IllegalStateException</code> if the clipboard is currently
-     * unavailable.  For example, on some platforms, the system clipboard is
-     * unavailable while it is accessed by another application.
-     *
-     * @param requestor the object requesting the clip data  (not used)
-     * @return the current transferable object on the clipboard
-     * @throws IllegalStateException if the clipboard is currently unavailable
-     * @see java.awt.Toolkit#getSystemClipboard
-     */
-    public synchronized Transferable getContents(Object requestor) {
-        return contents;
-    }
-
-
-    /**
-     * Returns an array of <code>DataFlavor</code>s in which the current
-     * contents of this clipboard can be provided. If there are no
-     * <code>DataFlavor</code>s available, this method returns a zero-length
-     * array.
-     *
-     * @return an array of <code>DataFlavor</code>s in which the current
-     *         contents of this clipboard can be provided
-     *
-     * @throws IllegalStateException if this clipboard is currently unavailable
-     *
-     * @since 1.5
-     */
-    public DataFlavor[] getAvailableDataFlavors() {
-        Transferable cntnts = getContents(null);
-        if (cntnts == null) {
-            return new DataFlavor[0];
-        }
-        return cntnts.getTransferDataFlavors();
-    }
-
-    /**
-     * Returns whether or not the current contents of this clipboard can be
-     * provided in the specified <code>DataFlavor</code>.
-     *
-     * @param flavor the requested <code>DataFlavor</code> for the contents
-     *
-     * @return <code>true</code> if the current contents of this clipboard
-     *         can be provided in the specified <code>DataFlavor</code>;
-     *         <code>false</code> otherwise
-     *
-     * @throws NullPointerException if <code>flavor</code> is <code>null</code>
-     * @throws IllegalStateException if this clipboard is currently unavailable
-     *
-     * @since 1.5
-     */
-    public boolean isDataFlavorAvailable(DataFlavor flavor) {
-        if (flavor == null) {
-            throw new NullPointerException("flavor");
-        }
-
-        Transferable cntnts = getContents(null);
-        if (cntnts == null) {
-            return false;
-        }
-        return cntnts.isDataFlavorSupported(flavor);
-    }
-
-    /**
-     * Returns an object representing the current contents of this clipboard
-     * in the specified <code>DataFlavor</code>.
-     * The class of the object returned is defined by the representation
-     * class of <code>flavor</code>.
-     *
-     * @param flavor the requested <code>DataFlavor</code> for the contents
-     *
-     * @return an object representing the current contents of this clipboard
-     *         in the specified <code>DataFlavor</code>
-     *
-     * @throws NullPointerException if <code>flavor</code> is <code>null</code>
-     * @throws IllegalStateException if this clipboard is currently unavailable
-     * @throws UnsupportedFlavorException if the requested <code>DataFlavor</code>
-     *         is not available
-     * @throws IOException if the data in the requested <code>DataFlavor</code>
-     *         can not be retrieved
-     *
-     * @see DataFlavor#getRepresentationClass
-     *
-     * @since 1.5
-     */
-    public Object getData(DataFlavor flavor)
-        throws UnsupportedFlavorException, IOException {
-        if (flavor == null) {
-            throw new NullPointerException("flavor");
-        }
-
-        Transferable cntnts = getContents(null);
-        if (cntnts == null) {
-            throw new UnsupportedFlavorException(flavor);
-        }
-        return cntnts.getTransferData(flavor);
-    }
-
-
-    /**
-     * Registers the specified <code>FlavorListener</code> to receive
-     * <code>FlavorEvent</code>s from this clipboard.
-     * If <code>listener</code> is <code>null</code>, no exception
-     * is thrown and no action is performed.
-     *
-     * @param listener the listener to be added
-     *
-     * @see #removeFlavorListener
-     * @see #getFlavorListeners
-     * @see FlavorListener
-     * @see FlavorEvent
-     * @since 1.5
-     */
-    public synchronized void addFlavorListener(FlavorListener listener) {
-        if (listener == null) {
-            return;
-        }
-
-        if (flavorListeners == null) {
-            flavorListeners = new HashSet<>();
-            currentDataFlavors = getAvailableDataFlavorSet();
-        }
-
-        flavorListeners.add(listener);
-    }
-
-    /**
-     * Removes the specified <code>FlavorListener</code> so that it no longer
-     * receives <code>FlavorEvent</code>s from this <code>Clipboard</code>.
-     * This method performs no function, nor does it throw an exception, if
-     * the listener specified by the argument was not previously added to this
-     * <code>Clipboard</code>.
-     * If <code>listener</code> is <code>null</code>, no exception
-     * is thrown and no action is performed.
-     *
-     * @param listener the listener to be removed
-     *
-     * @see #addFlavorListener
-     * @see #getFlavorListeners
-     * @see FlavorListener
-     * @see FlavorEvent
-     * @since 1.5
-     */
-    public synchronized void removeFlavorListener(FlavorListener listener) {
-        if (listener == null || flavorListeners == null) {
-            return;
-        }
-        flavorListeners.remove(listener);
-    }
-
-    /**
-     * Returns an array of all the <code>FlavorListener</code>s currently
-     * registered on this <code>Clipboard</code>.
-     *
-     * @return all of this clipboard's <code>FlavorListener</code>s or an empty
-     *         array if no listeners are currently registered
-     * @see #addFlavorListener
-     * @see #removeFlavorListener
-     * @see FlavorListener
-     * @see FlavorEvent
-     * @since 1.5
-     */
-    public synchronized FlavorListener[] getFlavorListeners() {
-        return flavorListeners == null ? new FlavorListener[0] :
-            flavorListeners.toArray(new FlavorListener[flavorListeners.size()]);
-    }
-
-    /**
-     * Checks change of the <code>DataFlavor</code>s and, if necessary,
-     * notifies all listeners that have registered interest for notification
-     * on <code>FlavorEvent</code>s.
-     *
-     * @since 1.5
-     */
-    private void fireFlavorsChanged() {
-        if (flavorListeners == null) {
-            return;
-        }
-
-        Set<DataFlavor> prevDataFlavors = currentDataFlavors;
-        currentDataFlavors = getAvailableDataFlavorSet();
-        if (Objects.equals(prevDataFlavors, currentDataFlavors)) {
-            return;
-        }
-        flavorListeners.forEach(listener ->
-                DataFlavorUtil.getDesktopService().invokeOnEventThread(() ->
-                        listener.flavorsChanged(new FlavorEvent(Clipboard.this))));
-    }
-
-    /**
-     * Returns a set of <code>DataFlavor</code>s currently available
-     * on this clipboard.
-     *
-     * @return a set of <code>DataFlavor</code>s currently available
-     *         on this clipboard
-     *
-     * @since 1.5
-     */
-    private Set<DataFlavor> getAvailableDataFlavorSet() {
-        Set<DataFlavor> set = new HashSet<>();
-        Transferable contents = getContents(null);
-        if (contents != null) {
-            DataFlavor[] flavors = contents.getTransferDataFlavors();
-            if (flavors != null) {
-                set.addAll(Arrays.asList(flavors));
-            }
-        }
-        return set;
-    }
-}
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/ClipboardOwner.java	Tue Feb 17 10:48:24 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-/*
- * Copyright (c) 1996, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.awt.datatransfer;
-
-/**
- * Defines the interface for classes that will provide data to
- * a clipboard. An instance of this interface becomes the owner
- * of the contents of a clipboard (clipboard owner) if it is
- * passed as an argument to
- * {@link java.awt.datatransfer.Clipboard#setContents} method of
- * the clipboard and this method returns successfully.
- * The instance remains the clipboard owner until another application
- * or another object within this application asserts ownership
- * of this clipboard.
- *
- * @see java.awt.datatransfer.Clipboard
- *
- * @author      Amy Fowler
- */
-
-public interface ClipboardOwner {
-
-    /**
-     * Notifies this object that it is no longer the clipboard owner.
-     * This method will be called when another application or another
-     * object within this application asserts ownership of the clipboard.
-     *
-     * @param clipboard the clipboard that is no longer owned
-     * @param contents the contents which this owner had placed on the clipboard
-     */
-    public void lostOwnership(Clipboard clipboard, Transferable contents);
-
-}
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/DataFlavor.java	Tue Feb 17 10:48:24 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1433 +0,0 @@
-/*
- * Copyright (c) 1996, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.awt.datatransfer;
-
-import sun.datatransfer.DataFlavorUtil;
-import sun.reflect.misc.ReflectUtil;
-
-import java.io.ByteArrayInputStream;
-import java.io.CharArrayReader;
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.OptionalDataException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.UnsupportedEncodingException;
-import java.nio.ByteBuffer;
-import java.nio.CharBuffer;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Objects;
-
-import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION;
-
-/**
- * A {@code DataFlavor} provides meta information about data. {@code DataFlavor}
- * is typically used to access data on the clipboard, or during
- * a drag and drop operation.
- * <p>
- * An instance of {@code DataFlavor} encapsulates a content type as
- * defined in <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
- * and <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC 2046</a>.
- * A content type is typically referred to as a MIME type.
- * <p>
- * A content type consists of a media type (referred
- * to as the primary type), a subtype, and optional parameters. See
- * <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045</a>
- * for details on the syntax of a MIME type.
- * <p>
- * The JRE data transfer implementation interprets the parameter &quot;class&quot;
- * of a MIME type as <B>a representation class</b>.
- * The representation class reflects the class of the object being
- * transferred. In other words, the representation class is the type of
- * object returned by {@link Transferable#getTransferData}.
- * For example, the MIME type of {@link #imageFlavor} is
- * {@code "image/x-java-image;class=java.awt.Image"},
- * the primary type is {@code image}, the subtype is
- * {@code x-java-image}, and the representation class is
- * {@code java.awt.Image}. When {@code getTransferData} is invoked
- * with a {@code DataFlavor} of {@code imageFlavor}, an instance of
- * {@code java.awt.Image} is returned.
- * It's important to note that {@code DataFlavor} does no error checking
- * against the representation class. It is up to consumers of
- * {@code DataFlavor}, such as {@code Transferable}, to honor the representation
- * class.
- * <br>
- * Note, if you do not specify a representation class when
- * creating a {@code DataFlavor}, the default
- * representation class is used. See appropriate documentation for
- * {@code DataFlavor}'s constructors.
- * <p>
- * Also, {@code DataFlavor} instances with the &quot;text&quot; primary
- * MIME type may have a &quot;charset&quot; parameter. Refer to
- * <a href="http://www.ietf.org/rfc/rfc2046.txt">RFC 2046</a> and
- * {@link #selectBestTextFlavor} for details on &quot;text&quot; MIME types
- * and the &quot;charset&quot; parameter.
- * <p>
- * Equality of {@code DataFlavors} is determined by the primary type,
- * subtype, and representation class. Refer to {@link #equals(DataFlavor)} for
- * details. When determining equality, any optional parameters are ignored.
- * For example, the following produces two {@code DataFlavors} that
- * are considered identical:
- * <pre>
- *   DataFlavor flavor1 = new DataFlavor(Object.class, &quot;X-test/test; class=&lt;java.lang.Object&gt;; foo=bar&quot;);
- *   DataFlavor flavor2 = new DataFlavor(Object.class, &quot;X-test/test; class=&lt;java.lang.Object&gt;; x=y&quot;);
- *   // The following returns true.
- *   flavor1.equals(flavor2);
- * </pre>
- * As mentioned, {@code flavor1} and {@code flavor2} are considered identical.
- * As such, asking a {@code Transferable} for either {@code DataFlavor} returns
- * the same results.
- * <p>
- * For more information on using data transfer with Swing see
- * the <a href="http://docs.oracle.com/javase/tutorial/uiswing/dnd/index.html">
- * How to Use Drag and Drop and Data Transfer</a>,
- * section in <em>Java Tutorial</em>.
- *
- * @author      Blake Sullivan
- * @author      Laurence P. G. Cable
- * @author      Jeff Dunn
- */
-public class DataFlavor implements Externalizable, Cloneable {
-
-    private static final long serialVersionUID = 8367026044764648243L;
-    private static final Class<InputStream> ioInputStreamClass = InputStream.class;
-
-    /**
-     * Tries to load a class from: the bootstrap loader, the system loader,
-     * the context loader (if one is present) and finally the loader specified.
-     *
-     * @param className the name of the class to be loaded
-     * @param fallback the fallback loader
-     * @return the class loaded
-     * @exception ClassNotFoundException if class is not found
-     */
-    protected final static Class<?> tryToLoadClass(String className,
-                                                   ClassLoader fallback)
-        throws ClassNotFoundException
-    {
-        ReflectUtil.checkPackageAccess(className);
-        try {
-            SecurityManager sm = System.getSecurityManager();
-            if (sm != null) {
-                sm.checkPermission(GET_CLASSLOADER_PERMISSION);
-            }
-            ClassLoader loader = ClassLoader.getSystemClassLoader();
-            try {
-                // bootstrap class loader and system class loader if present
-                return Class.forName(className, true, loader);
-            }
-            catch (ClassNotFoundException exception) {
-                // thread context class loader if and only if present
-                loader = Thread.currentThread().getContextClassLoader();
-                if (loader != null) {
-                    try {
-                        return Class.forName(className, true, loader);
-                    }
-                    catch (ClassNotFoundException e) {
-                        // fallback to user's class loader
-                    }
-                }
-            }
-        } catch (SecurityException exception) {
-            // ignore secured class loaders
-        }
-        return Class.forName(className, true, fallback);
-    }
-
-    /*
-     * private initializer
-     */
-    static private DataFlavor createConstant(Class<?> rc, String prn) {
-        try {
-            return new DataFlavor(rc, prn);
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    /*
-     * private initializer
-     */
-    static private DataFlavor createConstant(String mt, String prn) {
-        try {
-            return new DataFlavor(mt, prn);
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    /*
-     * private initializer
-     */
-    static private DataFlavor initHtmlDataFlavor(String htmlFlavorType) {
-        try {
-            return new DataFlavor ("text/html; class=java.lang.String;document=" +
-                                       htmlFlavorType + ";charset=Unicode");
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    /**
-     * The <code>DataFlavor</code> representing a Java Unicode String class,
-     * where:
-     * <pre>
-     *     representationClass = java.lang.String
-     *     mimeType           = "application/x-java-serialized-object"
-     * </pre>
-     */
-    public static final DataFlavor stringFlavor = createConstant(java.lang.String.class, "Unicode String");
-
-    /**
-     * The <code>DataFlavor</code> representing a Java Image class,
-     * where:
-     * <pre>
-     *     representationClass = java.awt.Image
-     *     mimeType            = "image/x-java-image"
-     * </pre>
-     */
-    public static final DataFlavor imageFlavor = createConstant("image/x-java-image; class=java.awt.Image", "Image");
-
-    /**
-     * The <code>DataFlavor</code> representing plain text with Unicode
-     * encoding, where:
-     * <pre>
-     *     representationClass = InputStream
-     *     mimeType            = "text/plain; charset=unicode"
-     * </pre>
-     * This <code>DataFlavor</code> has been <b>deprecated</b> because
-     * (1) Its representation is an InputStream, an 8-bit based representation,
-     * while Unicode is a 16-bit character set; and (2) The charset "unicode"
-     * is not well-defined. "unicode" implies a particular platform's
-     * implementation of Unicode, not a cross-platform implementation.
-     *
-     * @deprecated as of 1.3. Use <code>DataFlavor.getReaderForText(Transferable)</code>
-     *             instead of <code>Transferable.getTransferData(DataFlavor.plainTextFlavor)</code>.
-     */
-    @Deprecated
-    public static final DataFlavor plainTextFlavor = createConstant("text/plain; charset=unicode; class=java.io.InputStream", "Plain Text");
-
-    /**
-     * A MIME Content-Type of application/x-java-serialized-object represents
-     * a graph of Java object(s) that have been made persistent.
-     *
-     * The representation class associated with this <code>DataFlavor</code>
-     * identifies the Java type of an object returned as a reference
-     * from an invocation <code>java.awt.datatransfer.getTransferData</code>.
-     */
-    public static final String javaSerializedObjectMimeType = "application/x-java-serialized-object";
-
-    /**
-     * To transfer a list of files to/from Java (and the underlying
-     * platform) a <code>DataFlavor</code> of this type/subtype and
-     * representation class of <code>java.util.List</code> is used.
-     * Each element of the list is required/guaranteed to be of type
-     * <code>java.io.File</code>.
-     */
-    public static final DataFlavor javaFileListFlavor = createConstant("application/x-java-file-list;class=java.util.List", null);
-
-    /**
-     * To transfer a reference to an arbitrary Java object reference that
-     * has no associated MIME Content-type, across a <code>Transferable</code>
-     * interface WITHIN THE SAME JVM, a <code>DataFlavor</code>
-     * with this type/subtype is used, with a <code>representationClass</code>
-     * equal to the type of the class/interface being passed across the
-     * <code>Transferable</code>.
-     * <p>
-     * The object reference returned from
-     * <code>Transferable.getTransferData</code> for a <code>DataFlavor</code>
-     * with this MIME Content-Type is required to be
-     * an instance of the representation Class of the <code>DataFlavor</code>.
-     */
-    public static final String javaJVMLocalObjectMimeType = "application/x-java-jvm-local-objectref";
-
-    /**
-     * In order to pass a live link to a Remote object via a Drag and Drop
-     * <code>ACTION_LINK</code> operation a Mime Content Type of
-     * application/x-java-remote-object should be used,
-     * where the representation class of the <code>DataFlavor</code>
-     * represents the type of the <code>Remote</code> interface to be
-     * transferred.
-     */
-    public static final String javaRemoteObjectMimeType = "application/x-java-remote-object";
-
-    /**
-     * Represents a piece of an HTML markup. The markup consists of the part
-     * selected on the source side. Therefore some tags in the markup may be
-     * unpaired. If the flavor is used to represent the data in
-     * a {@link Transferable} instance, no additional changes will be made.
-     * This DataFlavor instance represents the same HTML markup as DataFlavor
-     * instances which content MIME type does not contain document parameter
-     * and representation class is the String class.
-     * <pre>
-     *     representationClass = String
-     *     mimeType           = "text/html"
-     * </pre>
-     */
-    public static DataFlavor selectionHtmlFlavor = initHtmlDataFlavor("selection");
-
-    /**
-     * Represents a piece of an HTML markup. If possible, the markup received
-     * from a native system is supplemented with pair tags to be
-     * a well-formed HTML markup. If the flavor is used to represent the data in
-     * a {@link Transferable} instance, no additional changes will be made.
-     * <pre>
-     *     representationClass = String
-     *     mimeType           = "text/html"
-     * </pre>
-     */
-    public static DataFlavor fragmentHtmlFlavor = initHtmlDataFlavor("fragment");
-
-    /**
-     * Represents a piece of an HTML markup. If possible, the markup
-     * received from a native system is supplemented with additional
-     * tags to make up a well-formed HTML document. If the flavor is used to
-     * represent the data in a {@link Transferable} instance,
-     * no additional changes will be made.
-     * <pre>
-     *     representationClass = String
-     *     mimeType           = "text/html"
-     * </pre>
-     */
-    public static  DataFlavor allHtmlFlavor = initHtmlDataFlavor("all");
-
-    /**
-     * Constructs a new <code>DataFlavor</code>.  This constructor is
-     * provided only for the purpose of supporting the
-     * <code>Externalizable</code> interface.  It is not
-     * intended for public (client) use.
-     *
-     * @since 1.2
-     */
-    public DataFlavor() {
-        super();
-    }
-
-    /**
-     * Constructs a fully specified <code>DataFlavor</code>.
-     *
-     * @exception NullPointerException if either <code>primaryType</code>,
-     *            <code>subType</code> or <code>representationClass</code> is null
-     */
-    private DataFlavor(String primaryType, String subType, MimeTypeParameterList params, Class<?> representationClass, String humanPresentableName) {
-        super();
-        if (primaryType == null) {
-            throw new NullPointerException("primaryType");
-        }
-        if (subType == null) {
-            throw new NullPointerException("subType");
-        }
-        if (representationClass == null) {
-            throw new NullPointerException("representationClass");
-        }
-
-        if (params == null) params = new MimeTypeParameterList();
-
-        params.set("class", representationClass.getName());
-
-        if (humanPresentableName == null) {
-            humanPresentableName = params.get("humanPresentableName");
-
-            if (humanPresentableName == null)
-                humanPresentableName = primaryType + "/" + subType;
-        }
-
-        try {
-            mimeType = new MimeType(primaryType, subType, params);
-        } catch (MimeTypeParseException mtpe) {
-            throw new IllegalArgumentException("MimeType Parse Exception: " + mtpe.getMessage());
-        }
-
-        this.representationClass  = representationClass;
-        this.humanPresentableName = humanPresentableName;
-
-        mimeType.removeParameter("humanPresentableName");
-    }
-
-    /**
-     * Constructs a <code>DataFlavor</code> that represents a Java class.
-     * <p>
-     * The returned <code>DataFlavor</code> will have the following
-     * characteristics:
-     * <pre>
-     *    representationClass = representationClass
-     *    mimeType            = application/x-java-serialized-object
-     * </pre>
-     * @param representationClass the class used to transfer data in this flavor
-     * @param humanPresentableName the human-readable string used to identify
-     *                 this flavor; if this parameter is <code>null</code>
-     *                 then the value of the MIME Content Type is used
-     * @exception NullPointerException if <code>representationClass</code> is null
-     */
-    public DataFlavor(Class<?> representationClass, String humanPresentableName) {
-        this("application", "x-java-serialized-object", null, representationClass, humanPresentableName);
-        if (representationClass == null) {
-            throw new NullPointerException("representationClass");
-        }
-    }
-
-    /**
-     * Constructs a <code>DataFlavor</code> that represents a
-     * <code>MimeType</code>.
-     * <p>
-     * The returned <code>DataFlavor</code> will have the following
-     * characteristics:
-     * <p>
-     * If the <code>mimeType</code> is
-     * "application/x-java-serialized-object; class=&lt;representation class&gt;",
-     * the result is the same as calling
-     * <code>new DataFlavor(Class.forName(&lt;representation class&gt;)</code>.
-     * <p>
-     * Otherwise:
-     * <pre>
-     *     representationClass = InputStream
-     *     mimeType            = mimeType
-     * </pre>
-     * @param mimeType the string used to identify the MIME type for this flavor;
-     *                 if the <code>mimeType</code> does not specify a
-     *                 "class=" parameter, or if the class is not successfully
-     *                 loaded, then an <code>IllegalArgumentException</code>
-     *                 is thrown
-     * @param humanPresentableName the human-readable string used to identify
-     *                 this flavor; if this parameter is <code>null</code>
-     *                 then the value of the MIME Content Type is used
-     * @exception IllegalArgumentException if <code>mimeType</code> is
-     *                 invalid or if the class is not successfully loaded
-     * @exception NullPointerException if <code>mimeType</code> is null
-     */
-    public DataFlavor(String mimeType, String humanPresentableName) {
-        super();
-        if (mimeType == null) {
-            throw new NullPointerException("mimeType");
-        }
-        try {
-            initialize(mimeType, humanPresentableName, this.getClass().getClassLoader());
-        } catch (MimeTypeParseException mtpe) {
-            throw new IllegalArgumentException("failed to parse:" + mimeType);
-        } catch (ClassNotFoundException cnfe) {
-            throw new IllegalArgumentException("can't find specified class: " + cnfe.getMessage());
-        }
-    }
-
-    /**
-     * Constructs a <code>DataFlavor</code> that represents a
-     * <code>MimeType</code>.
-     * <p>
-     * The returned <code>DataFlavor</code> will have the following
-     * characteristics:
-     * <p>
-     * If the mimeType is
-     * "application/x-java-serialized-object; class=&lt;representation class&gt;",
-     * the result is the same as calling
-     * <code>new DataFlavor(Class.forName(&lt;representation class&gt;)</code>.
-     * <p>
-     * Otherwise:
-     * <pre>
-     *     representationClass = InputStream
-     *     mimeType            = mimeType
-     * </pre>
-     * @param mimeType the string used to identify the MIME type for this flavor
-     * @param humanPresentableName the human-readable string used to
-     *          identify this flavor
-     * @param classLoader the class loader to use
-     * @exception ClassNotFoundException if the class is not loaded
-     * @exception IllegalArgumentException if <code>mimeType</code> is
-     *                 invalid
-     * @exception NullPointerException if <code>mimeType</code> is null
-     */
-    public DataFlavor(String mimeType, String humanPresentableName, ClassLoader classLoader) throws ClassNotFoundException {
-        super();
-        if (mimeType == null) {
-            throw new NullPointerException("mimeType");
-        }
-        try {
-            initialize(mimeType, humanPresentableName, classLoader);
-        } catch (MimeTypeParseException mtpe) {
-            throw new IllegalArgumentException("failed to parse:" + mimeType);
-        }
-    }
-
-    /**
-     * Constructs a <code>DataFlavor</code> from a <code>mimeType</code> string.
-     * The string can specify a "class=&lt;fully specified Java class name&gt;"
-     * parameter to create a <code>DataFlavor</code> with the desired
-     * representation class. If the string does not contain "class=" parameter,
-     * <code>java.io.InputStream</code> is used as default.
-     *
-     * @param mimeType the string used to identify the MIME type for this flavor;
-     *                 if the class specified by "class=" parameter is not
-     *                 successfully loaded, then an
-     *                 <code>ClassNotFoundException</code> is thrown
-     * @exception ClassNotFoundException if the class is not loaded
-     * @exception IllegalArgumentException if <code>mimeType</code> is
-     *                 invalid
-     * @exception NullPointerException if <code>mimeType</code> is null
-     */
-    public DataFlavor(String mimeType) throws ClassNotFoundException {
-        super();
-        if (mimeType == null) {
-            throw new NullPointerException("mimeType");
-        }
-        try {
-            initialize(mimeType, null, this.getClass().getClassLoader());
-        } catch (MimeTypeParseException mtpe) {
-            throw new IllegalArgumentException("failed to parse:" + mimeType);
-        }
-    }
-
-   /**
-    * Common initialization code called from various constructors.
-    *
-    * @param mimeType the MIME Content Type (must have a class= param)
-    * @param humanPresentableName the human Presentable Name or
-    *                 <code>null</code>
-    * @param classLoader the fallback class loader to resolve against
-    *
-    * @throws MimeTypeParseException
-    * @throws ClassNotFoundException
-    * @throws  NullPointerException if <code>mimeType</code> is null
-    *
-    * @see #tryToLoadClass
-    */
-    private void initialize(String mimeType, String humanPresentableName, ClassLoader classLoader) throws MimeTypeParseException, ClassNotFoundException {
-        if (mimeType == null) {
-            throw new NullPointerException("mimeType");
-        }
-
-        this.mimeType = new MimeType(mimeType); // throws
-
-        String rcn = getParameter("class");
-
-        if (rcn == null) {
-            if ("application/x-java-serialized-object".equals(this.mimeType.getBaseType()))
-
-                throw new IllegalArgumentException("no representation class specified for:" + mimeType);
-            else
-                representationClass = java.io.InputStream.class; // default
-        } else { // got a class name
-            representationClass = DataFlavor.tryToLoadClass(rcn, classLoader);
-        }
-
-        this.mimeType.setParameter("class", representationClass.getName());
-
-        if (humanPresentableName == null) {
-            humanPresentableName = this.mimeType.getParameter("humanPresentableName");
-            if (humanPresentableName == null)
-                humanPresentableName = this.mimeType.getPrimaryType() + "/" + this.mimeType.getSubType();
-        }
-
-        this.humanPresentableName = humanPresentableName; // set it.
-
-        this.mimeType.removeParameter("humanPresentableName"); // just in case
-    }
-
-    /**
-     * String representation of this <code>DataFlavor</code> and its
-     * parameters. The resulting <code>String</code> contains the name of
-     * the <code>DataFlavor</code> class, this flavor's MIME type, and its
-     * representation class. If this flavor has a primary MIME type of "text",
-     * supports the charset parameter, and has an encoded representation, the
-     * flavor's charset is also included. See <code>selectBestTextFlavor</code>
-     * for a list of text flavors which support the charset parameter.
-     *
-     * @return  string representation of this <code>DataFlavor</code>
-     * @see #selectBestTextFlavor
-     */
-    public String toString() {
-        String string = getClass().getName();
-        string += "["+paramString()+"]";
-        return string;
-    }
-
-    private String paramString() {
-        String params = "";
-        params += "mimetype=";
-        if (mimeType == null) {
-            params += "null";
-        } else {
-            params += mimeType.getBaseType();
-        }
-        params += ";representationclass=";
-        if (representationClass == null) {
-           params += "null";
-        } else {
-           params += representationClass.getName();
-        }
-        if (DataFlavorUtil.isFlavorCharsetTextType(this) &&
-            (isRepresentationClassInputStream() ||
-             isRepresentationClassByteBuffer() ||
-             byte[].class.equals(representationClass)))
-        {
-            params += ";charset=" + DataFlavorUtil.getTextCharset(this);
-        }
-        return params;
-    }
-
-    /**
-     * Returns a <code>DataFlavor</code> representing plain text with Unicode
-     * encoding, where:
-     * <pre>
-     *     representationClass = java.io.InputStream
-     *     mimeType            = "text/plain;
-     *                            charset=&lt;platform default Unicode encoding&gt;"
-     * </pre>
-     * Sun's implementation for Microsoft Windows uses the encoding <code>utf-16le</code>.
-     * Sun's implementation for Solaris and Linux uses the encoding
-     * <code>iso-10646-ucs-2</code>.
-     *
-     * @return a <code>DataFlavor</code> representing plain text
-     *    with Unicode encoding
-     * @since 1.3
-     */
-    public static final DataFlavor getTextPlainUnicodeFlavor() {
-        return new DataFlavor(
-            "text/plain;charset=" + DataFlavorUtil.getDesktopService().getDefaultUnicodeEncoding()
-            +";class=java.io.InputStream", "Plain Text");
-    }
-
-    /**
-     * Selects the best text <code>DataFlavor</code> from an array of <code>
-     * DataFlavor</code>s. Only <code>DataFlavor.stringFlavor</code>, and
-     * equivalent flavors, and flavors that have a primary MIME type of "text",
-     * are considered for selection.
-     * <p>
-     * Flavors are first sorted by their MIME types in the following order:
-     * <ul>
-     * <li>"text/sgml"
-     * <li>"text/xml"
-     * <li>"text/html"
-     * <li>"text/rtf"
-     * <li>"text/enriched"
-     * <li>"text/richtext"
-     * <li>"text/uri-list"
-     * <li>"text/tab-separated-values"
-     * <li>"text/t140"
-     * <li>"text/rfc822-headers"
-     * <li>"text/parityfec"
-     * <li>"text/directory"
-     * <li>"text/css"
-     * <li>"text/calendar"
-     * <li>"application/x-java-serialized-object"
-     * <li>"text/plain"
-     * <li>"text/&lt;other&gt;"
-     * </ul>
-     * <p>For example, "text/sgml" will be selected over
-     * "text/html", and <code>DataFlavor.stringFlavor</code> will be chosen
-     * over <code>DataFlavor.plainTextFlavor</code>.
-     * <p>
-     * If two or more flavors share the best MIME type in the array, then that
-     * MIME type will be checked to see if it supports the charset parameter.
-     * <p>
-     * The following MIME types support, or are treated as though they support,
-     * the charset parameter:
-     * <ul>
-     * <li>"text/sgml"
-     * <li>"text/xml"
-     * <li>"text/html"
-     * <li>"text/enriched"
-     * <li>"text/richtext"
-     * <li>"text/uri-list"
-     * <li>"text/directory"
-     * <li>"text/css"
-     * <li>"text/calendar"
-     * <li>"application/x-java-serialized-object"
-     * <li>"text/plain"
-     * </ul>
-     * The following MIME types do not support, or are treated as though they
-     * do not support, the charset parameter:
-     * <ul>
-     * <li>"text/rtf"
-     * <li>"text/tab-separated-values"
-     * <li>"text/t140"
-     * <li>"text/rfc822-headers"
-     * <li>"text/parityfec"
-     * </ul>
-     * For "text/&lt;other&gt;" MIME types, the first time the JRE needs to
-     * determine whether the MIME type supports the charset parameter, it will
-     * check whether the parameter is explicitly listed in an arbitrarily
-     * chosen <code>DataFlavor</code> which uses that MIME type. If so, the JRE
-     * will assume from that point on that the MIME type supports the charset
-     * parameter and will not check again. If the parameter is not explicitly
-     * listed, the JRE will assume from that point on that the MIME type does
-     * not support the charset parameter and will not check again. Because
-     * this check is performed on an arbitrarily chosen
-     * <code>DataFlavor</code>, developers must ensure that all
-     * <code>DataFlavor</code>s with a "text/&lt;other&gt;" MIME type specify
-     * the charset parameter if it is supported by that MIME type. Developers
-     * should never rely on the JRE to substitute the platform's default
-     * charset for a "text/&lt;other&gt;" DataFlavor. Failure to adhere to this
-     * restriction will lead to undefined behavior.
-     * <p>
-     * If the best MIME type in the array does not support the charset
-     * parameter, the flavors which share that MIME type will then be sorted by
-     * their representation classes in the following order:
-     * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
-     * <code>[B</code>, &lt;all others&gt;.
-     * <p>
-     * If two or more flavors share the best representation class, or if no
-     * flavor has one of the three specified representations, then one of those
-     * flavors will be chosen non-deterministically.
-     * <p>
-     * If the best MIME type in the array does support the charset parameter,
-     * the flavors which share that MIME type will then be sorted by their
-     * representation classes in the following order:
-     * <code>java.io.Reader</code>, <code>java.lang.String</code>,
-     * <code>java.nio.CharBuffer</code>, <code>[C</code>, &lt;all others&gt;.
-     * <p>
-     * If two or more flavors share the best representation class, and that
-     * representation is one of the four explicitly listed, then one of those
-     * flavors will be chosen non-deterministically. If, however, no flavor has
-     * one of the four specified representations, the flavors will then be
-     * sorted by their charsets. Unicode charsets, such as "UTF-16", "UTF-8",
-     * "UTF-16BE", "UTF-16LE", and their aliases, are considered best. After
-     * them, the platform default charset and its aliases are selected.
-     * "US-ASCII" and its aliases are worst. All other charsets are chosen in
-     * alphabetical order, but only charsets supported by this implementation
-     * of the Java platform will be considered.
-     * <p>
-     * If two or more flavors share the best charset, the flavors will then
-     * again be sorted by their representation classes in the following order:
-     * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
-     * <code>[B</code>, &lt;all others&gt;.
-     * <p>
-     * If two or more flavors share the best representation class, or if no
-     * flavor has one of the three specified representations, then one of those
-     * flavors will be chosen non-deterministically.
-     *
-     * @param availableFlavors an array of available <code>DataFlavor</code>s
-     * @return the best (highest fidelity) flavor according to the rules
-     *         specified above, or <code>null</code>,
-     *         if <code>availableFlavors</code> is <code>null</code>,
-     *         has zero length, or contains no text flavors
-     * @since 1.3
-     */
-    public static final DataFlavor selectBestTextFlavor(
-                                       DataFlavor[] availableFlavors) {
-        if (availableFlavors == null || availableFlavors.length == 0) {
-            return null;
-        }
-
-        DataFlavor bestFlavor = Collections.max(Arrays.asList(availableFlavors),
-                                                DataFlavorUtil.getTextFlavorComparator());
-
-        if (!bestFlavor.isFlavorTextType()) {
-            return null;
-        }
-
-        return bestFlavor;
-    }
-
-    /**
-     * Gets a Reader for a text flavor, decoded, if necessary, for the expected
-     * charset (encoding). The supported representation classes are
-     * <code>java.io.Reader</code>, <code>java.lang.String</code>,
-     * <code>java.nio.CharBuffer</code>, <code>[C</code>,
-     * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>,
-     * and <code>[B</code>.
-     * <p>
-     * Because text flavors which do not support the charset parameter are
-     * encoded in a non-standard format, this method should not be called for
-     * such flavors. However, in order to maintain backward-compatibility,
-     * if this method is called for such a flavor, this method will treat the
-     * flavor as though it supports the charset parameter and attempt to
-     * decode it accordingly. See <code>selectBestTextFlavor</code> for a list
-     * of text flavors which do not support the charset parameter.
-     *
-     * @param transferable the <code>Transferable</code> whose data will be
-     *        requested in this flavor
-     *
-     * @return a <code>Reader</code> to read the <code>Transferable</code>'s
-     *         data
-     *
-     * @exception IllegalArgumentException if the representation class
-     *            is not one of the seven listed above
-     * @exception IllegalArgumentException if the <code>Transferable</code>
-     *            has <code>null</code> data
-     * @exception NullPointerException if the <code>Transferable</code> is
-     *            <code>null</code>
-     * @exception UnsupportedEncodingException if this flavor's representation
-     *            is <code>java.io.InputStream</code>,
-     *            <code>java.nio.ByteBuffer</code>, or <code>[B</code> and
-     *            this flavor's encoding is not supported by this
-     *            implementation of the Java platform
-     * @exception UnsupportedFlavorException if the <code>Transferable</code>
-     *            does not support this flavor
-     * @exception IOException if the data cannot be read because of an
-     *            I/O error
-     * @see #selectBestTextFlavor
-     * @since 1.3
-     */
-    public Reader getReaderForText(Transferable transferable)
-        throws UnsupportedFlavorException, IOException
-    {
-        Object transferObject = transferable.getTransferData(this);
-        if (transferObject == null) {
-            throw new IllegalArgumentException
-                ("getTransferData() returned null");
-        }
-
-        if (transferObject instanceof Reader) {
-            return (Reader)transferObject;
-        } else if (transferObject instanceof String) {
-            return new StringReader((String)transferObject);
-        } else if (transferObject instanceof CharBuffer) {
-            CharBuffer buffer = (CharBuffer)transferObject;
-            int size = buffer.remaining();
-            char[] chars = new char[size];
-            buffer.get(chars, 0, size);
-            return new CharArrayReader(chars);
-        } else if (transferObject instanceof char[]) {
-            return new CharArrayReader((char[])transferObject);
-        }
-
-        InputStream stream = null;
-
-        if (transferObject instanceof InputStream) {
-            stream = (InputStream)transferObject;
-        } else if (transferObject instanceof ByteBuffer) {
-            ByteBuffer buffer = (ByteBuffer)transferObject;
-            int size = buffer.remaining();
-            byte[] bytes = new byte[size];
-            buffer.get(bytes, 0, size);
-            stream = new ByteArrayInputStream(bytes);
-        } else if (transferObject instanceof byte[]) {
-            stream = new ByteArrayInputStream((byte[])transferObject);
-        }
-
-        if (stream == null) {
-            throw new IllegalArgumentException("transfer data is not Reader, String, CharBuffer, char array, InputStream, ByteBuffer, or byte array");
-        }
-
-        String encoding = getParameter("charset");
-        return (encoding == null)
-            ? new InputStreamReader(stream)
-            : new InputStreamReader(stream, encoding);
-    }
-
-    /**
-     * Returns the MIME type string for this <code>DataFlavor</code>.
-     * @return the MIME type string for this flavor
-     */
-    public String getMimeType() {
-        return (mimeType != null) ? mimeType.toString() : null;
-    }
-
-    /**
-     * Returns the <code>Class</code> which objects supporting this
-     * <code>DataFlavor</code> will return when this <code>DataFlavor</code>
-     * is requested.
-     * @return the <code>Class</code> which objects supporting this
-     * <code>DataFlavor</code> will return when this <code>DataFlavor</code>
-     * is requested
-     */
-    public Class<?> getRepresentationClass() {
-        return representationClass;
-    }
-
-    /**
-     * Returns the human presentable name for the data format that this
-     * <code>DataFlavor</code> represents.  This name would be localized
-     * for different countries.
-     * @return the human presentable name for the data format that this
-     *    <code>DataFlavor</code> represents
-     */
-    public String getHumanPresentableName() {
-        return humanPresentableName;
-    }
-
-    /**
-     * Returns the primary MIME type for this <code>DataFlavor</code>.
-     * @return the primary MIME type of this <code>DataFlavor</code>
-     */
-    public String getPrimaryType() {
-        return (mimeType != null) ? mimeType.getPrimaryType() : null;
-    }
-
-    /**
-     * Returns the sub MIME type of this <code>DataFlavor</code>.
-     * @return the Sub MIME type of this <code>DataFlavor</code>
-     */
-    public String getSubType() {
-        return (mimeType != null) ? mimeType.getSubType() : null;
-    }
-
-    /**
-     * Returns the human presentable name for this <code>DataFlavor</code>
-     * if <code>paramName</code> equals "humanPresentableName".  Otherwise
-     * returns the MIME type value associated with <code>paramName</code>.
-     *
-     * @param paramName the parameter name requested
-     * @return the value of the name parameter, or <code>null</code>
-     *  if there is no associated value
-     */
-    public String getParameter(String paramName) {
-        if (paramName.equals("humanPresentableName")) {
-            return humanPresentableName;
-        } else {
-            return (mimeType != null)
-                ? mimeType.getParameter(paramName) : null;
-        }
-    }
-
-    /**
-     * Sets the human presentable name for the data format that this
-     * <code>DataFlavor</code> represents. This name would be localized
-     * for different countries.
-     * @param humanPresentableName the new human presentable name
-     */
-    public void setHumanPresentableName(String humanPresentableName) {
-        this.humanPresentableName = humanPresentableName;
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p>
-     * The equals comparison for the {@code DataFlavor} class is implemented
-     * as follows: Two <code>DataFlavor</code>s are considered equal if and
-     * only if their MIME primary type and subtype and representation class are
-     * equal. Additionally, if the primary type is "text", the subtype denotes
-     * a text flavor which supports the charset parameter, and the
-     * representation class is not <code>java.io.Reader</code>,
-     * <code>java.lang.String</code>, <code>java.nio.CharBuffer</code>, or
-     * <code>[C</code>, the <code>charset</code> parameter must also be equal.
-     * If a charset is not explicitly specified for one or both
-     * <code>DataFlavor</code>s, the platform default encoding is assumed. See
-     * <code>selectBestTextFlavor</code> for a list of text flavors which
-     * support the charset parameter.
-     *
-     * @param o the <code>Object</code> to compare with <code>this</code>
-     * @return <code>true</code> if <code>that</code> is equivalent to this
-     *         <code>DataFlavor</code>; <code>false</code> otherwise
-     * @see #selectBestTextFlavor
-     */
-    public boolean equals(Object o) {
-        return ((o instanceof DataFlavor) && equals((DataFlavor)o));
-    }
-
-    /**
-     * This method has the same behavior as {@link #equals(Object)}.
-     * The only difference being that it takes a {@code DataFlavor} instance
-     * as a parameter.
-     *
-     * @param that the <code>DataFlavor</code> to compare with
-     *        <code>this</code>
-     * @return <code>true</code> if <code>that</code> is equivalent to this
-     *         <code>DataFlavor</code>; <code>false</code> otherwise
-     * @see #selectBestTextFlavor
-     */
-    public boolean equals(DataFlavor that) {
-        if (that == null) {
-            return false;
-        }
-        if (this == that) {
-            return true;
-        }
-
-        if (!Objects.equals(this.getRepresentationClass(), that.getRepresentationClass())) {
-            return false;
-        }
-
-        if (mimeType == null) {
-            if (that.mimeType != null) {
-                return false;
-            }
-        } else {
-            if (!mimeType.match(that.mimeType)) {
-                return false;
-            }
-
-            if ("text".equals(getPrimaryType())) {
-                if (DataFlavorUtil.doesSubtypeSupportCharset(this)
-                        && representationClass != null
-                        && !isStandardTextRepresentationClass()) {
-                    String thisCharset =
-                            DataFlavorUtil.canonicalName(this.getParameter("charset"));
-                    String thatCharset =
-                            DataFlavorUtil.canonicalName(that.getParameter("charset"));
-                    if (!Objects.equals(thisCharset, thatCharset)) {
-                        return false;
-                    }
-                }
-
-                if ("html".equals(getSubType())) {
-                    String thisDocument = this.getParameter("document");
-                    String thatDocument = that.getParameter("document");
-                    if (!Objects.equals(thisDocument, thatDocument)) {
-                        return false;
-                    }
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Compares only the <code>mimeType</code> against the passed in
-     * <code>String</code> and <code>representationClass</code> is
-     * not considered in the comparison.
-     *
-     * If <code>representationClass</code> needs to be compared, then
-     * <code>equals(new DataFlavor(s))</code> may be used.
-     * @deprecated As inconsistent with <code>hashCode()</code> contract,
-     *             use <code>isMimeTypeEqual(String)</code> instead.
-     * @param s the {@code mimeType} to compare.
-     * @return true if the String (MimeType) is equal; false otherwise or if
-     *         {@code s} is {@code null}
-     */
-    @Deprecated
-    public boolean equals(String s) {
-        if (s == null || mimeType == null)
-            return false;
-        return isMimeTypeEqual(s);
-    }
-
-    /**
-     * Returns hash code for this <code>DataFlavor</code>.
-     * For two equal <code>DataFlavor</code>s, hash codes are equal.
-     * For the <code>String</code>
-     * that matches <code>DataFlavor.equals(String)</code>, it is not
-     * guaranteed that <code>DataFlavor</code>'s hash code is equal
-     * to the hash code of the <code>String</code>.
-     *
-     * @return a hash code for this <code>DataFlavor</code>
-     */
-    public int hashCode() {
-        int total = 0;
-
-        if (representationClass != null) {
-            total += representationClass.hashCode();
-        }
-
-        if (mimeType != null) {
-            String primaryType = mimeType.getPrimaryType();
-            if (primaryType != null) {
-                total += primaryType.hashCode();
-            }
-
-            // Do not add subType.hashCode() to the total. equals uses
-            // MimeType.match which reports a match if one or both of the
-            // subTypes is '*', regardless of the other subType.
-
-            if ("text".equals(primaryType)) {
-                if (DataFlavorUtil.doesSubtypeSupportCharset(this)
-                        && representationClass != null
-                        && !isStandardTextRepresentationClass()) {
-                    String charset = DataFlavorUtil.canonicalName(getParameter("charset"));
-                    if (charset != null) {
-                        total += charset.hashCode();
-                    }
-                }
-
-                if ("html".equals(getSubType())) {
-                    String document = this.getParameter("document");
-                    if (document != null) {
-                        total += document.hashCode();
-                    }
-                }
-            }
-        }
-
-        return total;
-    }
-
-    /**
-     * Identical to {@link #equals(DataFlavor)}.
-     *
-     * @param that the <code>DataFlavor</code> to compare with
-     *        <code>this</code>
-     * @return <code>true</code> if <code>that</code> is equivalent to this
-     *         <code>DataFlavor</code>; <code>false</code> otherwise
-     * @see #selectBestTextFlavor
-     * @since 1.3
-     */
-    public boolean match(DataFlavor that) {
-        return equals(that);
-    }
-
-    /**
-     * Returns whether the string representation of the MIME type passed in
-     * is equivalent to the MIME type of this <code>DataFlavor</code>.
-     * Parameters are not included in the comparison.
-     *
-     * @param mimeType the string representation of the MIME type
-     * @return true if the string representation of the MIME type passed in is
-     *         equivalent to the MIME type of this <code>DataFlavor</code>;
-     *         false otherwise
-     * @throws NullPointerException if mimeType is <code>null</code>
-     */
-    public boolean isMimeTypeEqual(String mimeType) {
-        // JCK Test DataFlavor0117: if 'mimeType' is null, throw NPE
-        if (mimeType == null) {
-            throw new NullPointerException("mimeType");
-        }
-        if (this.mimeType == null) {
-            return false;
-        }
-        try {
-            return this.mimeType.match(new MimeType(mimeType));
-        } catch (MimeTypeParseException mtpe) {
-            return false;
-        }
-    }
-
-    /**
-     * Compares the <code>mimeType</code> of two <code>DataFlavor</code>
-     * objects. No parameters are considered.
-     *
-     * @param dataFlavor the <code>DataFlavor</code> to be compared
-     * @return true if the <code>MimeType</code>s are equal,
-     *  otherwise false
-     */
-
-    public final boolean isMimeTypeEqual(DataFlavor dataFlavor) {
-        return isMimeTypeEqual(dataFlavor.mimeType);
-    }
-
-    /**
-     * Compares the <code>mimeType</code> of two <code>DataFlavor</code>
-     * objects.  No parameters are considered.
-     *
-     * @return true if the <code>MimeType</code>s are equal,
-     *  otherwise false
-     */
-
-    private boolean isMimeTypeEqual(MimeType mtype) {
-        if (this.mimeType == null) {
-            return (mtype == null);
-        }
-        return mimeType.match(mtype);
-    }
-
-    /**
-     * Checks if the representation class is one of the standard text
-     * representation classes.
-     *
-     * @return true if the representation class is one of the standard text
-     *              representation classes, otherwise false
-     */
-    private boolean isStandardTextRepresentationClass() {
-        return isRepresentationClassReader()
-                || String.class.equals(representationClass)
-                || isRepresentationClassCharBuffer()
-                || char[].class.equals(representationClass);
-    }
-
-   /**
-    * Does the <code>DataFlavor</code> represent a serialized object?
-    * @return whether or not a serialized object is represented
-    */
-    public boolean isMimeTypeSerializedObject() {
-        return isMimeTypeEqual(javaSerializedObjectMimeType);
-    }
-
-    /**
-     * Returns the default representation class.
-     * @return the default representation class
-     */
-    public final Class<?> getDefaultRepresentationClass() {
-        return ioInputStreamClass;
-    }
-
-    /**
-     * Returns the name of the default representation class.
-     * @return the name of the default representation class
-     */
-    public final String getDefaultRepresentationClassAsString() {
-        return getDefaultRepresentationClass().getName();
-    }
-
-   /**
-    * Does the <code>DataFlavor</code> represent a
-    * <code>java.io.InputStream</code>?
-    * @return whether or not this {@code DataFlavor} represent a
-    * {@code java.io.InputStream}
-    */
-    public boolean isRepresentationClassInputStream() {
-        return ioInputStreamClass.isAssignableFrom(representationClass);
-    }
-
-    /**
-     * Returns whether the representation class for this
-     * <code>DataFlavor</code> is <code>java.io.Reader</code> or a subclass
-     * thereof.
-     * @return whether or not the representation class for this
-     * {@code DataFlavor} is {@code java.io.Reader} or a subclass
-     * thereof
-     *
-     * @since 1.4
-     */
-    public boolean isRepresentationClassReader() {
-        return java.io.Reader.class.isAssignableFrom(representationClass);
-    }
-
-    /**
-     * Returns whether the representation class for this
-     * <code>DataFlavor</code> is <code>java.nio.CharBuffer</code> or a
-     * subclass thereof.
-     * @return whether or not the representation class for this
-     * {@code DataFlavor} is {@code java.nio.CharBuffer} or a subclass
-     * thereof
-     *
-     * @since 1.4
-     */
-    public boolean isRepresentationClassCharBuffer() {
-        return java.nio.CharBuffer.class.isAssignableFrom(representationClass);
-    }
-
-    /**
-     * Returns whether the representation class for this
-     * <code>DataFlavor</code> is <code>java.nio.ByteBuffer</code> or a
-     * subclass thereof.
-     * @return whether or not the representation class for this
-     * {@code DataFlavor} is {@code java.nio.ByteBuffer} or a subclass
-     * thereof
-     *
-     * @since 1.4
-     */
-    public boolean isRepresentationClassByteBuffer() {
-        return java.nio.ByteBuffer.class.isAssignableFrom(representationClass);
-    }
-
-   /**
-    * Returns true if the representation class can be serialized.
-    * @return true if the representation class can be serialized
-    */
-
-    public boolean isRepresentationClassSerializable() {
-        return java.io.Serializable.class.isAssignableFrom(representationClass);
-    }
-
-   /**
-    * Returns true if the representation class is <code>Remote</code>.
-    * @return true if the representation class is <code>Remote</code>
-    */
-    public boolean isRepresentationClassRemote() {
-        return DataFlavorUtil.RMI.isRemote(representationClass);
-    }
-
-   /**
-    * Returns true if the <code>DataFlavor</code> specified represents
-    * a serialized object.
-    * @return true if the <code>DataFlavor</code> specified represents
-    *   a Serialized Object
-    */
-
-    public boolean isFlavorSerializedObjectType() {
-        return isRepresentationClassSerializable() && isMimeTypeEqual(javaSerializedObjectMimeType);
-    }
-
-    /**
-     * Returns true if the <code>DataFlavor</code> specified represents
-     * a remote object.
-     * @return true if the <code>DataFlavor</code> specified represents
-     *  a Remote Object
-     */
-
-    public boolean isFlavorRemoteObjectType() {
-        return isRepresentationClassRemote()
-            && isRepresentationClassSerializable()
-            && isMimeTypeEqual(javaRemoteObjectMimeType);
-    }
-
-
-   /**
-    * Returns true if the <code>DataFlavor</code> specified represents
-    * a list of file objects.
-    * @return true if the <code>DataFlavor</code> specified represents
-    *   a List of File objects
-    */
-
-   public boolean isFlavorJavaFileListType() {
-        if (mimeType == null || representationClass == null)
-            return false;
-        return java.util.List.class.isAssignableFrom(representationClass) &&
-               mimeType.match(javaFileListFlavor.mimeType);
-
-   }
-
-    /**
-     * Returns whether this <code>DataFlavor</code> is a valid text flavor for
-     * this implementation of the Java platform. Only flavors equivalent to
-     * <code>DataFlavor.stringFlavor</code> and <code>DataFlavor</code>s with
-     * a primary MIME type of "text" can be valid text flavors.
-     * <p>
-     * If this flavor supports the charset parameter, it must be equivalent to
-     * <code>DataFlavor.stringFlavor</code>, or its representation must be
-     * <code>java.io.Reader</code>, <code>java.lang.String</code>,
-     * <code>java.nio.CharBuffer</code>, <code>[C</code>,
-     * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>, or
-     * <code>[B</code>. If the representation is
-     * <code>java.io.InputStream</code>, <code>java.nio.ByteBuffer</code>, or
-     * <code>[B</code>, then this flavor's <code>charset</code> parameter must
-     * be supported by this implementation of the Java platform. If a charset
-     * is not specified, then the platform default charset, which is always
-     * supported, is assumed.
-     * <p>
-     * If this flavor does not support the charset parameter, its
-     * representation must be <code>java.io.InputStream</code>,
-     * <code>java.nio.ByteBuffer</code>, or <code>[B</code>.
-     * <p>
-     * See <code>selectBestTextFlavor</code> for a list of text flavors which
-     * support the charset parameter.
-     *
-     * @return <code>true</code> if this <code>DataFlavor</code> is a valid
-     *         text flavor as described above; <code>false</code> otherwise
-     * @see #selectBestTextFlavor
-     * @since 1.4
-     */
-    public boolean isFlavorTextType() {
-        return (DataFlavorUtil.isFlavorCharsetTextType(this) ||
-                DataFlavorUtil.isFlavorNoncharsetTextType(this));
-    }
-
-   /**
-    * Serializes this <code>DataFlavor</code>.
-    */
-
-   public synchronized void writeExternal(ObjectOutput os) throws IOException {
-       if (mimeType != null) {
-           mimeType.setParameter("humanPresentableName", humanPresentableName);
-           os.writeObject(mimeType);
-           mimeType.removeParameter("humanPresentableName");
-       } else {
-           os.writeObject(null);
-       }
-
-       os.writeObject(representationClass);
-   }
-
-   /**
-    * Restores this <code>DataFlavor</code> from a Serialized state.
-    */
-
-   public synchronized void readExternal(ObjectInput is) throws IOException , ClassNotFoundException {
-       String rcn = null;
-        mimeType = (MimeType)is.readObject();
-
-        if (mimeType != null) {
-            humanPresentableName =
-                mimeType.getParameter("humanPresentableName");
-            mimeType.removeParameter("humanPresentableName");
-            rcn = mimeType.getParameter("class");
-            if (rcn == null) {
-                throw new IOException("no class parameter specified in: " +
-                                      mimeType);
-            }
-        }
-
-        try {
-            representationClass = (Class)is.readObject();
-        } catch (OptionalDataException ode) {
-            if (!ode.eof || ode.length != 0) {
-                throw ode;
-            }
-            // Ensure backward compatibility.
-            // Old versions didn't write the representation class to the stream.
-            if (rcn != null) {
-                representationClass =
-                    DataFlavor.tryToLoadClass(rcn, getClass().getClassLoader());
-            }
-        }
-   }
-
-   /**
-    * Returns a clone of this <code>DataFlavor</code>.
-    * @return a clone of this <code>DataFlavor</code>
-    */
-
-    public Object clone() throws CloneNotSupportedException {
-        Object newObj = super.clone();
-        if (mimeType != null) {
-            ((DataFlavor)newObj).mimeType = (MimeType)mimeType.clone();
-        }
-        return newObj;
-    } // clone()
-
-   /**
-    * Called on <code>DataFlavor</code> for every MIME Type parameter
-    * to allow <code>DataFlavor</code> subclasses to handle special
-    * parameters like the text/plain <code>charset</code>
-    * parameters, whose values are case insensitive.  (MIME type parameter
-    * values are supposed to be case sensitive.
-    * <p>
-    * This method is called for each parameter name/value pair and should
-    * return the normalized representation of the <code>parameterValue</code>.
-    *
-    * This method is never invoked by this implementation from 1.1 onwards.
-    *
-    * @param parameterName the parameter name
-    * @param parameterValue the parameter value
-    * @return the parameter value
-    * @deprecated
-    */
-    @Deprecated
-    protected String normalizeMimeTypeParameter(String parameterName, String parameterValue) {
-        return parameterValue;
-    }
-
-   /**
-    * Called for each MIME type string to give <code>DataFlavor</code> subtypes
-    * the opportunity to change how the normalization of MIME types is
-    * accomplished.  One possible use would be to add default
-    * parameter/value pairs in cases where none are present in the MIME
-    * type string passed in.
-    *
-    * This method is never invoked by this implementation from 1.1 onwards.
-    *
-    * @param mimeType the mime type
-    * @return the mime type
-    * @deprecated
-    */
-    @Deprecated
-    protected String normalizeMimeType(String mimeType) {
-        return mimeType;
-    }
-
-    /*
-     * fields
-     */
-
-    /* placeholder for caching any platform-specific data for flavor */
-
-    transient int       atom;
-
-    /* Mime Type of DataFlavor */
-
-    MimeType            mimeType;
-
-    private String      humanPresentableName;
-
-    /** Java class of objects this DataFlavor represents **/
-
-    private Class<?>       representationClass;
-
-} // class DataFlavor
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/FlavorEvent.java	Tue Feb 17 10:48:24 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2003, 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.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.awt.datatransfer;
-
-import java.util.EventObject;
-
-
-/**
- * <code>FlavorEvent</code> is used to notify interested parties
- * that available {@link DataFlavor}s have changed in the
- * {@link Clipboard} (the event source).
- *
- * @see FlavorListener
- *
- * @author Alexander Gerasimov
- * @since 1.5
- */
-public class FlavorEvent extends EventObject {
-    private static final long serialVersionUID = -5842664112252414548L;
-
-    /**
-     * Constructs a <code>FlavorEvent</code> object.
-     *
-     * @param source  the <code>Clipboard</code> that is the source of the event
-     *
-     * @throws IllegalArgumentException if the {@code source} is {@code null}
-     */
-    public FlavorEvent(Clipboard source) {
-        super(source);
-    }
-}
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/FlavorListener.java	Tue Feb 17 10:48:24 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package java.awt.datatransfer;
-
-import java.util.EventListener;
-
-
-/**
- * Defines an object which listens for {@link FlavorEvent}s.
- *
- * @author Alexander Gerasimov
- * @since 1.5
- */
-public interface FlavorListener extends EventListener {
-    /**
-     * Invoked when the target {@link Clipboard} of the listener
-     * has changed its available {@link DataFlavor}s.
-     * <p>
-     * Some notifications may be redundant &#8212; they are not
-     * caused by a change of the set of DataFlavors available
-     * on the clipboard.
-     * For example, if the clipboard subsystem supposes that
-     * the system clipboard's contents has been changed but it
-     * can't ascertain whether its DataFlavors have been changed
-     * because of some exceptional condition when accessing the
-     * clipboard, the notification is sent to ensure from omitting
-     * a significant notification. Ordinarily, those redundant
-     * notifications should be occasional.
-     *
-     * @param e  a <code>FlavorEvent</code> object
-     */
-    void flavorsChanged(FlavorEvent e);
-}
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/FlavorMap.java	Tue Feb 17 10:48:24 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.awt.datatransfer;
-
-import java.util.Map;
-
-
-/**
- * A two-way Map between "natives" (Strings), which correspond to platform-
- * specific data formats, and "flavors" (DataFlavors), which correspond to
- * platform-independent MIME types. FlavorMaps need not be symmetric, but
- * typically are.
- *
- *
- * @since 1.2
- */
-public interface FlavorMap {
-
-    /**
-     * Returns a <code>Map</code> of the specified <code>DataFlavor</code>s to
-     * their corresponding <code>String</code> native. The returned
-     * <code>Map</code> is a modifiable copy of this <code>FlavorMap</code>'s
-     * internal data. Client code is free to modify the <code>Map</code>
-     * without affecting this object.
-     *
-     * @param flavors an array of <code>DataFlavor</code>s which will be the
-     *        key set of the returned <code>Map</code>. If <code>null</code> is
-     *        specified, a mapping of all <code>DataFlavor</code>s currently
-     *        known to this <code>FlavorMap</code> to their corresponding
-     *        <code>String</code> natives will be returned.
-     * @return a <code>java.util.Map</code> of <code>DataFlavor</code>s to
-     *         <code>String</code> natives
-     */
-    Map<DataFlavor,String> getNativesForFlavors(DataFlavor[] flavors);
-
-    /**
-     * Returns a <code>Map</code> of the specified <code>String</code> natives
-     * to their corresponding <code>DataFlavor</code>. The returned
-     * <code>Map</code> is a modifiable copy of this <code>FlavorMap</code>'s
-     * internal data. Client code is free to modify the <code>Map</code>
-     * without affecting this object.
-     *
-     * @param natives an array of <code>String</code>s which will be the
-     *        key set of the returned <code>Map</code>. If <code>null</code> is
-     *        specified, a mapping of all <code>String</code> natives currently
-     *        known to this <code>FlavorMap</code> to their corresponding
-     *        <code>DataFlavor</code>s will be returned.
-     * @return a <code>java.util.Map</code> of <code>String</code> natives to
-     *         <code>DataFlavor</code>s
-     */
-    Map<String,DataFlavor> getFlavorsForNatives(String[] natives);
-}
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/FlavorTable.java	Tue Feb 17 10:48:24 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.awt.datatransfer;
-
-import java.util.List;
-
-
-/**
- * A FlavorMap which relaxes the traditional 1-to-1 restriction of a Map. A
- * flavor is permitted to map to any number of natives, and likewise a native
- * is permitted to map to any number of flavors. FlavorTables need not be
- * symmetric, but typically are.
- *
- * @author David Mendenhall
- *
- * @since 1.4
- */
-public interface FlavorTable extends FlavorMap {
-
-    /**
-     * Returns a <code>List</code> of <code>String</code> natives to which the
-     * specified <code>DataFlavor</code> corresponds. The <code>List</code>
-     * will be sorted from best native to worst. That is, the first native will
-     * best reflect data in the specified flavor to the underlying native
-     * platform. The returned <code>List</code> is a modifiable copy of this
-     * <code>FlavorTable</code>'s internal data. Client code is free to modify
-     * the <code>List</code> without affecting this object.
-     *
-     * @param flav the <code>DataFlavor</code> whose corresponding natives
-     *        should be returned. If <code>null</code> is specified, all
-     *        natives currently known to this <code>FlavorTable</code> are
-     *        returned in a non-deterministic order.
-     * @return a <code>java.util.List</code> of <code>java.lang.String</code>
-     *         objects which are platform-specific representations of platform-
-     *         specific data formats
-     */
-    List<String> getNativesForFlavor(DataFlavor flav);
-
-    /**
-     * Returns a <code>List</code> of <code>DataFlavor</code>s to which the
-     * specified <code>String</code> corresponds. The <code>List</code> will be
-     * sorted from best <code>DataFlavor</code> to worst. That is, the first
-     * <code>DataFlavor</code> will best reflect data in the specified
-     * native to a Java application. The returned <code>List</code> is a
-     * modifiable copy of this <code>FlavorTable</code>'s internal data.
-     * Client code is free to modify the <code>List</code> without affecting
-     * this object.
-     *
-     * @param nat the native whose corresponding <code>DataFlavor</code>s
-     *        should be returned. If <code>null</code> is specified, all
-     *        <code>DataFlavor</code>s currently known to this
-     *        <code>FlavorTable</code> are returned in a non-deterministic
-     *        order.
-     * @return a <code>java.util.List</code> of <code>DataFlavor</code>
-     *         objects into which platform-specific data in the specified,
-     *         platform-specific native can be translated
-     */
-    List<DataFlavor> getFlavorsForNative(String nat);
-}
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/MimeType.java	Tue Feb 17 10:48:24 2015 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,394 +0,0 @@
-/*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.awt.datatransfer;
-
-import java.io.Externalizable;
-import java.io.ObjectOutput;
-import java.io.ObjectInput;
-import java.io.IOException;
-import java.util.Enumeration;
-import java.util.Locale;
-
-
-/**
- * A Multipurpose Internet Mail Extension (MIME) type, as defined
- * in RFC 2045 and 2046.
- *
- * THIS IS *NOT* - REPEAT *NOT* - A PUBLIC CLASS! DataFlavor IS
- * THE PUBLIC INTERFACE, AND THIS IS PROVIDED AS A ***PRIVATE***
- * (THAT IS AS IN *NOT* PUBLIC) HELPER CLASS!
- */
-class MimeType implements Externalizable, Cloneable {
-
-    /*
-     * serialization support
-     */
-
-    static final long serialVersionUID = -6568722458793895906L;
-
-    /**
-     * Constructor for externalization; this constructor should not be
-     * called directly by an application, since the result will be an
-     * uninitialized, immutable <code>MimeType</code> object.
-     */
-    public MimeType() {
-    }
-
-    /**
-     * Builds a <code>MimeType</code> from a <code>String</code>.
-     *
-     * @param rawdata text used to initialize the <code>MimeType</code>
-     * @throws NullPointerException if <code>rawdata</code> is null
-     */
-    public MimeType(String rawdata) throws MimeTypeParseException {
-        parse(rawdata);
-    }
-
-    /**
-     * Builds a <code>MimeType</code> with the given primary and sub
-     * type but has an empty parameter list.
-     *
-     * @param primary the primary type of this <code>MimeType</code>
-     * @param sub the subtype of this <code>MimeType</code>
-     * @throws NullPointerException if either <code>primary</code> or
-     *         <code>sub</code> is null
-     */
-    public MimeType(String primary, String sub) throws MimeTypeParseException {
-        this(primary, sub, new MimeTypeParameterList());
-    }
-
-    /**
-     * Builds a <code>MimeType</code> with a pre-defined
-     * and valid (or empty) parameter list.
-     *
-     * @param primary the primary type of this <code>MimeType</code>
-     * @param sub the subtype of this <code>MimeType</code>
-     * @param mtpl the requested parameter list
-     * @throws NullPointerException if either <code>primary</code>,
-     *         <code>sub</code> or <code>mtpl</code> is null
-     */
-    public MimeType(String primary, String sub, MimeTypeParameterList mtpl) throws
-MimeTypeParseException {
-        //    check to see if primary is valid
-        if(isValidToken(primary)) {
-            primaryType = primary.toLowerCase(Locale.ENGLISH);
-        } else {
-            throw new MimeTypeParseException("Primary type is invalid.");
-        }
-
-        //    check to see if sub is valid
-        if(isValidToken(sub)) {
-            subType = sub.toLowerCase(Locale.ENGLISH);
-        } else {
-            throw new MimeTypeParseException("Sub type is invalid.");
-        }
-
-        parameters = (MimeTypeParameterList)mtpl.clone();
-    }
-
-    public int hashCode() {
-
-        // We sum up the hash codes for all of the strings. This
-        // way, the order of the strings is irrelevant
-        int code = 0;
-        code += primaryType.hashCode();
-        code += subType.hashCode();
-        code += parameters.hashCode();
-        return code;
-    } // hashCode()
-
-    /**
-     * <code>MimeType</code>s are equal if their primary types,
-     * subtypes, and  parameters are all equal. No default values
-     * are taken into account.
-     * @param thatObject the object to be evaluated as a
-     *    <code>MimeType</code>
-     * @return <code>true</code> if <code>thatObject</code> is
-     *    a <code>MimeType</code>; otherwise returns <code>false</code>
-     */
-    public boolean equals(Object thatObject) {
-        if (!(thatObject instanceof MimeType)) {
-            return false;
-        }
-        MimeType that = (MimeType)thatObject;
-        boolean isIt =