8056298: Separate java.awt.datatransfer from the desktop module
authorserb
Fri, 16 Jan 2015 18:46:16 +0300
changeset 28987 a389d5a5bc45
parent 28986 79f293b29d6a
child 28988 5694c83d3060
8056298: Separate java.awt.datatransfer from the desktop module Reviewed-by: erikj, alanb, mchung, alexsch
jdk/make/src/classes/build/tools/module/boot.modules
jdk/src/java.datatransfer/macosx/classes/sun/datatransfer/resources/flavormap.properties
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/Clipboard.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/ClipboardOwner.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/FlavorEvent.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/FlavorListener.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/FlavorMap.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/FlavorTable.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/MimeType.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/MimeTypeParameterList.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/MimeTypeParseException.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/StringSelection.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/SystemFlavorMap.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/Transferable.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/UnsupportedFlavorException.java
jdk/src/java.datatransfer/share/classes/java/awt/datatransfer/package.html
jdk/src/java.datatransfer/share/classes/sun/datatransfer/DataFlavorUtil.java
jdk/src/java.datatransfer/share/classes/sun/datatransfer/DesktopDatatransferService.java
jdk/src/java.datatransfer/unix/classes/sun/datatransfer/resources/flavormap.properties
jdk/src/java.datatransfer/windows/classes/sun/datatransfer/resources/flavormap.properties
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/datatransfer/resources/flavormap.properties
jdk/src/java.desktop/windows/classes/sun/datatransfer/resources/flavormap.properties
--- a/jdk/make/src/classes/build/tools/module/boot.modules	Fri Jan 16 19:11:10 2015 +0400
+++ b/jdk/make/src/classes/build/tools/module/boot.modules	Fri Jan 16 18:46:16 2015 +0300
@@ -1,4 +1,5 @@
 java.base
+java.datatransfer
 java.desktop
 java.activation
 java.annotations.common
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.datatransfer/macosx/classes/sun/datatransfer/resources/flavormap.properties	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -0,0 +1,1094 @@
+/*
+ * Copyright (c) 1997, 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.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).replaceAll("\\ ", " ");
+                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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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	Fri Jan 16 18:46:16 2015 +0300
@@ -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/sun/datatransfer/resources/flavormap.properties	Fri Jan 16 19:11:10 2015 +0400
+++ /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/share/classes/java/awt/datatransfer/Clipboard.java	Fri Jan 16 19:11:10 2015 +0400
+++ /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	Fri Jan 16 19:11:10 2015 +0400
+++ /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	Fri Jan 16 19:11:10 2015 +0400
+++ /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	Fri Jan 16 19:11:10 2015 +0400
+++ /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	Fri Jan 16 19:11:10 2015 +0400
+++ /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	Fri Jan 16 19:11:10 2015 +0400
+++ /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	Fri Jan 16 19:11:10 2015 +0400
+++ /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	Fri Jan 16 19:11:10 2015 +0400
+++ /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 =
-            ((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
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/MimeTypeParameterList.java	Fri Jan 16 19:11:10 2015 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,404 +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.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 = "()<>@,;:\\\"/[]?=";
-
-}
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/MimeTypeParseException.java	Fri Jan 16 19:11:10 2015 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * 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
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/StringSelection.java	Fri Jan 16 19:11:10 2015 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +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 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) {
-    }
-}
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/SystemFlavorMap.java	Fri Jan 16 19:11:10 2015 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1094 +0,0 @@
-/*
- * Copyright (c) 1997, 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.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).replaceAll("\\ ", " ");
-                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;
-        }
-    }
-}
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/Transferable.java	Fri Jan 16 19:11:10 2015 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +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 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;
-
-}
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/UnsupportedFlavorException.java	Fri Jan 16 19:11:10 2015 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * 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);
-    }
-}
--- a/jdk/src/java.desktop/share/classes/java/awt/datatransfer/package.html	Fri Jan 16 19:11:10 2015 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-<!--
- 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>
--- a/jdk/src/java.desktop/share/classes/sun/datatransfer/DataFlavorUtil.java	Fri Jan 16 19:11:10 2015 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,841 +0,0 @@
-/*
- * 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);
-            }
-        }
-
-    }
-}
--- a/jdk/src/java.desktop/share/classes/sun/datatransfer/DesktopDatatransferService.java	Fri Jan 16 19:11:10 2015 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/*
- * 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);
-}
--- a/jdk/src/java.desktop/unix/classes/sun/datatransfer/resources/flavormap.properties	Fri Jan 16 19:11:10 2015 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# 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
--- a/jdk/src/java.desktop/windows/classes/sun/datatransfer/resources/flavormap.properties	Fri Jan 16 19:11:10 2015 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-#
-# 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