Automatic sources dropoff on 2020-06-10 18:32:38.095721

The change is generated with prebuilt drop tool.

Change-Id: I24cbf6ba6db262a1ae1445db1427a08fee35b3b4
diff --git a/java/nio/Bits.java b/java/nio/Bits.java
new file mode 100644
index 0000000..56cb80b
--- /dev/null
+++ b/java/nio/Bits.java
@@ -0,0 +1,881 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import java.security.AccessController;
+
+import sun.misc.Unsafe;
+import sun.misc.VM;
+
+/**
+ * Access to bits, native and otherwise.
+ */
+
+class Bits {                            // package-private
+
+    private Bits() { }
+
+
+    // -- Swapping --
+
+    static short swap(short x) {
+        return Short.reverseBytes(x);
+    }
+
+    static char swap(char x) {
+        return Character.reverseBytes(x);
+    }
+
+    static int swap(int x) {
+        return Integer.reverseBytes(x);
+    }
+
+    static long swap(long x) {
+        return Long.reverseBytes(x);
+    }
+
+
+    // -- get/put char --
+
+    static private char makeChar(byte b1, byte b0) {
+        return (char)((b1 << 8) | (b0 & 0xff));
+    }
+
+    static char getCharL(ByteBuffer bb, int bi) {
+        return makeChar(bb._get(bi + 1),
+                        bb._get(bi    ));
+    }
+
+    static char getCharL(long a) {
+        return makeChar(_get(a + 1),
+                        _get(a    ));
+    }
+
+    static char getCharB(ByteBuffer bb, int bi) {
+        return makeChar(bb._get(bi    ),
+                        bb._get(bi + 1));
+    }
+
+    static char getCharB(long a) {
+        return makeChar(_get(a    ),
+                        _get(a + 1));
+    }
+
+    static char getChar(ByteBuffer bb, int bi, boolean bigEndian) {
+        return bigEndian ? getCharB(bb, bi) : getCharL(bb, bi);
+    }
+
+    static char getChar(long a, boolean bigEndian) {
+        return bigEndian ? getCharB(a) : getCharL(a);
+    }
+
+    private static byte char1(char x) { return (byte)(x >> 8); }
+    private static byte char0(char x) { return (byte)(x     ); }
+
+    static void putCharL(ByteBuffer bb, int bi, char x) {
+        bb._put(bi    , char0(x));
+        bb._put(bi + 1, char1(x));
+    }
+
+    static void putCharL(long a, char x) {
+        _put(a    , char0(x));
+        _put(a + 1, char1(x));
+    }
+
+    static void putCharB(ByteBuffer bb, int bi, char x) {
+        bb._put(bi    , char1(x));
+        bb._put(bi + 1, char0(x));
+    }
+
+    static void putCharB(long a, char x) {
+        _put(a    , char1(x));
+        _put(a + 1, char0(x));
+    }
+
+    static void putChar(ByteBuffer bb, int bi, char x, boolean bigEndian) {
+        if (bigEndian)
+            putCharB(bb, bi, x);
+        else
+            putCharL(bb, bi, x);
+    }
+
+    static void putChar(long a, char x, boolean bigEndian) {
+        if (bigEndian)
+            putCharB(a, x);
+        else
+            putCharL(a, x);
+    }
+
+
+    // -- get/put short --
+
+    static private short makeShort(byte b1, byte b0) {
+        return (short)((b1 << 8) | (b0 & 0xff));
+    }
+
+    static short getShortL(ByteBuffer bb, int bi) {
+        return makeShort(bb._get(bi + 1),
+                         bb._get(bi    ));
+    }
+
+    static short getShortL(long a) {
+        return makeShort(_get(a + 1),
+                         _get(a    ));
+    }
+
+    static short getShortB(ByteBuffer bb, int bi) {
+        return makeShort(bb._get(bi    ),
+                         bb._get(bi + 1));
+    }
+
+    static short getShortB(long a) {
+        return makeShort(_get(a    ),
+                         _get(a + 1));
+    }
+
+    static short getShort(ByteBuffer bb, int bi, boolean bigEndian) {
+        return bigEndian ? getShortB(bb, bi) : getShortL(bb, bi);
+    }
+
+    static short getShort(long a, boolean bigEndian) {
+        return bigEndian ? getShortB(a) : getShortL(a);
+    }
+
+    private static byte short1(short x) { return (byte)(x >> 8); }
+    private static byte short0(short x) { return (byte)(x     ); }
+
+    static void putShortL(ByteBuffer bb, int bi, short x) {
+        bb._put(bi    , short0(x));
+        bb._put(bi + 1, short1(x));
+    }
+
+    static void putShortL(long a, short x) {
+        _put(a    , short0(x));
+        _put(a + 1, short1(x));
+    }
+
+    static void putShortB(ByteBuffer bb, int bi, short x) {
+        bb._put(bi    , short1(x));
+        bb._put(bi + 1, short0(x));
+    }
+
+    static void putShortB(long a, short x) {
+        _put(a    , short1(x));
+        _put(a + 1, short0(x));
+    }
+
+    static void putShort(ByteBuffer bb, int bi, short x, boolean bigEndian) {
+        if (bigEndian)
+            putShortB(bb, bi, x);
+        else
+            putShortL(bb, bi, x);
+    }
+
+    static void putShort(long a, short x, boolean bigEndian) {
+        if (bigEndian)
+            putShortB(a, x);
+        else
+            putShortL(a, x);
+    }
+
+
+    // -- get/put int --
+
+    static private int makeInt(byte b3, byte b2, byte b1, byte b0) {
+        return (((b3       ) << 24) |
+                ((b2 & 0xff) << 16) |
+                ((b1 & 0xff) <<  8) |
+                ((b0 & 0xff)      ));
+    }
+
+    static int getIntL(ByteBuffer bb, int bi) {
+        return makeInt(bb._get(bi + 3),
+                       bb._get(bi + 2),
+                       bb._get(bi + 1),
+                       bb._get(bi    ));
+    }
+
+    static int getIntL(long a) {
+        return makeInt(_get(a + 3),
+                       _get(a + 2),
+                       _get(a + 1),
+                       _get(a    ));
+    }
+
+    static int getIntB(ByteBuffer bb, int bi) {
+        return makeInt(bb._get(bi    ),
+                       bb._get(bi + 1),
+                       bb._get(bi + 2),
+                       bb._get(bi + 3));
+    }
+
+    static int getIntB(long a) {
+        return makeInt(_get(a    ),
+                       _get(a + 1),
+                       _get(a + 2),
+                       _get(a + 3));
+    }
+
+    static int getInt(ByteBuffer bb, int bi, boolean bigEndian) {
+        return bigEndian ? getIntB(bb, bi) : getIntL(bb, bi) ;
+    }
+
+    static int getInt(long a, boolean bigEndian) {
+        return bigEndian ? getIntB(a) : getIntL(a) ;
+    }
+
+    private static byte int3(int x) { return (byte)(x >> 24); }
+    private static byte int2(int x) { return (byte)(x >> 16); }
+    private static byte int1(int x) { return (byte)(x >>  8); }
+    private static byte int0(int x) { return (byte)(x      ); }
+
+    static void putIntL(ByteBuffer bb, int bi, int x) {
+        bb._put(bi + 3, int3(x));
+        bb._put(bi + 2, int2(x));
+        bb._put(bi + 1, int1(x));
+        bb._put(bi    , int0(x));
+    }
+
+    static void putIntL(long a, int x) {
+        _put(a + 3, int3(x));
+        _put(a + 2, int2(x));
+        _put(a + 1, int1(x));
+        _put(a    , int0(x));
+    }
+
+    static void putIntB(ByteBuffer bb, int bi, int x) {
+        bb._put(bi    , int3(x));
+        bb._put(bi + 1, int2(x));
+        bb._put(bi + 2, int1(x));
+        bb._put(bi + 3, int0(x));
+    }
+
+    static void putIntB(long a, int x) {
+        _put(a    , int3(x));
+        _put(a + 1, int2(x));
+        _put(a + 2, int1(x));
+        _put(a + 3, int0(x));
+    }
+
+    static void putInt(ByteBuffer bb, int bi, int x, boolean bigEndian) {
+        if (bigEndian)
+            putIntB(bb, bi, x);
+        else
+            putIntL(bb, bi, x);
+    }
+
+    static void putInt(long a, int x, boolean bigEndian) {
+        if (bigEndian)
+            putIntB(a, x);
+        else
+            putIntL(a, x);
+    }
+
+
+    // -- get/put long --
+
+    static private long makeLong(byte b7, byte b6, byte b5, byte b4,
+                                 byte b3, byte b2, byte b1, byte b0)
+    {
+        return ((((long)b7       ) << 56) |
+                (((long)b6 & 0xff) << 48) |
+                (((long)b5 & 0xff) << 40) |
+                (((long)b4 & 0xff) << 32) |
+                (((long)b3 & 0xff) << 24) |
+                (((long)b2 & 0xff) << 16) |
+                (((long)b1 & 0xff) <<  8) |
+                (((long)b0 & 0xff)      ));
+    }
+
+    static long getLongL(ByteBuffer bb, int bi) {
+        return makeLong(bb._get(bi + 7),
+                        bb._get(bi + 6),
+                        bb._get(bi + 5),
+                        bb._get(bi + 4),
+                        bb._get(bi + 3),
+                        bb._get(bi + 2),
+                        bb._get(bi + 1),
+                        bb._get(bi    ));
+    }
+
+    static long getLongL(long a) {
+        return makeLong(_get(a + 7),
+                        _get(a + 6),
+                        _get(a + 5),
+                        _get(a + 4),
+                        _get(a + 3),
+                        _get(a + 2),
+                        _get(a + 1),
+                        _get(a    ));
+    }
+
+    static long getLongB(ByteBuffer bb, int bi) {
+        return makeLong(bb._get(bi    ),
+                        bb._get(bi + 1),
+                        bb._get(bi + 2),
+                        bb._get(bi + 3),
+                        bb._get(bi + 4),
+                        bb._get(bi + 5),
+                        bb._get(bi + 6),
+                        bb._get(bi + 7));
+    }
+
+    static long getLongB(long a) {
+        return makeLong(_get(a    ),
+                        _get(a + 1),
+                        _get(a + 2),
+                        _get(a + 3),
+                        _get(a + 4),
+                        _get(a + 5),
+                        _get(a + 6),
+                        _get(a + 7));
+    }
+
+    static long getLong(ByteBuffer bb, int bi, boolean bigEndian) {
+        return bigEndian ? getLongB(bb, bi) : getLongL(bb, bi);
+    }
+
+    static long getLong(long a, boolean bigEndian) {
+        return bigEndian ? getLongB(a) : getLongL(a);
+    }
+
+    private static byte long7(long x) { return (byte)(x >> 56); }
+    private static byte long6(long x) { return (byte)(x >> 48); }
+    private static byte long5(long x) { return (byte)(x >> 40); }
+    private static byte long4(long x) { return (byte)(x >> 32); }
+    private static byte long3(long x) { return (byte)(x >> 24); }
+    private static byte long2(long x) { return (byte)(x >> 16); }
+    private static byte long1(long x) { return (byte)(x >>  8); }
+    private static byte long0(long x) { return (byte)(x      ); }
+
+    static void putLongL(ByteBuffer bb, int bi, long x) {
+        bb._put(bi + 7, long7(x));
+        bb._put(bi + 6, long6(x));
+        bb._put(bi + 5, long5(x));
+        bb._put(bi + 4, long4(x));
+        bb._put(bi + 3, long3(x));
+        bb._put(bi + 2, long2(x));
+        bb._put(bi + 1, long1(x));
+        bb._put(bi    , long0(x));
+    }
+
+    static void putLongL(long a, long x) {
+        _put(a + 7, long7(x));
+        _put(a + 6, long6(x));
+        _put(a + 5, long5(x));
+        _put(a + 4, long4(x));
+        _put(a + 3, long3(x));
+        _put(a + 2, long2(x));
+        _put(a + 1, long1(x));
+        _put(a    , long0(x));
+    }
+
+    static void putLongB(ByteBuffer bb, int bi, long x) {
+        bb._put(bi    , long7(x));
+        bb._put(bi + 1, long6(x));
+        bb._put(bi + 2, long5(x));
+        bb._put(bi + 3, long4(x));
+        bb._put(bi + 4, long3(x));
+        bb._put(bi + 5, long2(x));
+        bb._put(bi + 6, long1(x));
+        bb._put(bi + 7, long0(x));
+    }
+
+    static void putLongB(long a, long x) {
+        _put(a    , long7(x));
+        _put(a + 1, long6(x));
+        _put(a + 2, long5(x));
+        _put(a + 3, long4(x));
+        _put(a + 4, long3(x));
+        _put(a + 5, long2(x));
+        _put(a + 6, long1(x));
+        _put(a + 7, long0(x));
+    }
+
+    static void putLong(ByteBuffer bb, int bi, long x, boolean bigEndian) {
+        if (bigEndian)
+            putLongB(bb, bi, x);
+        else
+            putLongL(bb, bi, x);
+    }
+
+    static void putLong(long a, long x, boolean bigEndian) {
+        if (bigEndian)
+            putLongB(a, x);
+        else
+            putLongL(a, x);
+    }
+
+
+    // -- get/put float --
+
+    static float getFloatL(ByteBuffer bb, int bi) {
+        return Float.intBitsToFloat(getIntL(bb, bi));
+    }
+
+    static float getFloatL(long a) {
+        return Float.intBitsToFloat(getIntL(a));
+    }
+
+    static float getFloatB(ByteBuffer bb, int bi) {
+        return Float.intBitsToFloat(getIntB(bb, bi));
+    }
+
+    static float getFloatB(long a) {
+        return Float.intBitsToFloat(getIntB(a));
+    }
+
+    static float getFloat(ByteBuffer bb, int bi, boolean bigEndian) {
+        return bigEndian ? getFloatB(bb, bi) : getFloatL(bb, bi);
+    }
+
+    static float getFloat(long a, boolean bigEndian) {
+        return bigEndian ? getFloatB(a) : getFloatL(a);
+    }
+
+    static void putFloatL(ByteBuffer bb, int bi, float x) {
+        putIntL(bb, bi, Float.floatToRawIntBits(x));
+    }
+
+    static void putFloatL(long a, float x) {
+        putIntL(a, Float.floatToRawIntBits(x));
+    }
+
+    static void putFloatB(ByteBuffer bb, int bi, float x) {
+        putIntB(bb, bi, Float.floatToRawIntBits(x));
+    }
+
+    static void putFloatB(long a, float x) {
+        putIntB(a, Float.floatToRawIntBits(x));
+    }
+
+    static void putFloat(ByteBuffer bb, int bi, float x, boolean bigEndian) {
+        if (bigEndian)
+            putFloatB(bb, bi, x);
+        else
+            putFloatL(bb, bi, x);
+    }
+
+    static void putFloat(long a, float x, boolean bigEndian) {
+        if (bigEndian)
+            putFloatB(a, x);
+        else
+            putFloatL(a, x);
+    }
+
+
+    // -- get/put double --
+
+    static double getDoubleL(ByteBuffer bb, int bi) {
+        return Double.longBitsToDouble(getLongL(bb, bi));
+    }
+
+    static double getDoubleL(long a) {
+        return Double.longBitsToDouble(getLongL(a));
+    }
+
+    static double getDoubleB(ByteBuffer bb, int bi) {
+        return Double.longBitsToDouble(getLongB(bb, bi));
+    }
+
+    static double getDoubleB(long a) {
+        return Double.longBitsToDouble(getLongB(a));
+    }
+
+    static double getDouble(ByteBuffer bb, int bi, boolean bigEndian) {
+        return bigEndian ? getDoubleB(bb, bi) : getDoubleL(bb, bi);
+    }
+
+    static double getDouble(long a, boolean bigEndian) {
+        return bigEndian ? getDoubleB(a) : getDoubleL(a);
+    }
+
+    static void putDoubleL(ByteBuffer bb, int bi, double x) {
+        putLongL(bb, bi, Double.doubleToRawLongBits(x));
+    }
+
+    static void putDoubleL(long a, double x) {
+        putLongL(a, Double.doubleToRawLongBits(x));
+    }
+
+    static void putDoubleB(ByteBuffer bb, int bi, double x) {
+        putLongB(bb, bi, Double.doubleToRawLongBits(x));
+    }
+
+    static void putDoubleB(long a, double x) {
+        putLongB(a, Double.doubleToRawLongBits(x));
+    }
+
+    static void putDouble(ByteBuffer bb, int bi, double x, boolean bigEndian) {
+        if (bigEndian)
+            putDoubleB(bb, bi, x);
+        else
+            putDoubleL(bb, bi, x);
+    }
+
+    static void putDouble(long a, double x, boolean bigEndian) {
+        if (bigEndian)
+            putDoubleB(a, x);
+        else
+            putDoubleL(a, x);
+    }
+
+
+    // -- Unsafe access --
+
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+
+    private static byte _get(long a) {
+        return unsafe.getByte(a);
+    }
+
+    private static void _put(long a, byte b) {
+        unsafe.putByte(a, b);
+    }
+
+    static Unsafe unsafe() {
+        return unsafe;
+    }
+
+
+    // -- Processor and memory-system properties --
+
+    private static final ByteOrder byteOrder;
+
+    static ByteOrder byteOrder() {
+        // Android-removed: Android is always little-endian.
+        /*
+        if (byteOrder == null)
+            throw new Error("Unknown byte order");
+        */
+        return byteOrder;
+    }
+
+    static {
+        // BEGIN Android-changed: Android is always little-endian.
+        /*
+        long a = unsafe.allocateMemory(8);
+        try {
+            unsafe.putLong(a, 0x0102030405060708L);
+            byte b = unsafe.getByte(a);
+            switch (b) {
+            case 0x01: byteOrder = ByteOrder.BIG_ENDIAN;     break;
+            case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN;  break;
+            default:
+                assert false;
+                byteOrder = null;
+            }
+        } finally {
+            unsafe.freeMemory(a);
+        }
+        */
+        byteOrder = ByteOrder.LITTLE_ENDIAN;
+        // END Android-changed: Android is always little-endian.
+    }
+
+
+    private static int pageSize = -1;
+
+    static int pageSize() {
+        if (pageSize == -1)
+            pageSize = unsafe().pageSize();
+        return pageSize;
+    }
+
+    static int pageCount(long size) {
+        return (int)(size + (long)pageSize() - 1L) / pageSize();
+    }
+
+    private static boolean unaligned;
+    private static boolean unalignedKnown = false;
+
+    static boolean unaligned() {
+        if (unalignedKnown)
+            return unaligned;
+        String arch = AccessController.doPrivileged(
+            new sun.security.action.GetPropertyAction("os.arch"));
+        unaligned = arch.equals("i386") || arch.equals("x86")
+            || arch.equals("amd64") || arch.equals("x86_64");
+        unalignedKnown = true;
+        return unaligned;
+    }
+
+
+    // -- Direct memory management --
+
+    // BEGIN Android-removed: Direct memory management unused on Android.
+    /*
+    // A user-settable upper limit on the maximum amount of allocatable
+    // direct buffer memory.  This value may be changed during VM
+    // initialization if it is launched with "-XX:MaxDirectMemorySize=<size>".
+    private static volatile long maxMemory = VM.maxDirectMemory();
+    private static final AtomicLong reservedMemory = new AtomicLong();
+    private static final AtomicLong totalCapacity = new AtomicLong();
+    private static final AtomicLong count = new AtomicLong();
+    private static volatile boolean memoryLimitSet = false;
+    // max. number of sleeps during try-reserving with exponentially
+    // increasing delay before throwing OutOfMemoryError:
+    // 1, 2, 4, 8, 16, 32, 64, 128, 256 (total 511 ms ~ 0.5 s)
+    // which means that OOME will be thrown after 0.5 s of trying
+    private static final int MAX_SLEEPS = 9;
+
+    // These methods should be called whenever direct memory is allocated or
+    // freed.  They allow the user to control the amount of direct memory
+    // which a process may access.  All sizes are specified in bytes.
+    static void reserveMemory(long size, int cap) {
+
+        if (!memoryLimitSet && VM.isBooted()) {
+            maxMemory = VM.maxDirectMemory();
+            memoryLimitSet = true;
+        }
+
+        // optimist!
+        if (tryReserveMemory(size, cap)) {
+            return;
+        }
+
+        final JavaLangRefAccess jlra = SharedSecrets.getJavaLangRefAccess();
+
+        // retry while helping enqueue pending Reference objects
+        // which includes executing pending Cleaner(s) which includes
+        // Cleaner(s) that free direct buffer memory
+        while (jlra.tryHandlePendingReference()) {
+            if (tryReserveMemory(size, cap)) {
+                return;
+            }
+        }
+
+        // trigger VM's Reference processing
+        System.gc();
+
+        // a retry loop with exponential back-off delays
+        // (this gives VM some time to do it's job)
+        boolean interrupted = false;
+        try {
+            long sleepTime = 1;
+            int sleeps = 0;
+            while (true) {
+                if (tryReserveMemory(size, cap)) {
+                    return;
+                }
+                if (sleeps >= MAX_SLEEPS) {
+                    break;
+                }
+                if (!jlra.tryHandlePendingReference()) {
+                    try {
+                        Thread.sleep(sleepTime);
+                        sleepTime <<= 1;
+                        sleeps++;
+                    } catch (InterruptedException e) {
+                        interrupted = true;
+                    }
+                }
+            }
+
+            // no luck
+            throw new OutOfMemoryError("Direct buffer memory");
+
+        } finally {
+            if (interrupted) {
+                // don't swallow interrupts
+                Thread.currentThread().interrupt();
+            }
+        }
+    }
+
+    private static boolean tryReserveMemory(long size, int cap) {
+
+        // -XX:MaxDirectMemorySize limits the total capacity rather than the
+        // actual memory usage, which will differ when buffers are page
+        // aligned.
+        long totalCap;
+        while (cap <= maxMemory - (totalCap = totalCapacity.get())) {
+            if (totalCapacity.compareAndSet(totalCap, totalCap + cap)) {
+                reservedMemory.addAndGet(size);
+                count.incrementAndGet();
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+
+    static void unreserveMemory(long size, int cap) {
+        long cnt = count.decrementAndGet();
+        long reservedMem = reservedMemory.addAndGet(-size);
+        long totalCap = totalCapacity.addAndGet(-cap);
+        assert cnt >= 0 && reservedMem >= 0 && totalCap >= 0;
+    }
+    */
+    // END Android-removed: Direct memory management unused on Android.
+
+    // -- Monitoring of direct buffer usage --
+
+    // BEGIN Android-removed: Remove support for java.lang.management.
+    /*
+    static {
+        // setup access to this package in SharedSecrets
+        sun.misc.SharedSecrets.setJavaNioAccess(
+            new sun.misc.JavaNioAccess() {
+                @Override
+                public sun.misc.JavaNioAccess.BufferPool getDirectBufferPool() {
+                    return new sun.misc.JavaNioAccess.BufferPool() {
+                        @Override
+                        public String getName() {
+                            return "direct";
+                        }
+                        @Override
+                        public long getCount() {
+                            return Bits.count.get();
+                        }
+                        @Override
+                        public long getTotalCapacity() {
+                            return Bits.totalCapacity.get();
+                        }
+                        @Override
+                        public long getMemoryUsed() {
+                            return Bits.reservedMemory.get();
+                        }
+                    };
+                }
+                @Override
+                public ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob) {
+                    return new DirectByteBuffer(addr, cap, ob);
+                }
+                @Override
+                public void truncate(Buffer buf) {
+                    buf.truncate();
+                }
+        });
+    }
+    */
+    // END Android-removed: Remove support for java.lang.management.
+
+    // BEGIN Android-removed: Bulk get/put methods are unused on Android.
+    /*
+
+    // -- Bulk get/put acceleration --
+
+    // These numbers represent the point at which we have empirically
+    // determined that the average cost of a JNI call exceeds the expense
+    // of an element by element copy.  These numbers may change over time.
+    static final int JNI_COPY_TO_ARRAY_THRESHOLD   = 6;
+    static final int JNI_COPY_FROM_ARRAY_THRESHOLD = 6;
+
+    // This number limits the number of bytes to copy per call to Unsafe's
+    // copyMemory method. A limit is imposed to allow for safepoint polling
+    // during a large copy
+    static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
+
+    // These methods do no bounds checking.  Verification that the copy will not
+    // result in memory corruption should be done prior to invocation.
+    // All positions and lengths are specified in bytes.
+
+    /**
+     * Copy from given source array to destination address.
+     *
+     * @param   src
+     *          source array
+     * @param   srcBaseOffset
+     *          offset of first element of storage in source array
+     * @param   srcPos
+     *          offset within source array of the first element to read
+     * @param   dstAddr
+     *          destination address
+     * @param   length
+     *          number of bytes to copy
+     *
+    static void copyFromArray(Object src, long srcBaseOffset, long srcPos,
+                              long dstAddr, long length)
+    {
+        long offset = srcBaseOffset + srcPos;
+        while (length > 0) {
+            long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
+            unsafe.copyMemory(src, offset, null, dstAddr, size);
+            length -= size;
+            offset += size;
+            dstAddr += size;
+        }
+    }
+
+    /**
+     * Copy from source address into given destination array.
+     *
+     * @param   srcAddr
+     *          source address
+     * @param   dst
+     *          destination array
+     * @param   dstBaseOffset
+     *          offset of first element of storage in destination array
+     * @param   dstPos
+     *          offset within destination array of the first element to write
+     * @param   length
+     *          number of bytes to copy
+     *
+    static void copyToArray(long srcAddr, Object dst, long dstBaseOffset, long dstPos,
+                            long length)
+    {
+        long offset = dstBaseOffset + dstPos;
+        while (length > 0) {
+            long size = (length > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : length;
+            unsafe.copyMemory(null, srcAddr, dst, offset, size);
+            length -= size;
+            srcAddr += size;
+            offset += size;
+        }
+    }
+
+    static void copyFromCharArray(Object src, long srcPos, long dstAddr,
+                                  long length)
+    {
+        copyFromShortArray(src, srcPos, dstAddr, length);
+    }
+
+    static void copyToCharArray(long srcAddr, Object dst, long dstPos,
+                                long length)
+    {
+        copyToShortArray(srcAddr, dst, dstPos, length);
+    }
+
+    static native void copyFromShortArray(Object src, long srcPos, long dstAddr,
+                                          long length);
+    static native void copyToShortArray(long srcAddr, Object dst, long dstPos,
+                                        long length);
+
+    static native void copyFromIntArray(Object src, long srcPos, long dstAddr,
+                                        long length);
+    static native void copyToIntArray(long srcAddr, Object dst, long dstPos,
+                                      long length);
+
+    static native void copyFromLongArray(Object src, long srcPos, long dstAddr,
+                                         long length);
+    static native void copyToLongArray(long srcAddr, Object dst, long dstPos,
+                                       long length);
+    */
+    // END Android-removed: Bulk get/put methods are unused on Android.
+}
diff --git a/java/nio/Buffer.java b/java/nio/Buffer.java
new file mode 100644
index 0000000..e517560
--- /dev/null
+++ b/java/nio/Buffer.java
@@ -0,0 +1,601 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio;
+
+import java.util.Spliterator;
+
+/**
+ * A container for data of a specific primitive type.
+ *
+ * <p> A buffer is a linear, finite sequence of elements of a specific
+ * primitive type.  Aside from its content, the essential properties of a
+ * buffer are its capacity, limit, and position: </p>
+ *
+ * <blockquote>
+ *
+ *   <p> A buffer's <i>capacity</i> is the number of elements it contains.  The
+ *   capacity of a buffer is never negative and never changes.  </p>
+ *
+ *   <p> A buffer's <i>limit</i> is the index of the first element that should
+ *   not be read or written.  A buffer's limit is never negative and is never
+ *   greater than its capacity.  </p>
+ *
+ *   <p> A buffer's <i>position</i> is the index of the next element to be
+ *   read or written.  A buffer's position is never negative and is never
+ *   greater than its limit.  </p>
+ *
+ * </blockquote>
+ *
+ * <p> There is one subclass of this class for each non-boolean primitive type.
+ *
+ *
+ * <h2> Transferring data </h2>
+ *
+ * <p> Each subclass of this class defines two categories of <i>get</i> and
+ * <i>put</i> operations: </p>
+ *
+ * <blockquote>
+ *
+ *   <p> <i>Relative</i> operations read or write one or more elements starting
+ *   at the current position and then increment the position by the number of
+ *   elements transferred.  If the requested transfer exceeds the limit then a
+ *   relative <i>get</i> operation throws a {@link BufferUnderflowException}
+ *   and a relative <i>put</i> operation throws a {@link
+ *   BufferOverflowException}; in either case, no data is transferred.  </p>
+ *
+ *   <p> <i>Absolute</i> operations take an explicit element index and do not
+ *   affect the position.  Absolute <i>get</i> and <i>put</i> operations throw
+ *   an {@link IndexOutOfBoundsException} if the index argument exceeds the
+ *   limit.  </p>
+ *
+ * </blockquote>
+ *
+ * <p> Data may also, of course, be transferred in to or out of a buffer by the
+ * I/O operations of an appropriate channel, which are always relative to the
+ * current position.
+ *
+ *
+ * <h2> Marking and resetting </h2>
+ *
+ * <p> A buffer's <i>mark</i> is the index to which its position will be reset
+ * when the {@link #reset reset} method is invoked.  The mark is not always
+ * defined, but when it is defined it is never negative and is never greater
+ * than the position.  If the mark is defined then it is discarded when the
+ * position or the limit is adjusted to a value smaller than the mark.  If the
+ * mark is not defined then invoking the {@link #reset reset} method causes an
+ * {@link InvalidMarkException} to be thrown.
+ *
+ *
+ * <h2> Invariants </h2>
+ *
+ * <p> The following invariant holds for the mark, position, limit, and
+ * capacity values:
+ *
+ * <blockquote>
+ *     <tt>0</tt> <tt>&lt;=</tt>
+ *     <i>mark</i> <tt>&lt;=</tt>
+ *     <i>position</i> <tt>&lt;=</tt>
+ *     <i>limit</i> <tt>&lt;=</tt>
+ *     <i>capacity</i>
+ * </blockquote>
+ *
+ * <p> A newly-created buffer always has a position of zero and a mark that is
+ * undefined.  The initial limit may be zero, or it may be some other value
+ * that depends upon the type of the buffer and the manner in which it is
+ * constructed.  Each element of a newly-allocated buffer is initialized
+ * to zero.
+ *
+ *
+ * <h2> Clearing, flipping, and rewinding </h2>
+ *
+ * <p> In addition to methods for accessing the position, limit, and capacity
+ * values and for marking and resetting, this class also defines the following
+ * operations upon buffers:
+ *
+ * <ul>
+ *
+ *   <li><p> {@link #clear} makes a buffer ready for a new sequence of
+ *   channel-read or relative <i>put</i> operations: It sets the limit to the
+ *   capacity and the position to zero.  </p></li>
+ *
+ *   <li><p> {@link #flip} makes a buffer ready for a new sequence of
+ *   channel-write or relative <i>get</i> operations: It sets the limit to the
+ *   current position and then sets the position to zero.  </p></li>
+ *
+ *   <li><p> {@link #rewind} makes a buffer ready for re-reading the data that
+ *   it already contains: It leaves the limit unchanged and sets the position
+ *   to zero.  </p></li>
+ *
+ * </ul>
+ *
+ *
+ * <h2> Read-only buffers </h2>
+ *
+ * <p> Every buffer is readable, but not every buffer is writable.  The
+ * mutation methods of each buffer class are specified as <i>optional
+ * operations</i> that will throw a {@link ReadOnlyBufferException} when
+ * invoked upon a read-only buffer.  A read-only buffer does not allow its
+ * content to be changed, but its mark, position, and limit values are mutable.
+ * Whether or not a buffer is read-only may be determined by invoking its
+ * {@link #isReadOnly isReadOnly} method.
+ *
+ *
+ * <h2> Thread safety </h2>
+ *
+ * <p> Buffers are not safe for use by multiple concurrent threads.  If a
+ * buffer is to be used by more than one thread then access to the buffer
+ * should be controlled by appropriate synchronization.
+ *
+ *
+ * <h2> Invocation chaining </h2>
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked.  This allows
+ * method invocations to be chained; for example, the sequence of statements
+ *
+ * <blockquote><pre>
+ * b.flip();
+ * b.position(23);
+ * b.limit(42);</pre></blockquote>
+ *
+ * can be replaced by the single, more compact statement
+ *
+ * <blockquote><pre>
+ * b.flip().position(23).limit(42);</pre></blockquote>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class Buffer {
+
+    /**
+     * The characteristics of Spliterators that traverse and split elements
+     * maintained in Buffers.
+     */
+    static final int SPLITERATOR_CHARACTERISTICS =
+        Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.ORDERED;
+
+    // Invariants: mark <= position <= limit <= capacity
+    private int mark = -1;
+    // Android-changed: position field non-private for use by Android's nio implementation classes.
+    int position = 0;
+    private int limit;
+    private int capacity;
+
+    // Used only by direct buffers
+    // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
+    long address;
+
+    // Android-added: _elementSizeShift field for NIOAccess class and framework native code.
+    /**
+     * The log base 2 of the element size of this buffer.  Each typed subclass
+     * (ByteBuffer, CharBuffer, etc.) is responsible for initializing this
+     * value.  The value is used by JNI code in frameworks/base/ to avoid the
+     * need for costly 'instanceof' tests.
+     */
+    final int _elementSizeShift;
+
+    // Creates a new buffer with the given mark, position, limit, and capacity,
+    // after checking invariants.
+    //
+    // Android-added: _elementSizeShift field for NIOAccess class and framework native code.
+    Buffer(int mark, int pos, int lim, int cap, int elementSizeShift) {       // package-private
+        if (cap < 0)
+            throw new IllegalArgumentException("Negative capacity: " + cap);
+        this.capacity = cap;
+        limit(lim);
+        position(pos);
+        if (mark >= 0) {
+            if (mark > pos)
+                throw new IllegalArgumentException("mark > position: ("
+                                                   + mark + " > " + pos + ")");
+            this.mark = mark;
+        }
+        // Android-added: _elementSizeShift field for NIOAccess class and framework native code.
+        _elementSizeShift = elementSizeShift;
+    }
+
+    /**
+     * Returns this buffer's capacity.
+     *
+     * @return  The capacity of this buffer
+     */
+    public final int capacity() {
+        return capacity;
+    }
+
+    /**
+     * Returns this buffer's position.
+     *
+     * @return  The position of this buffer
+     */
+    public final int position() {
+        return position;
+    }
+
+    /**
+     * Sets this buffer's position.  If the mark is defined and larger than the
+     * new position then it is discarded.
+     *
+     * @param  newPosition
+     *         The new position value; must be non-negative
+     *         and no larger than the current limit
+     *
+     * @return  This buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on <tt>newPosition</tt> do not hold
+     */
+    public Buffer position(int newPosition) {
+        if ((newPosition > limit) || (newPosition < 0))
+            // Android-changed: Improved error message.
+            throw new IllegalArgumentException("Bad position " + newPosition + "/" + limit);
+        position = newPosition;
+        if (mark > position) mark = -1;
+        return this;
+    }
+
+    /**
+     * Returns this buffer's limit.
+     *
+     * @return  The limit of this buffer
+     */
+    public final int limit() {
+        return limit;
+    }
+
+    /**
+     * Sets this buffer's limit.  If the position is larger than the new limit
+     * then it is set to the new limit.  If the mark is defined and larger than
+     * the new limit then it is discarded.
+     *
+     * @param  newLimit
+     *         The new limit value; must be non-negative
+     *         and no larger than this buffer's capacity
+     *
+     * @return  This buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on <tt>newLimit</tt> do not hold
+     */
+    public Buffer limit(int newLimit) {
+        if ((newLimit > capacity) || (newLimit < 0))
+            throw new IllegalArgumentException();
+        limit = newLimit;
+        if (position > limit) position = limit;
+        if (mark > limit) mark = -1;
+        return this;
+    }
+
+    /**
+     * Sets this buffer's mark at its position.
+     *
+     * @return  This buffer
+     */
+    public Buffer mark() {
+        mark = position;
+        return this;
+    }
+
+    /**
+     * Resets this buffer's position to the previously-marked position.
+     *
+     * <p> Invoking this method neither changes nor discards the mark's
+     * value. </p>
+     *
+     * @return  This buffer
+     *
+     * @throws  InvalidMarkException
+     *          If the mark has not been set
+     */
+    public Buffer reset() {
+        int m = mark;
+        if (m < 0)
+            throw new InvalidMarkException();
+        position = m;
+        return this;
+    }
+
+    /**
+     * Clears this buffer.  The position is set to zero, the limit is set to
+     * the capacity, and the mark is discarded.
+     *
+     * <p> Invoke this method before using a sequence of channel-read or
+     * <i>put</i> operations to fill this buffer.  For example:
+     *
+     * <blockquote><pre>
+     * buf.clear();     // Prepare buffer for reading
+     * in.read(buf);    // Read data</pre></blockquote>
+     *
+     * <p> This method does not actually erase the data in the buffer, but it
+     * is named as if it did because it will most often be used in situations
+     * in which that might as well be the case. </p>
+     *
+     * @return  This buffer
+     */
+    public Buffer clear() {
+        position = 0;
+        limit = capacity;
+        mark = -1;
+        return this;
+    }
+
+    /**
+     * Flips this buffer.  The limit is set to the current position and then
+     * the position is set to zero.  If the mark is defined then it is
+     * discarded.
+     *
+     * <p> After a sequence of channel-read or <i>put</i> operations, invoke
+     * this method to prepare for a sequence of channel-write or relative
+     * <i>get</i> operations.  For example:
+     *
+     * <blockquote><pre>
+     * buf.put(magic);    // Prepend header
+     * in.read(buf);      // Read data into rest of buffer
+     * buf.flip();        // Flip buffer
+     * out.write(buf);    // Write header + data to channel</pre></blockquote>
+     *
+     * <p> This method is often used in conjunction with the {@link
+     * java.nio.ByteBuffer#compact compact} method when transferring data from
+     * one place to another.  </p>
+     *
+     * @return  This buffer
+     */
+    public Buffer flip() {
+        limit = position;
+        position = 0;
+        mark = -1;
+        return this;
+    }
+
+    /**
+     * Rewinds this buffer.  The position is set to zero and the mark is
+     * discarded.
+     *
+     * <p> Invoke this method before a sequence of channel-write or <i>get</i>
+     * operations, assuming that the limit has already been set
+     * appropriately.  For example:
+     *
+     * <blockquote><pre>
+     * out.write(buf);    // Write remaining data
+     * buf.rewind();      // Rewind buffer
+     * buf.get(array);    // Copy data into array</pre></blockquote>
+     *
+     * @return  This buffer
+     */
+    public Buffer rewind() {
+        position = 0;
+        mark = -1;
+        return this;
+    }
+
+    /**
+     * Returns the number of elements between the current position and the
+     * limit.
+     *
+     * @return  The number of elements remaining in this buffer
+     */
+    public final int remaining() {
+        return limit - position;
+    }
+
+    /**
+     * Tells whether there are any elements between the current position and
+     * the limit.
+     *
+     * @return  <tt>true</tt> if, and only if, there is at least one element
+     *          remaining in this buffer
+     */
+    public final boolean hasRemaining() {
+        return position < limit;
+    }
+
+    /**
+     * Tells whether or not this buffer is read-only.
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is read-only
+     */
+    public abstract boolean isReadOnly();
+
+    /**
+     * Tells whether or not this buffer is backed by an accessible
+     * array.
+     *
+     * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+     * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+     * </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer
+     *          is backed by an array and is not read-only
+     *
+     * @since 1.6
+     */
+    public abstract boolean hasArray();
+
+    /**
+     * Returns the array that backs this
+     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method is intended to allow array-backed buffers to be
+     * passed to native code more efficiently. Concrete subclasses
+     * provide more strongly-typed return values for this method.
+     *
+     * <p> Modifications to this buffer's content will cause the returned
+     * array's content to be modified, and vice versa.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The array that backs this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     *
+     * @since 1.6
+     */
+    public abstract Object array();
+
+    /**
+     * Returns the offset within this buffer's backing array of the first
+     * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> If this buffer is backed by an array then buffer position <i>p</i>
+     * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The offset within this buffer's array
+     *          of the first element of the buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     *
+     * @since 1.6
+     */
+    public abstract int arrayOffset();
+
+    /**
+     * Tells whether or not this buffer is
+     * <a href="ByteBuffer.html#direct"><i>direct</i></a>.
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is direct
+     *
+     * @since 1.6
+     */
+    public abstract boolean isDirect();
+
+
+    // -- Package-private methods for bounds checking, etc. --
+
+    /**
+     * Checks the current position against the limit, throwing a {@link
+     * BufferUnderflowException} if it is not smaller than the limit, and then
+     * increments the position.
+     *
+     * @return  The current position value, before it is incremented
+     */
+    final int nextGetIndex() {                          // package-private
+        if (position >= limit)
+            throw new BufferUnderflowException();
+        return position++;
+    }
+
+    final int nextGetIndex(int nb) {                    // package-private
+        if (limit - position < nb)
+            throw new BufferUnderflowException();
+        int p = position;
+        position += nb;
+        return p;
+    }
+
+    /**
+     * Checks the current position against the limit, throwing a {@link
+     * BufferOverflowException} if it is not smaller than the limit, and then
+     * increments the position.
+     *
+     * @return  The current position value, before it is incremented
+     */
+    final int nextPutIndex() {                          // package-private
+        if (position >= limit)
+            throw new BufferOverflowException();
+        return position++;
+    }
+
+    final int nextPutIndex(int nb) {                    // package-private
+        if (limit - position < nb)
+            throw new BufferOverflowException();
+        int p = position;
+        position += nb;
+        return p;
+    }
+
+    /**
+     * Checks the given index against the limit, throwing an {@link
+     * IndexOutOfBoundsException} if it is not smaller than the limit
+     * or is smaller than zero.
+     */
+    final int checkIndex(int i) {                       // package-private
+        if ((i < 0) || (i >= limit))
+            // Android-changed: Add bounds details to exception.
+            throw new IndexOutOfBoundsException(
+                    "index=" + i + " out of bounds (limit=" + limit + ")");
+        return i;
+    }
+
+    final int checkIndex(int i, int nb) {               // package-private
+        if ((i < 0) || (nb > limit - i))
+            // Android-changed: Add bounds details to exception.
+            throw new IndexOutOfBoundsException(
+                    "index=" + i + " out of bounds (limit=" + limit + ", nb=" + nb + ")");
+        return i;
+    }
+
+    final int markValue() {                             // package-private
+        return mark;
+    }
+
+    final void truncate() {                             // package-private
+        mark = -1;
+        position = 0;
+        limit = 0;
+        capacity = 0;
+    }
+
+    final void discardMark() {                          // package-private
+        mark = -1;
+    }
+
+    static void checkBounds(int off, int len, int size) { // package-private
+        if ((off | len | (off + len) | (size - (off + len))) < 0)
+            // Android-changed: Add bounds details to exception.
+            throw new IndexOutOfBoundsException(
+                    "off=" + off + ", len=" + len + " out of bounds (size=" + size + ")");
+    }
+
+    // Android-added: getElementSizeShift() method for testing.
+    /**
+     * For testing only. This field is accessed directly via JNI from frameworks code.
+     *
+     * @hide
+     */
+    public int getElementSizeShift() {
+        return _elementSizeShift;
+    }
+
+}
diff --git a/java/nio/BufferOverflowException.java b/java/nio/BufferOverflowException.java
new file mode 100644
index 0000000..d141a82
--- /dev/null
+++ b/java/nio/BufferOverflowException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+/**
+ * Unchecked exception thrown when a relative <i>put</i> operation reaches
+ * the target buffer's limit.
+ *
+ * @since 1.4
+ */
+
+public class BufferOverflowException
+    extends RuntimeException
+{
+
+    private static final long serialVersionUID = -5484897634319144535L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public BufferOverflowException() { }
+
+}
diff --git a/java/nio/BufferUnderflowException.java b/java/nio/BufferUnderflowException.java
new file mode 100644
index 0000000..d7a062a
--- /dev/null
+++ b/java/nio/BufferUnderflowException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+/**
+ * Unchecked exception thrown when a relative <i>get</i> operation reaches
+ * the source buffer's limit.
+ *
+ * @since 1.4
+ */
+
+public class BufferUnderflowException
+    extends RuntimeException
+{
+
+    private static final long serialVersionUID = -1713313658691622206L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public BufferUnderflowException() { }
+
+}
diff --git a/java/nio/ByteBuffer.annotated.java b/java/nio/ByteBuffer.annotated.java
new file mode 100644
index 0000000..d0caba2
--- /dev/null
+++ b/java/nio/ByteBuffer.annotated.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+
+package java.nio;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class ByteBuffer extends java.nio.Buffer implements java.lang.Comparable<java.nio.ByteBuffer> {
+
+ByteBuffer(int mark, int pos, int lim, int cap) { super(0, 0, 0, 0, 0); throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer allocateDirect(int capacity) { throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer allocate(int capacity) { throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer wrap(byte[] array, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public static java.nio.ByteBuffer wrap(byte[] array) { throw new RuntimeException("Stub!"); }
+
+public abstract java.nio.ByteBuffer slice();
+
+public abstract java.nio.ByteBuffer duplicate();
+
+public abstract java.nio.ByteBuffer asReadOnlyBuffer();
+
+public abstract byte get();
+
+public abstract java.nio.ByteBuffer put(byte b);
+
+public abstract byte get(int index);
+
+public abstract java.nio.ByteBuffer put(int index, byte b);
+
+public java.nio.ByteBuffer get(byte[] dst, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer get(byte[] dst) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(java.nio.ByteBuffer src) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(byte[] src, int offset, int length) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer put(byte[] src) { throw new RuntimeException("Stub!"); }
+
+public final boolean hasArray() { throw new RuntimeException("Stub!"); }
+
+public final byte[] array() { throw new RuntimeException("Stub!"); }
+
+public final int arrayOffset() { throw new RuntimeException("Stub!"); }
+
+public abstract java.nio.ByteBuffer compact();
+
+public abstract boolean isDirect();
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object ob) { throw new RuntimeException("Stub!"); }
+
+public int compareTo(java.nio.ByteBuffer that) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteOrder order() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer order(java.nio.ByteOrder bo) { throw new RuntimeException("Stub!"); }
+
+public abstract char getChar();
+
+public abstract java.nio.ByteBuffer putChar(char value);
+
+public abstract char getChar(int index);
+
+public abstract java.nio.ByteBuffer putChar(int index, char value);
+
+public abstract java.nio.CharBuffer asCharBuffer();
+
+public abstract short getShort();
+
+public abstract java.nio.ByteBuffer putShort(short value);
+
+public abstract short getShort(int index);
+
+public abstract java.nio.ByteBuffer putShort(int index, short value);
+
+public abstract java.nio.ShortBuffer asShortBuffer();
+
+public abstract int getInt();
+
+public abstract java.nio.ByteBuffer putInt(int value);
+
+public abstract int getInt(int index);
+
+public abstract java.nio.ByteBuffer putInt(int index, int value);
+
+public abstract java.nio.IntBuffer asIntBuffer();
+
+public abstract long getLong();
+
+public abstract java.nio.ByteBuffer putLong(long value);
+
+public abstract long getLong(int index);
+
+public abstract java.nio.ByteBuffer putLong(int index, long value);
+
+public abstract java.nio.LongBuffer asLongBuffer();
+
+public abstract float getFloat();
+
+public abstract java.nio.ByteBuffer putFloat(float value);
+
+public abstract float getFloat(int index);
+
+public abstract java.nio.ByteBuffer putFloat(int index, float value);
+
+public abstract java.nio.FloatBuffer asFloatBuffer();
+
+public abstract double getDouble();
+
+public abstract java.nio.ByteBuffer putDouble(double value);
+
+public abstract double getDouble(int index);
+
+public abstract java.nio.ByteBuffer putDouble(int index, double value);
+
+public abstract java.nio.DoubleBuffer asDoubleBuffer();
+
+public boolean isAccessible() { throw new RuntimeException("Stub!"); }
+
[email protected]
+public void setAccessible(boolean value) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/nio/ByteBuffer.java b/java/nio/ByteBuffer.java
new file mode 100644
index 0000000..b286cbd
--- /dev/null
+++ b/java/nio/ByteBuffer.java
@@ -0,0 +1,1746 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+import libcore.io.Memory;
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * A byte buffer.
+ *
+ * <p> This class defines six categories of operations upon
+ * byte buffers:
+ *
+ * <ul>
+ *
+ *   <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ *   {@link #put(byte) <i>put</i>} methods that read and write
+ *   single bytes; </p></li>
+ *
+ *   <li><p> Relative {@link #get(byte[]) <i>bulk get</i>}
+ *   methods that transfer contiguous sequences of bytes from this buffer
+ *   into an array; </p></li>
+ *
+ *   <li><p> Relative {@link #put(byte[]) <i>bulk put</i>}
+ *   methods that transfer contiguous sequences of bytes from a
+ *   byte array or some other byte
+ *   buffer into this buffer; </p></li>
+ *
+ *
+ *   <li><p> Absolute and relative {@link #getChar() <i>get</i>}
+ *   and {@link #putChar(char) <i>put</i>} methods that read and
+ *   write values of other primitive types, translating them to and from
+ *   sequences of bytes in a particular byte order; </p></li>
+ *
+ *   <li><p> Methods for creating <i><a href="#views">view buffers</a></i>,
+ *   which allow a byte buffer to be viewed as a buffer containing values of
+ *   some other primitive type; and </p></li>
+ *
+ *
+ *   <li><p> Methods for {@link #compact compacting}, {@link
+ *   #duplicate duplicating}, and {@link #slice slicing}
+ *   a byte buffer.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> Byte buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, or by {@link #wrap(byte[]) <i>wrapping</i>} an
+ * existing byte array  into a buffer.
+ *
+ *
+ *
+ * <a name="direct"></a>
+ * <h2> Direct <i>vs.</i> non-direct buffers </h2>
+ *
+ * <p> A byte buffer is either <i>direct</i> or <i>non-direct</i>.  Given a
+ * direct byte buffer, the Java virtual machine will make a best effort to
+ * perform native I/O operations directly upon it.  That is, it will attempt to
+ * avoid copying the buffer's content to (or from) an intermediate buffer
+ * before (or after) each invocation of one of the underlying operating
+ * system's native I/O operations.
+ *
+ * <p> A direct byte buffer may be created by invoking the {@link
+ * #allocateDirect(int) allocateDirect} factory method of this class.  The
+ * buffers returned by this method typically have somewhat higher allocation
+ * and deallocation costs than non-direct buffers.  The contents of direct
+ * buffers may reside outside of the normal garbage-collected heap, and so
+ * their impact upon the memory footprint of an application might not be
+ * obvious.  It is therefore recommended that direct buffers be allocated
+ * primarily for large, long-lived buffers that are subject to the underlying
+ * system's native I/O operations.  In general it is best to allocate direct
+ * buffers only when they yield a measureable gain in program performance.
+ *
+ * <p> A direct byte buffer may also be created by {@link
+ * java.nio.channels.FileChannel#map mapping} a region of a file
+ * directly into memory.  An implementation of the Java platform may optionally
+ * support the creation of direct byte buffers from native code via JNI.  If an
+ * instance of one of these kinds of buffers refers to an inaccessible region
+ * of memory then an attempt to access that region will not change the buffer's
+ * content and will cause an unspecified exception to be thrown either at the
+ * time of the access or at some later time.
+ *
+ * <p> Whether a byte buffer is direct or non-direct may be determined by
+ * invoking its {@link #isDirect isDirect} method.  This method is provided so
+ * that explicit buffer management can be done in performance-critical code.
+ *
+ *
+ * <a name="bin"></a>
+ * <h2> Access to binary data </h2>
+ *
+ * <p> This class defines methods for reading and writing values of all other
+ * primitive types, except <tt>boolean</tt>.  Primitive values are translated
+ * to (or from) sequences of bytes according to the buffer's current byte
+ * order, which may be retrieved and modified via the {@link #order order}
+ * methods.  Specific byte orders are represented by instances of the {@link
+ * ByteOrder} class.  The initial order of a byte buffer is always {@link
+ * ByteOrder#BIG_ENDIAN BIG_ENDIAN}.
+ *
+ * <p> For access to heterogeneous binary data, that is, sequences of values of
+ * different types, this class defines a family of absolute and relative
+ * <i>get</i> and <i>put</i> methods for each type.  For 32-bit floating-point
+ * values, for example, this class defines:
+ *
+ * <blockquote><pre>
+ * float  {@link #getFloat()}
+ * float  {@link #getFloat(int) getFloat(int index)}
+ *  void  {@link #putFloat(float) putFloat(float f)}
+ *  void  {@link #putFloat(int,float) putFloat(int index, float f)}</pre></blockquote>
+ *
+ * <p> Corresponding methods are defined for the types <tt>char</tt>,
+ * <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and <tt>double</tt>.  The index
+ * parameters of the absolute <i>get</i> and <i>put</i> methods are in terms of
+ * bytes rather than of the type being read or written.
+ *
+ * <a name="views"></a>
+ *
+ * <p> For access to homogeneous binary data, that is, sequences of values of
+ * the same type, this class defines methods that can create <i>views</i> of a
+ * given byte buffer.  A <i>view buffer</i> is simply another buffer whose
+ * content is backed by the byte buffer.  Changes to the byte buffer's content
+ * will be visible in the view buffer, and vice versa; the two buffers'
+ * position, limit, and mark values are independent.  The {@link
+ * #asFloatBuffer() asFloatBuffer} method, for example, creates an instance of
+ * the {@link FloatBuffer} class that is backed by the byte buffer upon which
+ * the method is invoked.  Corresponding view-creation methods are defined for
+ * the types <tt>char</tt>, <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, and
+ * <tt>double</tt>.
+ *
+ * <p> View buffers have three important advantages over the families of
+ * type-specific <i>get</i> and <i>put</i> methods described above:
+ *
+ * <ul>
+ *
+ *   <li><p> A view buffer is indexed not in terms of bytes but rather in terms
+ *   of the type-specific size of its values;  </p></li>
+ *
+ *   <li><p> A view buffer provides relative bulk <i>get</i> and <i>put</i>
+ *   methods that can transfer contiguous sequences of values between a buffer
+ *   and an array or some other buffer of the same type; and  </p></li>
+ *
+ *   <li><p> A view buffer is potentially much more efficient because it will
+ *   be direct if, and only if, its backing byte buffer is direct.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> The byte order of a view buffer is fixed to be that of its byte buffer
+ * at the time that the view is created.  </p>
+ *
+*
+*
+ *
+ * <h2> Invocation chaining </h2>
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked.  This allows
+ * method invocations to be chained.
+ *
+ *
+ * The sequence of statements
+ *
+ * <blockquote><pre>
+ * bb.putInt(0xCAFEBABE);
+ * bb.putShort(3);
+ * bb.putShort(45);</pre></blockquote>
+ *
+ * can, for example, be replaced by the single statement
+ *
+ * <blockquote><pre>
+ * bb.putInt(0xCAFEBABE).putShort(3).putShort(45);</pre></blockquote>
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class ByteBuffer
+    extends Buffer
+    implements Comparable<ByteBuffer>
+{
+
+    // These fields are declared here rather than in Heap-X-Buffer in order to
+    // reduce the number of virtual method invocations needed to access these
+    // values, which is especially costly when coding small buffers.
+    //
+    final byte[] hb;                  // Non-null only for heap buffers
+    final int offset;
+    boolean isReadOnly;                 // Valid only for heap buffers
+
+    // Creates a new buffer with the given mark, position, limit, capacity,
+    // backing array, and array offset
+    //
+    ByteBuffer(int mark, int pos, int lim, int cap,   // package-private
+                 byte[] hb, int offset)
+    {
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 0 /* elementSizeShift */);
+        this.hb = hb;
+        this.offset = offset;
+    }
+
+    // Creates a new buffer with the given mark, position, limit, and capacity
+    //
+    ByteBuffer(int mark, int pos, int lim, int cap) { // package-private
+        this(mark, pos, lim, cap, null, 0);
+    }
+
+
+    /**
+     * Allocates a new direct byte buffer.
+     *
+     * <p> The new buffer's position will be zero, its limit will be its
+     * capacity, its mark will be undefined, and each of its elements will be
+     * initialized to zero.  Whether or not it has a
+     * {@link #hasArray backing array} is unspecified.
+     *
+     * @param  capacity
+     *         The new buffer's capacity, in bytes
+     *
+     * @return  The new byte buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the <tt>capacity</tt> is a negative integer
+     */
+    public static ByteBuffer allocateDirect(int capacity) {
+        // Android-changed: Android's DirectByteBuffers carry a MemoryRef.
+        // return new DirectByteBuffer(capacity);
+        DirectByteBuffer.MemoryRef memoryRef = new DirectByteBuffer.MemoryRef(capacity);
+        return new DirectByteBuffer(capacity, memoryRef);
+    }
+
+
+    /**
+     * Allocates a new byte buffer.
+     *
+     * <p> The new buffer's position will be zero, its limit will be its
+     * capacity, its mark will be undefined, and each of its elements will be
+     * initialized to zero.  It will have a {@link #array backing array},
+     * and its {@link #arrayOffset array offset} will be zero.
+     *
+     * @param  capacity
+     *         The new buffer's capacity, in bytes
+     *
+     * @return  The new byte buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the <tt>capacity</tt> is a negative integer
+     */
+    public static ByteBuffer allocate(int capacity) {
+        if (capacity < 0)
+            throw new IllegalArgumentException();
+        return new HeapByteBuffer(capacity, capacity);
+    }
+
+    /**
+     * Wraps a byte array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given byte array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity will be
+     * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+     * will be <tt>offset + length</tt>, and its mark will be undefined.  Its
+     * {@link #array backing array} will be the given array, and
+     * its {@link #arrayOffset array offset} will be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back the new buffer
+     *
+     * @param  offset
+     *         The offset of the subarray to be used; must be non-negative and
+     *         no larger than <tt>array.length</tt>.  The new buffer's position
+     *         will be set to this value.
+     *
+     * @param  length
+     *         The length of the subarray to be used;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>.
+     *         The new buffer's limit will be set to <tt>offset + length</tt>.
+     *
+     * @return  The new byte buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public static ByteBuffer wrap(byte[] array,
+                                    int offset, int length)
+    {
+        try {
+            return new HeapByteBuffer(array, offset, length);
+        } catch (IllegalArgumentException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Wraps a byte array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given byte array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity and limit will be
+     * <tt>array.length</tt>, its position will be zero, and its mark will be
+     * undefined.  Its {@link #array backing array} will be the
+     * given array, and its {@link #arrayOffset array offset>} will
+     * be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back this buffer
+     *
+     * @return  The new byte buffer
+     */
+    public static ByteBuffer wrap(byte[] array) {
+        return wrap(array, 0, array.length);
+    }
+
+
+    /**
+     * Creates a new byte buffer whose content is a shared subsequence of
+     * this buffer's content.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of bytes remaining in this buffer, and its mark
+     * will be undefined.  The new buffer will be direct if, and only if, this
+     * buffer is direct, and it will be read-only if, and only if, this buffer
+     * is read-only.  </p>
+     *
+     * @return  The new byte buffer
+     */
+    public abstract ByteBuffer slice();
+
+    /**
+     * Creates a new byte buffer that shares this buffer's content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer, and vice
+     * versa; the two buffers' position, limit, and mark values will be
+     * independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.  The new buffer will be direct if,
+     * and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  The new byte buffer
+     */
+    public abstract ByteBuffer duplicate();
+
+    /**
+     * Creates a new, read-only byte buffer that shares this buffer's
+     * content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer; the new
+     * buffer itself, however, will be read-only and will not allow the shared
+     * content to be modified.  The two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.
+     *
+     * <p> If this buffer is itself read-only then this method behaves in
+     * exactly the same way as the {@link #duplicate duplicate} method.  </p>
+     *
+     * @return  The new, read-only byte buffer
+     */
+    public abstract ByteBuffer asReadOnlyBuffer();
+
+
+    // -- Singleton get/put methods --
+
+    /**
+     * Relative <i>get</i> method.  Reads the byte at this buffer's
+     * current position, and then increments the position.
+     *
+     * @return  The byte at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If the buffer's current position is not smaller than its limit
+     */
+    public abstract byte get();
+
+    /**
+     * Relative <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given byte into this buffer at the current
+     * position, and then increments the position. </p>
+     *
+     * @param  b
+     *         The byte to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If this buffer's current position is not smaller than its limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer put(byte b);
+
+    /**
+     * Absolute <i>get</i> method.  Reads the byte at the given
+     * index.
+     *
+     * @param  index
+     *         The index from which the byte will be read
+     *
+     * @return  The byte at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     */
+    public abstract byte get(int index);
+
+    /**
+     * Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given byte into this buffer at the given
+     * index. </p>
+     *
+     * @param  index
+     *         The index at which the byte will be written
+     *
+     * @param  b
+     *         The byte value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer put(int index, byte b);
+
+
+    // -- Bulk get operations --
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers bytes from this buffer into the given
+     * destination array.  If there are fewer bytes remaining in the
+     * buffer than are required to satisfy the request, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * bytes are transferred and a {@link BufferUnderflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> bytes from this
+     * buffer into the given array, starting at the current position of this
+     * buffer and at the given offset in the array.  The position of this
+     * buffer is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>src.get(dst,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst[i] = src.get();
+     * }</pre>
+     *
+     * except that it first checks that there are sufficient bytes in
+     * this buffer and it is potentially much more efficient.
+     *
+     * @param  dst
+     *         The array into which bytes are to be written
+     *
+     * @param  offset
+     *         The offset within the array of the first byte to be
+     *         written; must be non-negative and no larger than
+     *         <tt>dst.length</tt>
+     *
+     * @param  length
+     *         The maximum number of bytes to be written to the given
+     *         array; must be non-negative and no larger than
+     *         <tt>dst.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> bytes
+     *          remaining in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public ByteBuffer get(byte[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            dst[i] = get();
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers bytes from this buffer into the given
+     * destination array.  An invocation of this method of the form
+     * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     src.get(a, 0, a.length) </pre>
+     *
+     * @param   dst
+     *          The destination array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> bytes
+     *          remaining in this buffer
+     */
+    public ByteBuffer get(byte[] dst) {
+        return get(dst, 0, dst.length);
+    }
+
+
+    // -- Bulk put operations --
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the bytes remaining in the given source
+     * buffer into this buffer.  If there are more bytes remaining in the
+     * source buffer than in this buffer, that is, if
+     * <tt>src.remaining()</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>,
+     * then no bytes are transferred and a {@link
+     * BufferOverflowException} is thrown.
+     *
+     * <p> Otherwise, this method copies
+     * <i>n</i>&nbsp;=&nbsp;<tt>src.remaining()</tt> bytes from the given
+     * buffer into this buffer, starting at each buffer's current position.
+     * The positions of both buffers are then incremented by <i>n</i>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+     *
+     * <pre>
+     *     while (src.hasRemaining())
+     *         dst.put(src.get()); </pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The source buffer from which bytes are to be read;
+     *         must not be this buffer
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *          for the remaining bytes in the source buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the source buffer is this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public ByteBuffer put(ByteBuffer src) {
+        if (src == this)
+            throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
+        int n = src.remaining();
+        if (n > remaining())
+            throw new BufferOverflowException();
+
+        // Android-changed: improve ByteBuffer.put(ByteBuffer) performance through bulk copy.
+        /*
+        for (int i = 0; i < n; i++)
+            put(src.get());
+        */
+        // Note that we use offset instead of arrayOffset because arrayOffset is specified to
+        // throw for read only buffers. Our use of arrayOffset here is provably safe, we only
+        // use it to read *from* readOnly buffers.
+        if (this.hb != null && src.hb != null) {
+            // System.arraycopy is intrinsified by ART and therefore tiny bit faster than memmove
+            System.arraycopy(src.hb, src.position() + src.offset, hb, position() + offset, n);
+        } else {
+            // Use the buffer object (and the raw memory address) if it's a direct buffer. Note that
+            // isDirect() doesn't imply !hasArray(), ByteBuffer.allocateDirect allocated buffer will
+            // have a backing, non-gc-movable byte array. JNI allocated direct byte buffers WILL NOT
+            // have a backing array.
+            final Object srcObject = src.isDirect() ? src : src.hb;
+            int srcOffset = src.position();
+            if (!src.isDirect()) {
+                srcOffset += src.offset;
+            }
+
+            final ByteBuffer dst = this;
+            final Object dstObject = dst.isDirect() ? dst : dst.hb;
+            int dstOffset = dst.position();
+            if (!dst.isDirect()) {
+                dstOffset += dst.offset;
+            }
+            Memory.memmove(dstObject, dstOffset, srcObject, srcOffset, n);
+        }
+        src.position(src.limit());
+        this.position(this.position() + n);
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers bytes into this buffer from the given
+     * source array.  If there are more bytes to be copied from the array
+     * than remain in this buffer, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * bytes are transferred and a {@link BufferOverflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> bytes from the
+     * given array into this buffer, starting at the given offset in the array
+     * and at the current position of this buffer.  The position of this buffer
+     * is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst.put(a[i]);
+     * }</pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The array from which bytes are to be read
+     *
+     * @param  offset
+     *         The offset within the array of the first byte to be read;
+     *         must be non-negative and no larger than <tt>array.length</tt>
+     *
+     * @param  length
+     *         The number of bytes to be read from the given array;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public ByteBuffer put(byte[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            this.put(src[i]);
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the entire content of the given source
+     * byte array into this buffer.  An invocation of this method of the
+     * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+     * invocation
+     *
+     * <pre>
+     *     dst.put(a, 0, a.length) </pre>
+     *
+     * @param   src
+     *          The source array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public final ByteBuffer put(byte[] src) {
+        return put(src, 0, src.length);
+    }
+
+
+    // -- Other stuff --
+
+    /**
+     * Tells whether or not this buffer is backed by an accessible byte
+     * array.
+     *
+     * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+     * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+     * </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer
+     *          is backed by an array and is not read-only
+     */
+    public final boolean hasArray() {
+        return (hb != null) && !isReadOnly;
+    }
+
+    /**
+     * Returns the byte array that backs this
+     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Modifications to this buffer's content will cause the returned
+     * array's content to be modified, and vice versa.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The array that backs this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final byte[] array() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return hb;
+    }
+
+    /**
+     * Returns the offset within this buffer's backing array of the first
+     * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> If this buffer is backed by an array then buffer position <i>p</i>
+     * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The offset within this buffer's array
+     *          of the first element of the buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final int arrayOffset() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return offset;
+    }
+
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = ByteBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
+    /**
+     * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> The bytes between the buffer's current position and its limit,
+     * if any, are copied to the beginning of the buffer.  That is, the
+     * byte at index <i>p</i>&nbsp;=&nbsp;<tt>position()</tt> is copied
+     * to index zero, the byte at index <i>p</i>&nbsp;+&nbsp;1 is copied
+     * to index one, and so forth until the byte at index
+     * <tt>limit()</tt>&nbsp;-&nbsp;1 is copied to index
+     * <i>n</i>&nbsp;=&nbsp;<tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>&nbsp;-&nbsp;<i>p</i>.
+     * The buffer's position is then set to <i>n+1</i> and its limit is set to
+     * its capacity.  The mark, if defined, is discarded.
+     *
+     * <p> The buffer's position is set to the number of bytes copied,
+     * rather than to zero, so that an invocation of this method can be
+     * followed immediately by an invocation of another relative <i>put</i>
+     * method. </p>
+     *
+
+     *
+     * <p> Invoke this method after writing data from a buffer in case the
+     * write was incomplete.  The following loop, for example, copies bytes
+     * from one channel to another via the buffer <tt>buf</tt>:
+     *
+     * <blockquote><pre>{@code
+     *   buf.clear();          // Prepare buffer for use
+     *   while (in.read(buf) >= 0 || buf.position != 0) {
+     *       buf.flip();
+     *       out.write(buf);
+     *       buf.compact();    // In case of partial write
+     *   }
+     * }</pre></blockquote>
+     *
+
+     *
+     * @return  This buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer compact();
+
+    /**
+     * Tells whether or not this byte buffer is direct.
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is direct
+     */
+    public abstract boolean isDirect();
+
+
+    /**
+     * Returns a string summarizing the state of this buffer.
+     *
+     * @return  A summary string
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName());
+        sb.append("[pos=");
+        sb.append(position());
+        sb.append(" lim=");
+        sb.append(limit());
+        sb.append(" cap=");
+        sb.append(capacity());
+        sb.append("]");
+        return sb.toString();
+    }
+
+
+    /**
+     * Returns the current hash code of this buffer.
+     *
+     * <p> The hash code of a byte buffer depends only upon its remaining
+     * elements; that is, upon the elements from <tt>position()</tt> up to, and
+     * including, the element at <tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>.
+     *
+     * <p> Because buffer hash codes are content-dependent, it is inadvisable
+     * to use buffers as keys in hash maps or similar data structures unless it
+     * is known that their contents will not change.  </p>
+     *
+     * @return  The current hash code of this buffer
+     */
+    public int hashCode() {
+        int h = 1;
+        int p = position();
+        for (int i = limit() - 1; i >= p; i--)
+            h = 31 * h + (int)get(i);
+        return h;
+    }
+
+    /**
+     * Tells whether or not this buffer is equal to another object.
+     *
+     * <p> Two byte buffers are equal if, and only if,
+     *
+     * <ol>
+     *
+     *   <li><p> They have the same element type,  </p></li>
+     *
+     *   <li><p> They have the same number of remaining elements, and
+     *   </p></li>
+     *
+     *   <li><p> The two sequences of remaining elements, considered
+     *   independently of their starting positions, are pointwise equal.
+
+     *   </p></li>
+     *
+     * </ol>
+     *
+     * <p> A byte buffer is not equal to any other type of object.  </p>
+     *
+     * @param  ob  The object to which this buffer is to be compared
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is equal to the
+     *           given object
+     */
+    public boolean equals(Object ob) {
+        if (this == ob)
+            return true;
+        if (!(ob instanceof ByteBuffer))
+            return false;
+        ByteBuffer that = (ByteBuffer)ob;
+        if (this.remaining() != that.remaining())
+            return false;
+        int p = this.position();
+        for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+            if (!equals(this.get(i), that.get(j)))
+                return false;
+        return true;
+    }
+
+    private static boolean equals(byte x, byte y) {
+
+
+        return x == y;
+
+    }
+
+    /**
+     * Compares this buffer to another.
+     *
+     * <p> Two byte buffers are compared by comparing their sequences of
+     * remaining elements lexicographically, without regard to the starting
+     * position of each sequence within its corresponding buffer.
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     * Pairs of {@code byte} elements are compared as if by invoking
+     * {@link Byte#compare(byte,byte)}.
+
+     *
+     * <p> A byte buffer is not comparable to any other type of object.
+     *
+     * @return  A negative integer, zero, or a positive integer as this buffer
+     *          is less than, equal to, or greater than the given buffer
+     */
+    public int compareTo(ByteBuffer that) {
+        int n = this.position() + Math.min(this.remaining(), that.remaining());
+        for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+            int cmp = compare(this.get(i), that.get(j));
+            if (cmp != 0)
+                return cmp;
+        }
+        return this.remaining() - that.remaining();
+    }
+
+    private static int compare(byte x, byte y) {
+
+
+        return Byte.compare(x, y);
+
+    }
+
+    // -- Other char stuff --
+
+
+    // -- Other byte stuff: Access to binary data --
+
+
+    boolean bigEndian                                   // package-private
+        = true;
+    boolean nativeByteOrder                             // package-private
+        = (Bits.byteOrder() == ByteOrder.BIG_ENDIAN);
+
+    /**
+     * Retrieves this buffer's byte order.
+     *
+     * <p> The byte order is used when reading or writing multibyte values, and
+     * when creating buffers that are views of this byte buffer.  The order of
+     * a newly-created byte buffer is always {@link ByteOrder#BIG_ENDIAN
+     * BIG_ENDIAN}.  </p>
+     *
+     * @return  This buffer's byte order
+     */
+    public final ByteOrder order() {
+        return bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
+    }
+
+    /**
+     * Modifies this buffer's byte order.
+     *
+     * @param  bo
+     *         The new byte order,
+     *         either {@link ByteOrder#BIG_ENDIAN BIG_ENDIAN}
+     *         or {@link ByteOrder#LITTLE_ENDIAN LITTLE_ENDIAN}
+     *
+     * @return  This buffer
+     */
+    public final ByteBuffer order(ByteOrder bo) {
+        bigEndian = (bo == ByteOrder.BIG_ENDIAN);
+        nativeByteOrder =
+            (bigEndian == (Bits.byteOrder() == ByteOrder.BIG_ENDIAN));
+        return this;
+    }
+
+    // Unchecked accessors, for use by ByteBufferAs-X-Buffer classes
+    //
+    abstract byte _get(int i);                          // package-private
+    abstract void _put(int i, byte b);                  // package-private
+
+
+    /**
+     * Relative <i>get</i> method for reading a char value.
+     *
+     * <p> Reads the next two bytes at this buffer's current position,
+     * composing them into a char value according to the current byte order,
+     * and then increments the position by two.  </p>
+     *
+     * @return  The char value at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than two bytes
+     *          remaining in this buffer
+     */
+    public abstract char getChar();
+
+    /**
+     * Relative <i>put</i> method for writing a char
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes two bytes containing the given char value, in the
+     * current byte order, into this buffer at the current position, and then
+     * increments the position by two.  </p>
+     *
+     * @param  value
+     *         The char value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there are fewer than two bytes
+     *          remaining in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putChar(char value);
+
+    /**
+     * Absolute <i>get</i> method for reading a char value.
+     *
+     * <p> Reads two bytes at the given index, composing them into a
+     * char value according to the current byte order.  </p>
+     *
+     * @param  index
+     *         The index from which the bytes will be read
+     *
+     * @return  The char value at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus one
+     */
+    public abstract char getChar(int index);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract char getCharUnchecked(int index);
+    abstract void getUnchecked(int pos, char[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Absolute <i>put</i> method for writing a char
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes two bytes containing the given char value, in the
+     * current byte order, into this buffer at the given index.  </p>
+     *
+     * @param  index
+     *         The index at which the bytes will be written
+     *
+     * @param  value
+     *         The char value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus one
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putChar(int index, char value);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putCharUnchecked(int index, char value);
+    abstract void putUnchecked(int pos, char[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Creates a view of this byte buffer as a char buffer.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of bytes remaining in this buffer divided by
+     * two, and its mark will be undefined.  The new buffer will be direct
+     * if, and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  A new char buffer
+     */
+    public abstract CharBuffer asCharBuffer();
+
+
+    /**
+     * Relative <i>get</i> method for reading a short value.
+     *
+     * <p> Reads the next two bytes at this buffer's current position,
+     * composing them into a short value according to the current byte order,
+     * and then increments the position by two.  </p>
+     *
+     * @return  The short value at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than two bytes
+     *          remaining in this buffer
+     */
+    public abstract short getShort();
+
+    /**
+     * Relative <i>put</i> method for writing a short
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes two bytes containing the given short value, in the
+     * current byte order, into this buffer at the current position, and then
+     * increments the position by two.  </p>
+     *
+     * @param  value
+     *         The short value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there are fewer than two bytes
+     *          remaining in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putShort(short value);
+
+    /**
+     * Absolute <i>get</i> method for reading a short value.
+     *
+     * <p> Reads two bytes at the given index, composing them into a
+     * short value according to the current byte order.  </p>
+     *
+     * @param  index
+     *         The index from which the bytes will be read
+     *
+     * @return  The short value at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus one
+     */
+    public abstract short getShort(int index);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract short getShortUnchecked(int index);
+    abstract void getUnchecked(int pos, short[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Absolute <i>put</i> method for writing a short
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes two bytes containing the given short value, in the
+     * current byte order, into this buffer at the given index.  </p>
+     *
+     * @param  index
+     *         The index at which the bytes will be written
+     *
+     * @param  value
+     *         The short value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus one
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putShort(int index, short value);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putShortUnchecked(int index, short value);
+    abstract void putUnchecked(int pos, short[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Creates a view of this byte buffer as a short buffer.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of bytes remaining in this buffer divided by
+     * two, and its mark will be undefined.  The new buffer will be direct
+     * if, and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  A new short buffer
+     */
+    public abstract ShortBuffer asShortBuffer();
+
+
+    /**
+     * Relative <i>get</i> method for reading an int value.
+     *
+     * <p> Reads the next four bytes at this buffer's current position,
+     * composing them into an int value according to the current byte order,
+     * and then increments the position by four.  </p>
+     *
+     * @return  The int value at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than four bytes
+     *          remaining in this buffer
+     */
+    public abstract int getInt();
+
+    /**
+     * Relative <i>put</i> method for writing an int
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes four bytes containing the given int value, in the
+     * current byte order, into this buffer at the current position, and then
+     * increments the position by four.  </p>
+     *
+     * @param  value
+     *         The int value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there are fewer than four bytes
+     *          remaining in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putInt(int value);
+
+    /**
+     * Absolute <i>get</i> method for reading an int value.
+     *
+     * <p> Reads four bytes at the given index, composing them into a
+     * int value according to the current byte order.  </p>
+     *
+     * @param  index
+     *         The index from which the bytes will be read
+     *
+     * @return  The int value at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus three
+     */
+    public abstract int getInt(int index);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract int getIntUnchecked(int index);
+    abstract void getUnchecked(int pos, int[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Absolute <i>put</i> method for writing an int
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes four bytes containing the given int value, in the
+     * current byte order, into this buffer at the given index.  </p>
+     *
+     * @param  index
+     *         The index at which the bytes will be written
+     *
+     * @param  value
+     *         The int value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus three
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putInt(int index, int value);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putIntUnchecked(int index, int value);
+    abstract void putUnchecked(int pos, int[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Creates a view of this byte buffer as an int buffer.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of bytes remaining in this buffer divided by
+     * four, and its mark will be undefined.  The new buffer will be direct
+     * if, and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  A new int buffer
+     */
+    public abstract IntBuffer asIntBuffer();
+
+
+    /**
+     * Relative <i>get</i> method for reading a long value.
+     *
+     * <p> Reads the next eight bytes at this buffer's current position,
+     * composing them into a long value according to the current byte order,
+     * and then increments the position by eight.  </p>
+     *
+     * @return  The long value at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than eight bytes
+     *          remaining in this buffer
+     */
+    public abstract long getLong();
+
+    /**
+     * Relative <i>put</i> method for writing a long
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes eight bytes containing the given long value, in the
+     * current byte order, into this buffer at the current position, and then
+     * increments the position by eight.  </p>
+     *
+     * @param  value
+     *         The long value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there are fewer than eight bytes
+     *          remaining in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putLong(long value);
+
+    /**
+     * Absolute <i>get</i> method for reading a long value.
+     *
+     * <p> Reads eight bytes at the given index, composing them into a
+     * long value according to the current byte order.  </p>
+     *
+     * @param  index
+     *         The index from which the bytes will be read
+     *
+     * @return  The long value at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus seven
+     */
+    public abstract long getLong(int index);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract long getLongUnchecked(int index);
+    abstract void getUnchecked(int pos, long[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Absolute <i>put</i> method for writing a long
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes eight bytes containing the given long value, in the
+     * current byte order, into this buffer at the given index.  </p>
+     *
+     * @param  index
+     *         The index at which the bytes will be written
+     *
+     * @param  value
+     *         The long value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus seven
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putLong(int index, long value);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putLongUnchecked(int index, long value);
+    abstract void putUnchecked(int pos, long[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Creates a view of this byte buffer as a long buffer.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of bytes remaining in this buffer divided by
+     * eight, and its mark will be undefined.  The new buffer will be direct
+     * if, and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  A new long buffer
+     */
+    public abstract LongBuffer asLongBuffer();
+
+
+    /**
+     * Relative <i>get</i> method for reading a float value.
+     *
+     * <p> Reads the next four bytes at this buffer's current position,
+     * composing them into a float value according to the current byte order,
+     * and then increments the position by four.  </p>
+     *
+     * @return  The float value at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than four bytes
+     *          remaining in this buffer
+     */
+    public abstract float getFloat();
+
+    /**
+     * Relative <i>put</i> method for writing a float
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes four bytes containing the given float value, in the
+     * current byte order, into this buffer at the current position, and then
+     * increments the position by four.  </p>
+     *
+     * @param  value
+     *         The float value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there are fewer than four bytes
+     *          remaining in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putFloat(float value);
+
+    /**
+     * Absolute <i>get</i> method for reading a float value.
+     *
+     * <p> Reads four bytes at the given index, composing them into a
+     * float value according to the current byte order.  </p>
+     *
+     * @param  index
+     *         The index from which the bytes will be read
+     *
+     * @return  The float value at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus three
+     */
+    public abstract float getFloat(int index);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract float getFloatUnchecked(int index);
+    abstract void getUnchecked(int pos, float[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Absolute <i>put</i> method for writing a float
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes four bytes containing the given float value, in the
+     * current byte order, into this buffer at the given index.  </p>
+     *
+     * @param  index
+     *         The index at which the bytes will be written
+     *
+     * @param  value
+     *         The float value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus three
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putFloat(int index, float value);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putFloatUnchecked(int index, float value);
+    abstract void putUnchecked(int pos, float[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Creates a view of this byte buffer as a float buffer.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of bytes remaining in this buffer divided by
+     * four, and its mark will be undefined.  The new buffer will be direct
+     * if, and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  A new float buffer
+     */
+    public abstract FloatBuffer asFloatBuffer();
+
+
+    /**
+     * Relative <i>get</i> method for reading a double value.
+     *
+     * <p> Reads the next eight bytes at this buffer's current position,
+     * composing them into a double value according to the current byte order,
+     * and then increments the position by eight.  </p>
+     *
+     * @return  The double value at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than eight bytes
+     *          remaining in this buffer
+     */
+    public abstract double getDouble();
+
+    /**
+     * Relative <i>put</i> method for writing a double
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes eight bytes containing the given double value, in the
+     * current byte order, into this buffer at the current position, and then
+     * increments the position by eight.  </p>
+     *
+     * @param  value
+     *         The double value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there are fewer than eight bytes
+     *          remaining in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putDouble(double value);
+
+    /**
+     * Absolute <i>get</i> method for reading a double value.
+     *
+     * <p> Reads eight bytes at the given index, composing them into a
+     * double value according to the current byte order.  </p>
+     *
+     * @param  index
+     *         The index from which the bytes will be read
+     *
+     * @return  The double value at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus seven
+     */
+    public abstract double getDouble(int index);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract double getDoubleUnchecked(int index);
+    abstract void getUnchecked(int pos, double[] dst, int dstOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Absolute <i>put</i> method for writing a double
+     * value&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes eight bytes containing the given double value, in the
+     * current byte order, into this buffer at the given index.  </p>
+     *
+     * @param  index
+     *         The index at which the bytes will be written
+     *
+     * @param  value
+     *         The double value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit,
+     *          minus seven
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ByteBuffer putDouble(int index, double value);
+
+    // BEGIN Android-added: {get,put}*Unchecked() accessors.
+    abstract void putDoubleUnchecked(int index, double value);
+    abstract void putUnchecked(int pos, double[] dst, int srcOffset, int length);
+    // END Android-added: {get,put}*Unchecked() accessors.
+
+    /**
+     * Creates a view of this byte buffer as a double buffer.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of bytes remaining in this buffer divided by
+     * eight, and its mark will be undefined.  The new buffer will be direct
+     * if, and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  A new double buffer
+     */
+    public abstract DoubleBuffer asDoubleBuffer();
+
+    // BEGIN Android-added: isAccessible(), setAccessible(), for use by frameworks (MediaCodec).
+    /**
+     * @hide
+     */
+    public boolean isAccessible() {
+        return true;
+    }
+
+    /**
+     * @hide
+     */
+    public void setAccessible(boolean value) {
+        throw new UnsupportedOperationException();
+    }
+    // END Android-added: isAccessible(), setAccessible(), for use by frameworks (MediaCodec).
+}
diff --git a/java/nio/ByteBufferAsCharBuffer.java b/java/nio/ByteBufferAsCharBuffer.java
new file mode 100644
index 0000000..9dbb8a6
--- /dev/null
+++ b/java/nio/ByteBufferAsCharBuffer.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsCharBuffer extends CharBuffer {      // package-private
+
+    protected final ByteBuffer bb;
+    protected final int offset;
+    private final ByteOrder order;
+
+    ByteBufferAsCharBuffer(ByteBuffer bb,
+                           int mark, int pos, int lim, int cap,
+                           int off, ByteOrder order) {
+        super(mark, pos, lim, cap);
+        this.bb = bb.duplicate();
+        this.isReadOnly = bb.isReadOnly;
+        // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+        // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+        // DirectByteBuffer.
+        // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method
+        // in art which return the address of the first usable byte of the underlying memory, i.e,
+        // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+        // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+        if (bb instanceof DirectByteBuffer) {
+            this.address = bb.address + off;
+        }
+        this.bb.order(order);
+        this.order = order;
+        offset = off;
+    }
+
+    public CharBuffer slice() {
+        int pos = this.position();
+        int lim = this.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        int off = (pos << 1) + offset;
+        assert (off >= 0);
+        return new ByteBufferAsCharBuffer(bb, -1, 0, rem, rem, off, order);
+    }
+
+    public CharBuffer duplicate() {
+        return new ByteBufferAsCharBuffer(bb,
+                markValue(),
+                position(),
+                limit(),
+                capacity(),
+                offset,
+                order);
+    }
+
+    public CharBuffer asReadOnlyBuffer() {
+        return new ByteBufferAsCharBuffer(bb.asReadOnlyBuffer(),
+                markValue(),
+                position(),
+                limit(),
+                capacity(),
+                offset,
+                order);
+    }
+
+    protected int ix(int i) {
+        return (i << 1) + offset;
+    }
+
+    public char get() {
+        return get(nextGetIndex());
+    }
+
+    public char get(int i) {
+        return bb.getCharUnchecked(ix(checkIndex(i)));
+    }
+
+    public CharBuffer get(char[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        bb.getUnchecked(ix(position), dst, offset, length);
+        position += length;
+        return this;
+    }
+
+    char getUnchecked(int i) {
+        return bb.getCharUnchecked(ix(i));
+    }
+
+    public CharBuffer put(char x) {
+        put(nextPutIndex(), x);
+        return this;
+    }
+
+    public CharBuffer put(int i, char x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        bb.putCharUnchecked(ix(checkIndex(i)), x);
+        return this;
+    }
+
+    public CharBuffer put(char[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        bb.putUnchecked(ix(position), src, offset, length);
+        position += length;
+        return this;
+    }
+
+    public CharBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        if (!(bb instanceof DirectByteBuffer)) {
+            System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 1);
+        } else {
+            Memory.memmove(this, ix(0), this, ix(pos), rem << 1);
+        }
+        position(rem);
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    public boolean isDirect() {
+        return bb.isDirect();
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public String toString(int start, int end) {
+        if ((end > limit()) || (start > end))
+            throw new IndexOutOfBoundsException();
+        try {
+            int len = end - start;
+            char[] ca = new char[len];
+            CharBuffer cb = CharBuffer.wrap(ca);
+            CharBuffer db = this.duplicate();
+            db.position(start);
+            db.limit(end);
+            cb.put(db);
+            return new String(ca);
+        } catch (StringIndexOutOfBoundsException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    // --- Methods to support CharSequence ---
+
+    public CharBuffer subSequence(int start, int end) {
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        pos = (pos <= lim ? pos : lim);
+        int len = lim - pos;
+
+        if ((start < 0) || (end > len) || (start > end))
+            throw new IndexOutOfBoundsException();
+        return new ByteBufferAsCharBuffer(bb,
+                -1,
+                pos + start,
+                pos + end,
+                capacity(),
+                offset,
+                order);
+    }
+
+    public ByteOrder order() {
+        return order;
+    }
+}
diff --git a/java/nio/ByteBufferAsDoubleBuffer.java b/java/nio/ByteBufferAsDoubleBuffer.java
new file mode 100644
index 0000000..ff4a6bf
--- /dev/null
+++ b/java/nio/ByteBufferAsDoubleBuffer.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2000, 2008, 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.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsDoubleBuffer
+        extends DoubleBuffer {            // package-private
+
+    protected final ByteBuffer bb;
+    protected final int offset;
+    private final ByteOrder order;
+
+    ByteBufferAsDoubleBuffer(ByteBuffer bb,
+                             int mark, int pos, int lim, int cap,
+                             int off, ByteOrder order) {
+        super(mark, pos, lim, cap);
+        this.bb = bb.duplicate();
+        this.isReadOnly = bb.isReadOnly;
+        // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+        // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+        // DirectByteBuffer.
+        // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method
+        // in art which return the address of the first usable byte of the underlying memory, i.e,
+        // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+        // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+        if (bb instanceof DirectByteBuffer) {
+            this.address = bb.address + off;
+        }
+        this.bb.order(order);
+        this.order = order;
+        offset = off;
+    }
+
+    public DoubleBuffer slice() {
+        int pos = this.position();
+        int lim = this.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        int off = (pos << 3) + offset;
+        assert (off >= 0);
+        return new ByteBufferAsDoubleBuffer(bb, -1, 0, rem, rem, off, order);
+    }
+
+    public DoubleBuffer duplicate() {
+        return new ByteBufferAsDoubleBuffer(bb,
+                markValue(),
+                position(),
+                limit(),
+                capacity(),
+                offset,
+                order);
+    }
+
+    public DoubleBuffer asReadOnlyBuffer() {
+        return new ByteBufferAsDoubleBuffer(bb.asReadOnlyBuffer(),
+                markValue(),
+                position(),
+                limit(),
+                capacity(),
+                offset,
+                order);
+    }
+
+    protected int ix(int i) {
+        return (i << 3) + offset;
+    }
+
+    public double get() {
+        return get(nextGetIndex());
+    }
+
+    public double get(int i) {
+        return bb.getDoubleUnchecked(ix(checkIndex(i)));
+    }
+
+    public DoubleBuffer get(double[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        bb.getUnchecked(ix(position), dst, offset, length);
+        position += length;
+        return this;
+    }
+
+    public DoubleBuffer put(double x) {
+        put(nextPutIndex(), x);
+        return this;
+    }
+
+    public DoubleBuffer put(int i, double x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        bb.putDoubleUnchecked(ix(checkIndex(i)), x);
+        return this;
+    }
+
+    public DoubleBuffer put(double[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        bb.putUnchecked(ix(position), src, offset, length);
+        position += length;
+        return this;
+    }
+
+    public DoubleBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        if (!(bb instanceof DirectByteBuffer)) {
+            System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 3);
+        } else {
+            Memory.memmove(this, ix(0), this, ix(pos), rem << 3);
+        }
+        position(rem);
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    public boolean isDirect() {
+        return bb.isDirect();
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public ByteOrder order() {
+        return order;
+    }
+}
diff --git a/java/nio/ByteBufferAsFloatBuffer.java b/java/nio/ByteBufferAsFloatBuffer.java
new file mode 100644
index 0000000..8e4e2e8
--- /dev/null
+++ b/java/nio/ByteBufferAsFloatBuffer.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2000, 2008, 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.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsFloatBuffer extends FloatBuffer {       // package-private
+
+    protected final ByteBuffer bb;
+    protected final int offset;
+    private final ByteOrder order;
+
+    ByteBufferAsFloatBuffer(ByteBuffer bb,
+                            int mark, int pos, int lim, int cap,
+                            int off, ByteOrder order) {
+        super(mark, pos, lim, cap);
+        this.bb = bb.duplicate();
+        this.isReadOnly = bb.isReadOnly;
+        // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+        // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+        // DirectByteBuffer.
+        // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method
+        // in art which return the address of the first usable byte of the underlying memory, i.e,
+        // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+        // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+        if (bb instanceof DirectByteBuffer) {
+            this.address = bb.address + off;
+        }
+        this.bb.order(order);
+        this.order = order;
+        offset = off;
+    }
+
+    public FloatBuffer slice() {
+        int pos = this.position();
+        int lim = this.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        int off = (pos << 2) + offset;
+        assert (off >= 0);
+        return new ByteBufferAsFloatBuffer(bb, -1, 0, rem, rem, off, order);
+    }
+
+    public FloatBuffer duplicate() {
+        return new ByteBufferAsFloatBuffer(bb,
+                markValue(),
+                position(),
+                limit(),
+                capacity(),
+                offset,
+                order);
+    }
+
+    public FloatBuffer asReadOnlyBuffer() {
+        return new ByteBufferAsFloatBuffer(bb.asReadOnlyBuffer(),
+                markValue(),
+                position(),
+                limit(),
+                capacity(),
+                offset,
+                order);
+    }
+
+    protected int ix(int i) {
+        return (i << 2) + offset;
+    }
+
+    public float get() {
+        return get(nextGetIndex());
+    }
+
+    public float get(int i) {
+        return bb.getFloatUnchecked(ix(checkIndex(i)));
+    }
+
+    public FloatBuffer get(float[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        bb.getUnchecked(ix(position), dst, offset, length);
+        position += length;
+        return this;
+    }
+
+    public FloatBuffer put(float x) {
+        put(nextPutIndex(), x);
+        return this;
+    }
+
+    public FloatBuffer put(int i, float x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        bb.putFloatUnchecked(ix(checkIndex(i)), x);
+        return this;
+    }
+
+    public FloatBuffer put(float[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        bb.putUnchecked(ix(position), src, offset, length);
+        position += length;
+        return this;
+    }
+
+    public FloatBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        if (!(bb instanceof DirectByteBuffer)) {
+            System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 2);
+        } else {
+            Memory.memmove(this, ix(0), this, ix(pos), rem << 2);
+        }
+        position(rem);
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    public boolean isDirect() {
+        return bb.isDirect();
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public ByteOrder order() {
+        return order;
+    }
+}
diff --git a/java/nio/ByteBufferAsIntBuffer.java b/java/nio/ByteBufferAsIntBuffer.java
new file mode 100644
index 0000000..e340426
--- /dev/null
+++ b/java/nio/ByteBufferAsIntBuffer.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2000, 2008, 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.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsIntBuffer extends IntBuffer {        // package-private
+
+    protected final ByteBuffer bb;
+    protected final int offset;
+    private final ByteOrder order;
+
+    ByteBufferAsIntBuffer(ByteBuffer bb,
+                          int mark, int pos, int lim, int cap,
+                          int off, ByteOrder order) {
+        super(mark, pos, lim, cap);
+        this.bb = bb.duplicate();
+        this.isReadOnly = bb.isReadOnly;
+        // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+        // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+        // DirectByteBuffer.
+        // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method
+        // in art which return the address of the first usable byte of the underlying memory, i.e,
+        // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+        // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+        if (bb instanceof DirectByteBuffer) {
+            this.address = bb.address + off;
+        }
+        this.bb.order(order);
+        this.order = order;
+        offset = off;
+    }
+
+    public IntBuffer slice() {
+        int pos = this.position();
+        int lim = this.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        int off = (pos << 2) + offset;
+        assert (off >= 0);
+        return new ByteBufferAsIntBuffer(bb, -1, 0, rem, rem, off, order);
+    }
+
+    public IntBuffer duplicate() {
+        return new ByteBufferAsIntBuffer(bb,
+                markValue(),
+                position(),
+                limit(),
+                capacity(),
+                offset,
+                order);
+    }
+
+    public IntBuffer asReadOnlyBuffer() {
+        return new ByteBufferAsIntBuffer(bb.asReadOnlyBuffer(),
+                markValue(),
+                position(),
+                limit(),
+                capacity(),
+                offset,
+                order);
+    }
+
+    protected int ix(int i) {
+        return (i << 2) + offset;
+    }
+
+    public int get() {
+        return get(nextGetIndex());
+    }
+
+    public int get(int i) {
+        return bb.getIntUnchecked(ix(checkIndex(i)));
+    }
+
+    public IntBuffer get(int[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        bb.getUnchecked(ix(position), dst, offset, length);
+        position += length;
+        return this;
+    }
+
+    public IntBuffer put(int x) {
+        put(nextPutIndex(), x);
+        return this;
+    }
+
+    public IntBuffer put(int i, int x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        bb.putIntUnchecked(ix(checkIndex(i)), x);
+        return this;
+    }
+
+    public IntBuffer put(int[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        bb.putUnchecked(ix(position), src, offset, length);
+        position += length;
+        return this;
+    }
+
+    public IntBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        if (!(bb instanceof DirectByteBuffer)) {
+            System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 2);
+        } else {
+            Memory.memmove(this, ix(0), this, ix(pos), rem << 2);
+        }
+        position(rem);
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    public boolean isDirect() {
+        return bb.isDirect();
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public ByteOrder order() {
+        return order;
+    }
+}
diff --git a/java/nio/ByteBufferAsLongBuffer.java b/java/nio/ByteBufferAsLongBuffer.java
new file mode 100644
index 0000000..70f59c9
--- /dev/null
+++ b/java/nio/ByteBufferAsLongBuffer.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2000, 2008, 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.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsLongBuffer extends LongBuffer {                 // package-private
+
+    protected final ByteBuffer bb;
+    protected final int offset;
+    private final ByteOrder order;
+
+    ByteBufferAsLongBuffer(ByteBuffer bb,
+                           int mark, int pos, int lim, int cap,
+                           int off, ByteOrder order) {
+        super(mark, pos, lim, cap);
+        this.bb = bb.duplicate();
+        this.isReadOnly = bb.isReadOnly;
+        // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+        // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+        // DirectByteBuffer.
+        // The address field is used by NIOAccess#getBasePointer and GetDirectBufferAddress method
+        // in art which return the address of the first usable byte of the underlying memory, i.e,
+        // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+        // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+        if (bb instanceof DirectByteBuffer) {
+            this.address = bb.address + off;
+        }
+        this.bb.order(order);
+        this.order = order;
+        offset = off;
+    }
+
+    public LongBuffer slice() {
+        int pos = this.position();
+        int lim = this.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        int off = (pos << 3) + offset;
+        assert (off >= 0);
+        return new ByteBufferAsLongBuffer(bb, -1, 0, rem, rem, off, order);
+    }
+
+    public LongBuffer duplicate() {
+        return new ByteBufferAsLongBuffer(bb,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset,
+                order);
+    }
+
+    public LongBuffer asReadOnlyBuffer() {
+        return new ByteBufferAsLongBuffer(bb.asReadOnlyBuffer(),
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset,
+                order);
+    }
+
+    protected int ix(int i) {
+        return (i << 3) + offset;
+    }
+
+    public long get() {
+        return get(nextGetIndex());
+    }
+
+    public long get(int i) {
+        return bb.getLongUnchecked(ix(checkIndex(i)));
+    }
+
+    public LongBuffer get(long[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        bb.getUnchecked(ix(position), dst, offset, length);
+        position += length;
+        return this;
+    }
+
+    public LongBuffer put(long x) {
+        put(nextPutIndex(), x);
+        return this;
+    }
+
+    public LongBuffer put(int i, long x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        bb.putLongUnchecked(ix(checkIndex(i)), x);
+        return this;
+    }
+
+    public LongBuffer put(long[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        bb.putUnchecked(ix(position), src, offset, length);
+        position += length;
+        return this;
+    }
+
+    public LongBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        if (!(bb instanceof DirectByteBuffer)) {
+            System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 3);
+        } else {
+            Memory.memmove(this, ix(0), this, ix(pos), rem << 3);
+        }
+        position(rem);
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    public boolean isDirect() {
+        return bb.isDirect();
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public ByteOrder order() {
+        return order;
+    }
+}
diff --git a/java/nio/ByteBufferAsShortBuffer.java b/java/nio/ByteBufferAsShortBuffer.java
new file mode 100644
index 0000000..5178a7e
--- /dev/null
+++ b/java/nio/ByteBufferAsShortBuffer.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2000, 2008, 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.nio;
+
+import libcore.io.Memory;
+
+class ByteBufferAsShortBuffer extends ShortBuffer {       // package-private
+
+    protected final ByteBuffer bb;
+    protected final int offset;
+    private final ByteOrder order;
+
+    ByteBufferAsShortBuffer(ByteBuffer bb,
+                            int mark, int pos, int lim, int cap,
+                            int off, ByteOrder order) {
+        super(mark, pos, lim, cap);
+        this.bb = bb.duplicate();
+        this.isReadOnly = bb.isReadOnly;
+        // There are only two possibilities for the type of ByteBuffer "bb", viz, DirectByteBuffer and
+        // HeapByteBuffer. We only have to initialize the field when bb is an instance of
+        // DirectByteBuffer.
+        // The address field is use by NIOAccess#getBasePointer and GetDirectBufferAddress method
+        // in art which return the address of the first usable byte of the underlying memory, i.e,
+        // the position of parent buffer. Therefore, value of "off" will be equal to parent buffer's
+        // position when the method is called from either HeapByteBuffer or DirectByteBuffer.
+        if (bb instanceof DirectByteBuffer) {
+            this.address = bb.address + off;
+        }
+        this.bb.order(order);
+        this.order = order;
+        offset = off;
+    }
+
+    public ShortBuffer slice() {
+        int pos = this.position();
+        int lim = this.limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        int off = (pos << 1) + offset;
+        assert (off >= 0);
+        return new ByteBufferAsShortBuffer(bb, -1, 0, rem, rem, off, order);
+    }
+
+    public ShortBuffer duplicate() {
+        return new ByteBufferAsShortBuffer(bb,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset, order);
+    }
+
+    public ShortBuffer asReadOnlyBuffer() {
+        return new ByteBufferAsShortBuffer(bb.asReadOnlyBuffer(),
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset, order);
+    }
+
+    protected int ix(int i) {
+        return (i << 1) + offset;
+    }
+
+    public short get() {
+        return get(nextGetIndex());
+    }
+
+    public short get(int i) {
+        return bb.getShortUnchecked(ix(checkIndex(i)));
+
+    }
+
+    public ShortBuffer get(short[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        bb.getUnchecked(ix(position), dst, offset, length);
+        position += length;
+        return this;
+    }
+
+    public ShortBuffer put(short x) {
+        put(nextPutIndex(), x);
+        return this;
+    }
+
+    public ShortBuffer put(int i, short x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        bb.putShortUnchecked(ix(checkIndex(i)), x);
+        return this;
+    }
+
+    public ShortBuffer put(short[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        bb.putUnchecked(ix(position), src, offset, length);
+        position += length;
+        return this;
+    }
+
+    public ShortBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        if (!(bb instanceof DirectByteBuffer)) {
+            System.arraycopy(bb.array(), ix(pos), bb.array(), ix(0), rem << 1);
+        } else {
+            Memory.memmove(this, ix(0), this, ix(pos), rem << 1);
+        }
+        position(rem);
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    public boolean isDirect() {
+        return bb.isDirect();
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public ByteOrder order() {
+        return order;
+    }
+}
diff --git a/java/nio/ByteOrder.java b/java/nio/ByteOrder.java
new file mode 100644
index 0000000..a20cacc
--- /dev/null
+++ b/java/nio/ByteOrder.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio;
+
+
+/**
+ * A typesafe enumeration for byte orders.
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public final class ByteOrder {
+
+    private String name;
+
+    private ByteOrder(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Constant denoting big-endian byte order.  In this order, the bytes of a
+     * multibyte value are ordered from most significant to least significant.
+     */
+    public static final ByteOrder BIG_ENDIAN
+        = new ByteOrder("BIG_ENDIAN");
+
+    /**
+     * Constant denoting little-endian byte order.  In this order, the bytes of
+     * a multibyte value are ordered from least significant to most
+     * significant.
+     */
+    public static final ByteOrder LITTLE_ENDIAN
+        = new ByteOrder("LITTLE_ENDIAN");
+
+    /**
+     * Retrieves the native byte order of the underlying platform.
+     *
+     * <p> This method is defined so that performance-sensitive Java code can
+     * allocate direct buffers with the same byte order as the hardware.
+     * Native code libraries are often more efficient when such buffers are
+     * used.  </p>
+     *
+     * @return  The native byte order of the hardware upon which this Java
+     *          virtual machine is running
+     */
+    public static ByteOrder nativeOrder() {
+        return Bits.byteOrder();
+    }
+
+    /**
+     * Constructs a string describing this object.
+     *
+     * <p> This method returns the string <tt>"BIG_ENDIAN"</tt> for {@link
+     * #BIG_ENDIAN} and <tt>"LITTLE_ENDIAN"</tt> for {@link #LITTLE_ENDIAN}.
+     * </p>
+     *
+     * @return  The specified string
+     */
+    public String toString() {
+        return name;
+    }
+
+}
diff --git a/java/nio/CharBuffer.java b/java/nio/CharBuffer.java
new file mode 100644
index 0000000..6d73448
--- /dev/null
+++ b/java/nio/CharBuffer.java
@@ -0,0 +1,1274 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import java.io.IOException;
+import java.util.Spliterator;
+import java.util.stream.StreamSupport;
+import java.util.stream.IntStream;
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+
+/**
+ * A char buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * char buffers:
+ *
+ * <ul>
+ *
+ *   <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ *   {@link #put(char) <i>put</i>} methods that read and write
+ *   single chars; </p></li>
+ *
+ *   <li><p> Relative {@link #get(char[]) <i>bulk get</i>}
+ *   methods that transfer contiguous sequences of chars from this buffer
+ *   into an array; and</p></li>
+ *
+ *   <li><p> Relative {@link #put(char[]) <i>bulk put</i>}
+ *   methods that transfer contiguous sequences of chars from a
+ *   char array,&#32;a&#32;string, or some other char
+ *   buffer into this buffer;&#32;and </p></li>
+ *
+ *
+ *   <li><p> Methods for {@link #compact compacting}, {@link
+ *   #duplicate duplicating}, and {@link #slice slicing}
+ *   a char buffer.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> Char buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(char[]) <i>wrapping</i>} an existing
+ * char array or&#32;string into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, a char buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>.  A
+ * char buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct.  A char buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct.  Whether or not
+ * a char buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method.  </p>
+ *
+*
+ *
+ * <p> This class implements the {@link CharSequence} interface so that
+ * character buffers may be used wherever character sequences are accepted, for
+ * example in the regular-expression package <tt>{@link java.util.regex}</tt>.
+ * </p>
+ *
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked.  This allows
+ * method invocations to be chained.
+ *
+ *
+ * The sequence of statements
+ *
+ * <blockquote><pre>
+ * cb.put("text/");
+ * cb.put(subtype);
+ * cb.put("; charset=");
+ * cb.put(enc);</pre></blockquote>
+ *
+ * can, for example, be replaced by the single statement
+ *
+ * <blockquote><pre>
+ * cb.put("text/").put(subtype).put("; charset=").put(enc);</pre></blockquote>
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class CharBuffer
+    extends Buffer
+    implements Comparable<CharBuffer>, Appendable, CharSequence, Readable
+{
+
+    // These fields are declared here rather than in Heap-X-Buffer in order to
+    // reduce the number of virtual method invocations needed to access these
+    // values, which is especially costly when coding small buffers.
+    //
+    final char[] hb;                  // Non-null only for heap buffers
+    final int offset;
+    boolean isReadOnly;                 // Valid only for heap buffers
+
+    // Creates a new buffer with the given mark, position, limit, capacity,
+    // backing array, and array offset
+    //
+    CharBuffer(int mark, int pos, int lim, int cap,   // package-private
+                 char[] hb, int offset)
+    {
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 1 /* elementSizeShift */);
+        this.hb = hb;
+        this.offset = offset;
+    }
+
+    // Creates a new buffer with the given mark, position, limit, and capacity
+    //
+    CharBuffer(int mark, int pos, int lim, int cap) { // package-private
+        this(mark, pos, lim, cap, null, 0);
+    }
+
+
+    /**
+     * Allocates a new char buffer.
+     *
+     * <p> The new buffer's position will be zero, its limit will be its
+     * capacity, its mark will be undefined, and each of its elements will be
+     * initialized to zero.  It will have a {@link #array backing array},
+     * and its {@link #arrayOffset array offset} will be zero.
+     *
+     * @param  capacity
+     *         The new buffer's capacity, in chars
+     *
+     * @return  The new char buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the <tt>capacity</tt> is a negative integer
+     */
+    public static CharBuffer allocate(int capacity) {
+        if (capacity < 0)
+            throw new IllegalArgumentException();
+        return new HeapCharBuffer(capacity, capacity);
+    }
+
+    /**
+     * Wraps a char array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given char array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity will be
+     * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+     * will be <tt>offset + length</tt>, and its mark will be undefined.  Its
+     * {@link #array backing array} will be the given array, and
+     * its {@link #arrayOffset array offset} will be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back the new buffer
+     *
+     * @param  offset
+     *         The offset of the subarray to be used; must be non-negative and
+     *         no larger than <tt>array.length</tt>.  The new buffer's position
+     *         will be set to this value.
+     *
+     * @param  length
+     *         The length of the subarray to be used;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>.
+     *         The new buffer's limit will be set to <tt>offset + length</tt>.
+     *
+     * @return  The new char buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public static CharBuffer wrap(char[] array,
+                                    int offset, int length)
+    {
+        try {
+            return new HeapCharBuffer(array, offset, length);
+        } catch (IllegalArgumentException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Wraps a char array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given char array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity and limit will be
+     * <tt>array.length</tt>, its position will be zero, and its mark will be
+     * undefined.  Its {@link #array backing array} will be the
+     * given array, and its {@link #arrayOffset array offset>} will
+     * be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back this buffer
+     *
+     * @return  The new char buffer
+     */
+    public static CharBuffer wrap(char[] array) {
+        return wrap(array, 0, array.length);
+    }
+
+
+    /**
+     * Attempts to read characters into the specified character buffer.
+     * The buffer is used as a repository of characters as-is: the only
+     * changes made are the results of a put operation. No flipping or
+     * rewinding of the buffer is performed.
+     *
+     * @param target the buffer to read characters into
+     * @return The number of characters added to the buffer, or
+     *         -1 if this source of characters is at its end
+     * @throws IOException if an I/O error occurs
+     * @throws NullPointerException if target is null
+     * @throws ReadOnlyBufferException if target is a read only buffer
+     * @since 1.5
+     */
+    public int read(CharBuffer target) throws IOException {
+        // Determine the number of bytes n that can be transferred
+        int targetRemaining = target.remaining();
+        int remaining = remaining();
+        if (remaining == 0)
+            return -1;
+        int n = Math.min(remaining, targetRemaining);
+        int limit = limit();
+        // Set source limit to prevent target overflow
+        if (targetRemaining < remaining)
+            limit(position() + n);
+        try {
+            if (n > 0)
+                target.put(this);
+        } finally {
+            limit(limit); // restore real limit
+        }
+        return n;
+    }
+
+    /**
+     * Wraps a character sequence into a buffer.
+     *
+     * <p> The content of the new, read-only buffer will be the content of the
+     * given character sequence.  The buffer's capacity will be
+     * <tt>csq.length()</tt>, its position will be <tt>start</tt>, its limit
+     * will be <tt>end</tt>, and its mark will be undefined.  </p>
+     *
+     * @param  csq
+     *         The character sequence from which the new character buffer is to
+     *         be created
+     *
+     * @param  start
+     *         The index of the first character to be used;
+     *         must be non-negative and no larger than <tt>csq.length()</tt>.
+     *         The new buffer's position will be set to this value.
+     *
+     * @param  end
+     *         The index of the character following the last character to be
+     *         used; must be no smaller than <tt>start</tt> and no larger
+     *         than <tt>csq.length()</tt>.
+     *         The new buffer's limit will be set to this value.
+     *
+     * @return  The new character buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>start</tt> and <tt>end</tt>
+     *          parameters do not hold
+     */
+    public static CharBuffer wrap(CharSequence csq, int start, int end) {
+        try {
+            return new StringCharBuffer(csq, start, end);
+        } catch (IllegalArgumentException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Wraps a character sequence into a buffer.
+     *
+     * <p> The content of the new, read-only buffer will be the content of the
+     * given character sequence.  The new buffer's capacity and limit will be
+     * <tt>csq.length()</tt>, its position will be zero, and its mark will be
+     * undefined.  </p>
+     *
+     * @param  csq
+     *         The character sequence from which the new character buffer is to
+     *         be created
+     *
+     * @return  The new character buffer
+     */
+    public static CharBuffer wrap(CharSequence csq) {
+        return wrap(csq, 0, csq.length());
+    }
+
+
+    /**
+     * Creates a new char buffer whose content is a shared subsequence of
+     * this buffer's content.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of chars remaining in this buffer, and its mark
+     * will be undefined.  The new buffer will be direct if, and only if, this
+     * buffer is direct, and it will be read-only if, and only if, this buffer
+     * is read-only.  </p>
+     *
+     * @return  The new char buffer
+     */
+    public abstract CharBuffer slice();
+
+    /**
+     * Creates a new char buffer that shares this buffer's content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer, and vice
+     * versa; the two buffers' position, limit, and mark values will be
+     * independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.  The new buffer will be direct if,
+     * and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  The new char buffer
+     */
+    public abstract CharBuffer duplicate();
+
+    /**
+     * Creates a new, read-only char buffer that shares this buffer's
+     * content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer; the new
+     * buffer itself, however, will be read-only and will not allow the shared
+     * content to be modified.  The two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.
+     *
+     * <p> If this buffer is itself read-only then this method behaves in
+     * exactly the same way as the {@link #duplicate duplicate} method.  </p>
+     *
+     * @return  The new, read-only char buffer
+     */
+    public abstract CharBuffer asReadOnlyBuffer();
+
+
+    // -- Singleton get/put methods --
+
+    /**
+     * Relative <i>get</i> method.  Reads the char at this buffer's
+     * current position, and then increments the position.
+     *
+     * @return  The char at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If the buffer's current position is not smaller than its limit
+     */
+    public abstract char get();
+
+    /**
+     * Relative <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given char into this buffer at the current
+     * position, and then increments the position. </p>
+     *
+     * @param  c
+     *         The char to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If this buffer's current position is not smaller than its limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract CharBuffer put(char c);
+
+    /**
+     * Absolute <i>get</i> method.  Reads the char at the given
+     * index.
+     *
+     * @param  index
+     *         The index from which the char will be read
+     *
+     * @return  The char at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     */
+    public abstract char get(int index);
+
+    /**
+     * Absolute <i>get</i> method.  Reads the char at the given
+     * index without any validation of the index.
+     *
+     * @param  index
+     *         The index from which the char will be read
+     *
+     * @return  The char at the given index
+     */
+    abstract char getUnchecked(int index);   // package-private
+
+    /**
+     * Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given char into this buffer at the given
+     * index. </p>
+     *
+     * @param  index
+     *         The index at which the char will be written
+     *
+     * @param  c
+     *         The char value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract CharBuffer put(int index, char c);
+
+
+    // -- Bulk get operations --
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers chars from this buffer into the given
+     * destination array.  If there are fewer chars remaining in the
+     * buffer than are required to satisfy the request, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * chars are transferred and a {@link BufferUnderflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> chars from this
+     * buffer into the given array, starting at the current position of this
+     * buffer and at the given offset in the array.  The position of this
+     * buffer is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>src.get(dst,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst[i] = src.get();
+     * }</pre>
+     *
+     * except that it first checks that there are sufficient chars in
+     * this buffer and it is potentially much more efficient.
+     *
+     * @param  dst
+     *         The array into which chars are to be written
+     *
+     * @param  offset
+     *         The offset within the array of the first char to be
+     *         written; must be non-negative and no larger than
+     *         <tt>dst.length</tt>
+     *
+     * @param  length
+     *         The maximum number of chars to be written to the given
+     *         array; must be non-negative and no larger than
+     *         <tt>dst.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> chars
+     *          remaining in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public CharBuffer get(char[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            dst[i] = get();
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers chars from this buffer into the given
+     * destination array.  An invocation of this method of the form
+     * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     src.get(a, 0, a.length) </pre>
+     *
+     * @param   dst
+     *          The destination array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> chars
+     *          remaining in this buffer
+     */
+    public CharBuffer get(char[] dst) {
+        return get(dst, 0, dst.length);
+    }
+
+
+    // -- Bulk put operations --
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the chars remaining in the given source
+     * buffer into this buffer.  If there are more chars remaining in the
+     * source buffer than in this buffer, that is, if
+     * <tt>src.remaining()</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>,
+     * then no chars are transferred and a {@link
+     * BufferOverflowException} is thrown.
+     *
+     * <p> Otherwise, this method copies
+     * <i>n</i>&nbsp;=&nbsp;<tt>src.remaining()</tt> chars from the given
+     * buffer into this buffer, starting at each buffer's current position.
+     * The positions of both buffers are then incremented by <i>n</i>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+     *
+     * <pre>
+     *     while (src.hasRemaining())
+     *         dst.put(src.get()); </pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The source buffer from which chars are to be read;
+     *         must not be this buffer
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *          for the remaining chars in the source buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the source buffer is this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public CharBuffer put(CharBuffer src) {
+        if (src == this)
+            throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
+        int n = src.remaining();
+        if (n > remaining())
+            throw new BufferOverflowException();
+        for (int i = 0; i < n; i++)
+            put(src.get());
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers chars into this buffer from the given
+     * source array.  If there are more chars to be copied from the array
+     * than remain in this buffer, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * chars are transferred and a {@link BufferOverflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> chars from the
+     * given array into this buffer, starting at the given offset in the array
+     * and at the current position of this buffer.  The position of this buffer
+     * is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst.put(a[i]);
+     * }</pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The array from which chars are to be read
+     *
+     * @param  offset
+     *         The offset within the array of the first char to be read;
+     *         must be non-negative and no larger than <tt>array.length</tt>
+     *
+     * @param  length
+     *         The number of chars to be read from the given array;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public CharBuffer put(char[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            this.put(src[i]);
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the entire content of the given source
+     * char array into this buffer.  An invocation of this method of the
+     * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+     * invocation
+     *
+     * <pre>
+     *     dst.put(a, 0, a.length) </pre>
+     *
+     * @param   src
+     *          The source array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public final CharBuffer put(char[] src) {
+        return put(src, 0, src.length);
+    }
+
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers chars from the given string into this
+     * buffer.  If there are more chars to be copied from the string than
+     * remain in this buffer, that is, if
+     * <tt>end&nbsp;-&nbsp;start</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>,
+     * then no chars are transferred and a {@link
+     * BufferOverflowException} is thrown.
+     *
+     * <p> Otherwise, this method copies
+     * <i>n</i>&nbsp;=&nbsp;<tt>end</tt>&nbsp;-&nbsp;<tt>start</tt> chars
+     * from the given string into this buffer, starting at the given
+     * <tt>start</tt> index and at the current position of this buffer.  The
+     * position of this buffer is then incremented by <i>n</i>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src,&nbsp;start,&nbsp;end)</tt> has exactly the same effect
+     * as the loop
+     *
+     * <pre>{@code
+     *     for (int i = start; i < end; i++)
+     *         dst.put(src.charAt(i));
+     * }</pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The string from which chars are to be read
+     *
+     * @param  start
+     *         The offset within the string of the first char to be read;
+     *         must be non-negative and no larger than
+     *         <tt>string.length()</tt>
+     *
+     * @param  end
+     *         The offset within the string of the last char to be read,
+     *         plus one; must be non-negative and no larger than
+     *         <tt>string.length()</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>start</tt> and <tt>end</tt>
+     *          parameters do not hold
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public CharBuffer put(String src, int start, int end) {
+        checkBounds(start, end - start, src.length());
+
+        // BEGIN Android-added: Don't check readonly/overflow if there's nothing to write.
+        // This is questionable behaviour but code expects it.
+        if (start == end) {
+            return this;
+        }
+        // END Android-added: Don't check readonly/overflow if there's nothing to write.
+
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
+        if (end - start > remaining())
+            throw new BufferOverflowException();
+        for (int i = start; i < end; i++)
+            this.put(src.charAt(i));
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the entire content of the given source string
+     * into this buffer.  An invocation of this method of the form
+     * <tt>dst.put(s)</tt> behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     dst.put(s, 0, s.length()) </pre>
+     *
+     * @param   src
+     *          The source string
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public final CharBuffer put(String src) {
+        return put(src, 0, src.length());
+    }
+
+
+    // -- Other stuff --
+
+    /**
+     * Tells whether or not this buffer is backed by an accessible char
+     * array.
+     *
+     * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+     * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+     * </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer
+     *          is backed by an array and is not read-only
+     */
+    public final boolean hasArray() {
+        return (hb != null) && !isReadOnly;
+    }
+
+    /**
+     * Returns the char array that backs this
+     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Modifications to this buffer's content will cause the returned
+     * array's content to be modified, and vice versa.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The array that backs this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final char[] array() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return hb;
+    }
+
+    /**
+     * Returns the offset within this buffer's backing array of the first
+     * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> If this buffer is backed by an array then buffer position <i>p</i>
+     * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The offset within this buffer's array
+     *          of the first element of the buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final int arrayOffset() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return offset;
+    }
+
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = CharBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
+    /**
+     * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> The chars between the buffer's current position and its limit,
+     * if any, are copied to the beginning of the buffer.  That is, the
+     * char at index <i>p</i>&nbsp;=&nbsp;<tt>position()</tt> is copied
+     * to index zero, the char at index <i>p</i>&nbsp;+&nbsp;1 is copied
+     * to index one, and so forth until the char at index
+     * <tt>limit()</tt>&nbsp;-&nbsp;1 is copied to index
+     * <i>n</i>&nbsp;=&nbsp;<tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>&nbsp;-&nbsp;<i>p</i>.
+     * The buffer's position is then set to <i>n+1</i> and its limit is set to
+     * its capacity.  The mark, if defined, is discarded.
+     *
+     * <p> The buffer's position is set to the number of chars copied,
+     * rather than to zero, so that an invocation of this method can be
+     * followed immediately by an invocation of another relative <i>put</i>
+     * method. </p>
+     *
+
+     *
+     * @return  This buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract CharBuffer compact();
+
+    /**
+     * Tells whether or not this char buffer is direct.
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is direct
+     */
+    public abstract boolean isDirect();
+
+
+    /**
+     * Returns the current hash code of this buffer.
+     *
+     * <p> The hash code of a char buffer depends only upon its remaining
+     * elements; that is, upon the elements from <tt>position()</tt> up to, and
+     * including, the element at <tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>.
+     *
+     * <p> Because buffer hash codes are content-dependent, it is inadvisable
+     * to use buffers as keys in hash maps or similar data structures unless it
+     * is known that their contents will not change.  </p>
+     *
+     * @return  The current hash code of this buffer
+     */
+    public int hashCode() {
+        int h = 1;
+        int p = position();
+        for (int i = limit() - 1; i >= p; i--)
+            h = 31 * h + (int) get(i);
+        return h;
+    }
+
+    /**
+     * Tells whether or not this buffer is equal to another object.
+     *
+     * <p> Two char buffers are equal if, and only if,
+     *
+     * <ol>
+     *
+     *   <li><p> They have the same element type,  </p></li>
+     *
+     *   <li><p> They have the same number of remaining elements, and
+     *   </p></li>
+     *
+     *   <li><p> The two sequences of remaining elements, considered
+     *   independently of their starting positions, are pointwise equal.
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     *   </p></li>
+     *
+     * </ol>
+     *
+     * <p> A char buffer is not equal to any other type of object.  </p>
+     *
+     * @param  ob  The object to which this buffer is to be compared
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is equal to the
+     *           given object
+     */
+    public boolean equals(Object ob) {
+        if (this == ob)
+            return true;
+        if (!(ob instanceof CharBuffer))
+            return false;
+        CharBuffer that = (CharBuffer)ob;
+        if (this.remaining() != that.remaining())
+            return false;
+        int p = this.position();
+        for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+            if (!equals(this.get(i), that.get(j)))
+                return false;
+        return true;
+    }
+
+    private static boolean equals(char x, char y) {
+
+
+        return x == y;
+
+    }
+
+    /**
+     * Compares this buffer to another.
+     *
+     * <p> Two char buffers are compared by comparing their sequences of
+     * remaining elements lexicographically, without regard to the starting
+     * position of each sequence within its corresponding buffer.
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     * Pairs of {@code char} elements are compared as if by invoking
+     * {@link Character#compare(char,char)}.
+
+     *
+     * <p> A char buffer is not comparable to any other type of object.
+     *
+     * @return  A negative integer, zero, or a positive integer as this buffer
+     *          is less than, equal to, or greater than the given buffer
+     */
+    public int compareTo(CharBuffer that) {
+        int n = this.position() + Math.min(this.remaining(), that.remaining());
+        for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+            int cmp = compare(this.get(i), that.get(j));
+            if (cmp != 0)
+                return cmp;
+        }
+        return this.remaining() - that.remaining();
+    }
+
+    private static int compare(char x, char y) {
+
+
+        return Character.compare(x, y);
+
+    }
+
+    // -- Other char stuff --
+
+
+    /**
+     * Returns a string containing the characters in this buffer.
+     *
+     * <p> The first character of the resulting string will be the character at
+     * this buffer's position, while the last character will be the character
+     * at index <tt>limit()</tt>&nbsp;-&nbsp;1.  Invoking this method does not
+     * change the buffer's position. </p>
+     *
+     * @return  The specified string
+     */
+    public String toString() {
+        return toString(position(), limit());
+    }
+
+    abstract String toString(int start, int end);       // package-private
+
+
+    // --- Methods to support CharSequence ---
+
+    /**
+     * Returns the length of this character buffer.
+     *
+     * <p> When viewed as a character sequence, the length of a character
+     * buffer is simply the number of characters between the position
+     * (inclusive) and the limit (exclusive); that is, it is equivalent to
+     * <tt>remaining()</tt>. </p>
+     *
+     * @return  The length of this character buffer
+     */
+    public final int length() {
+        return remaining();
+    }
+
+    /**
+     * Reads the character at the given index relative to the current
+     * position.
+     *
+     * @param  index
+     *         The index of the character to be read, relative to the position;
+     *         must be non-negative and smaller than <tt>remaining()</tt>
+     *
+     * @return  The character at index
+     *          <tt>position()&nbsp;+&nbsp;index</tt>
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on <tt>index</tt> do not hold
+     */
+    public final char charAt(int index) {
+        return get(position() + checkIndex(index, 1));
+    }
+
+    /**
+     * Creates a new character buffer that represents the specified subsequence
+     * of this buffer, relative to the current position.
+     *
+     * <p> The new buffer will share this buffer's content; that is, if the
+     * content of this buffer is mutable then modifications to one buffer will
+     * cause the other to be modified.  The new buffer's capacity will be that
+     * of this buffer, its position will be
+     * <tt>position()</tt>&nbsp;+&nbsp;<tt>start</tt>, and its limit will be
+     * <tt>position()</tt>&nbsp;+&nbsp;<tt>end</tt>.  The new buffer will be
+     * direct if, and only if, this buffer is direct, and it will be read-only
+     * if, and only if, this buffer is read-only.  </p>
+     *
+     * @param  start
+     *         The index, relative to the current position, of the first
+     *         character in the subsequence; must be non-negative and no larger
+     *         than <tt>remaining()</tt>
+     *
+     * @param  end
+     *         The index, relative to the current position, of the character
+     *         following the last character in the subsequence; must be no
+     *         smaller than <tt>start</tt> and no larger than
+     *         <tt>remaining()</tt>
+     *
+     * @return  The new character buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on <tt>start</tt> and <tt>end</tt>
+     *          do not hold
+     */
+    public abstract CharBuffer subSequence(int start, int end);
+
+
+    // --- Methods to support Appendable ---
+
+    /**
+     * Appends the specified character sequence  to this
+     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> An invocation of this method of the form <tt>dst.append(csq)</tt>
+     * behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     dst.put(csq.toString()) </pre>
+     *
+     * <p> Depending on the specification of <tt>toString</tt> for the
+     * character sequence <tt>csq</tt>, the entire sequence may not be
+     * appended.  For instance, invoking the {@link CharBuffer#toString()
+     * toString} method of a character buffer will return a subsequence whose
+     * content depends upon the buffer's position and limit.
+     *
+     * @param  csq
+     *         The character sequence to append.  If <tt>csq</tt> is
+     *         <tt>null</tt>, then the four characters <tt>"null"</tt> are
+     *         appended to this character buffer.
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     *
+     * @since  1.5
+     */
+    public CharBuffer append(CharSequence csq) {
+        if (csq == null)
+            return put("null");
+        else
+            return put(csq.toString());
+    }
+
+    /**
+     * Appends a subsequence of the  specified character sequence  to this
+     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> An invocation of this method of the form <tt>dst.append(csq, start,
+     * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in exactly the
+     * same way as the invocation
+     *
+     * <pre>
+     *     dst.put(csq.subSequence(start, end).toString()) </pre>
+     *
+     * @param  csq
+     *         The character sequence from which a subsequence will be
+     *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
+     *         will be appended as if <tt>csq</tt> contained the four
+     *         characters <tt>"null"</tt>.
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
+     *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
+     *          <tt>csq.length()</tt>
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     *
+     * @since  1.5
+     */
+    public CharBuffer append(CharSequence csq, int start, int end) {
+        CharSequence cs = (csq == null ? "null" : csq);
+        return put(cs.subSequence(start, end).toString());
+    }
+
+    /**
+     * Appends the specified char  to this
+     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> An invocation of this method of the form <tt>dst.append(c)</tt>
+     * behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     dst.put(c) </pre>
+     *
+     * @param  c
+     *         The 16-bit char to append
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     *
+     * @since  1.5
+     */
+    public CharBuffer append(char c) {
+        return put(c);
+    }
+
+
+    // -- Other byte stuff: Access to binary data --
+
+
+    /**
+     * Retrieves this buffer's byte order.
+     *
+     * <p> The byte order of a char buffer created by allocation or by
+     * wrapping an existing <tt>char</tt> array is the {@link
+     * ByteOrder#nativeOrder native order} of the underlying
+     * hardware.  The byte order of a char buffer created as a <a
+     * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+     * byte buffer at the moment that the view is created.  </p>
+     *
+     * @return  This buffer's byte order
+     */
+    public abstract ByteOrder order();
+
+    @Override
+    public IntStream chars() {
+        return StreamSupport.intStream(() -> new CharBufferSpliterator(this),
+            Buffer.SPLITERATOR_CHARACTERISTICS, false);
+    }
+}
diff --git a/java/nio/CharBufferSpliterator.java b/java/nio/CharBufferSpliterator.java
new file mode 100644
index 0000000..5b3977a
--- /dev/null
+++ b/java/nio/CharBufferSpliterator.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio;
+
+import java.util.Comparator;
+import java.util.Spliterator;
+import java.util.function.IntConsumer;
+
+/**
+ * A Spliterator.OfInt for sources that traverse and split elements
+ * maintained in a CharBuffer.
+ *
+ * @implNote
+ * The implementation is based on the code for the Array-based spliterators.
+ */
+class CharBufferSpliterator implements Spliterator.OfInt {
+    private final CharBuffer buffer;
+    private int index;   // current index, modified on advance/split
+    private final int limit;
+
+    CharBufferSpliterator(CharBuffer buffer) {
+        this(buffer, buffer.position(), buffer.limit());
+    }
+
+    CharBufferSpliterator(CharBuffer buffer, int origin, int limit) {
+        assert origin <= limit;
+        this.buffer = buffer;
+        this.index = (origin <= limit) ? origin : limit;
+        this.limit = limit;
+    }
+
+    @Override
+    public OfInt trySplit() {
+        int lo = index, mid = (lo + limit) >>> 1;
+        return (lo >= mid)
+               ? null
+               : new CharBufferSpliterator(buffer, lo, index = mid);
+    }
+
+    @Override
+    public void forEachRemaining(IntConsumer action) {
+        if (action == null)
+            throw new NullPointerException();
+        CharBuffer cb = buffer;
+        int i = index;
+        int hi = limit;
+        index = hi;
+        while (i < hi) {
+            action.accept(cb.getUnchecked(i++));
+        }
+    }
+
+    @Override
+    public boolean tryAdvance(IntConsumer action) {
+        if (action == null)
+            throw new NullPointerException();
+        if (index >= 0 && index < limit) {
+            action.accept(buffer.getUnchecked(index++));
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public long estimateSize() {
+        return (long)(limit - index);
+    }
+
+    @Override
+    public int characteristics() {
+        return Buffer.SPLITERATOR_CHARACTERISTICS;
+    }
+}
diff --git a/java/nio/DirectByteBuffer.annotated.java b/java/nio/DirectByteBuffer.annotated.java
new file mode 100644
index 0000000..51e0e9c
--- /dev/null
+++ b/java/nio/DirectByteBuffer.annotated.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio;
+
+
[email protected]
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class DirectByteBuffer extends java.nio.MappedByteBuffer implements sun.nio.ch.DirectBuffer {
+
[email protected]
+public DirectByteBuffer(int cap, long addr, java.io.FileDescriptor fd, java.lang.Runnable unmapper, boolean isReadOnly) { super(0, 0, 0, 0); throw new RuntimeException("Stub!"); }
+
+public final java.lang.Object attachment() { throw new RuntimeException("Stub!"); }
+
+public final sun.misc.Cleaner cleaner() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer slice() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer duplicate() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer asReadOnlyBuffer() { throw new RuntimeException("Stub!"); }
+
[email protected]
+public final long address() { throw new RuntimeException("Stub!"); }
+
+public final byte get() { throw new RuntimeException("Stub!"); }
+
+public final byte get(int i) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer get(byte[] dst, int dstOffset, int length) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(java.nio.ByteBuffer src) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer put(byte x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer put(int i, byte x) { throw new RuntimeException("Stub!"); }
+
+public java.nio.ByteBuffer put(byte[] src, int srcOffset, int length) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer compact() { throw new RuntimeException("Stub!"); }
+
+public final boolean isDirect() { throw new RuntimeException("Stub!"); }
+
+public final boolean isReadOnly() { throw new RuntimeException("Stub!"); }
+
+public final char getChar() { throw new RuntimeException("Stub!"); }
+
+public final char getChar(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putChar(char x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putChar(int i, char x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.CharBuffer asCharBuffer() { throw new RuntimeException("Stub!"); }
+
+public final short getShort() { throw new RuntimeException("Stub!"); }
+
+public final short getShort(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putShort(short x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putShort(int i, short x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ShortBuffer asShortBuffer() { throw new RuntimeException("Stub!"); }
+
+public int getInt() { throw new RuntimeException("Stub!"); }
+
+public int getInt(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putInt(int x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putInt(int i, int x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.IntBuffer asIntBuffer() { throw new RuntimeException("Stub!"); }
+
+public final long getLong() { throw new RuntimeException("Stub!"); }
+
+public final long getLong(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putLong(long x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putLong(int i, long x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.LongBuffer asLongBuffer() { throw new RuntimeException("Stub!"); }
+
+public final float getFloat() { throw new RuntimeException("Stub!"); }
+
+public final float getFloat(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putFloat(float x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putFloat(int i, float x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.FloatBuffer asFloatBuffer() { throw new RuntimeException("Stub!"); }
+
+public final double getDouble() { throw new RuntimeException("Stub!"); }
+
+public final double getDouble(int i) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putDouble(double x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.ByteBuffer putDouble(int i, double x) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.DoubleBuffer asDoubleBuffer() { throw new RuntimeException("Stub!"); }
+
+public final boolean isAccessible() { throw new RuntimeException("Stub!"); }
+
+public final void setAccessible(boolean value) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/nio/DirectByteBuffer.java b/java/nio/DirectByteBuffer.java
new file mode 100644
index 0000000..3e06011
--- /dev/null
+++ b/java/nio/DirectByteBuffer.java
@@ -0,0 +1,975 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio;
+
+import java.io.FileDescriptor;
+
+import dalvik.system.VMRuntime;
+import libcore.io.Memory;
+import sun.misc.Cleaner;
+import sun.nio.ch.DirectBuffer;
+
+// Not final because it is extended in tests.
+/** @hide */
+public class DirectByteBuffer extends MappedByteBuffer implements DirectBuffer {
+
+    /**
+     * Stores the details of the memory backing a DirectByteBuffer. This could be a pointer
+     * (passed through from JNI or resulting from a mapping) or a non-movable byte array allocated
+     * from Java. Each MemoryRef also has an isAccessible associated with it, which determines
+     * whether the underlying memory is "accessible". The notion of "accessibility" is usually
+     * defined by the allocator of the reference, and is separate from the accessibility of the
+     * memory as defined by the underlying system.
+     *
+     * A single MemoryRef instance is shared across all slices and duplicates of a given buffer.
+     */
+    final static class MemoryRef {
+        byte[] buffer;
+        long allocatedAddress;
+        final int offset;
+        boolean isAccessible;
+        boolean isFreed;
+
+
+        // Reference to original DirectByteBuffer that held this MemoryRef. The field is set
+        // only for the MemoryRef created through JNI NewDirectByteBuffer(void*, long) function.
+        // This allows users of JNI NewDirectByteBuffer to create a PhantomReference on the
+        // DirectByteBuffer instance that will only be put in the associated ReferenceQueue when
+        // the underlying memory is not referenced by any DirectByteBuffer instance. The
+        // MemoryRef can outlive the original DirectByteBuffer instance if, for example, slice()
+        // or asReadOnlyBuffer() are called and all strong references to the original DirectByteBuffer
+        // are discarded.
+        final Object originalBufferObject;
+
+        MemoryRef(int capacity) {
+            VMRuntime runtime = VMRuntime.getRuntime();
+            buffer = (byte[]) runtime.newNonMovableArray(byte.class, capacity + 7);
+            allocatedAddress = runtime.addressOf(buffer);
+            // Offset is set to handle the alignment: http://b/16449607
+            offset = (int) (((allocatedAddress + 7) & ~(long) 7) - allocatedAddress);
+            isAccessible = true;
+            isFreed = false;
+            originalBufferObject = null;
+        }
+
+        MemoryRef(long allocatedAddress, Object originalBufferObject) {
+            buffer = null;
+            this.allocatedAddress = allocatedAddress;
+            this.offset = 0;
+            this.originalBufferObject = originalBufferObject;
+            isAccessible = true;
+        }
+
+        void free() {
+            buffer = null;
+            allocatedAddress = 0;
+            isAccessible = false;
+            isFreed = true;
+        }
+    }
+
+    final Cleaner cleaner;
+    final MemoryRef memoryRef;
+
+    DirectByteBuffer(int capacity, MemoryRef memoryRef) {
+        super(-1, 0, capacity, capacity, memoryRef.buffer, memoryRef.offset);
+        // Only have references to java objects, no need for a cleaner since the GC will do all
+        // the work.
+        this.memoryRef = memoryRef;
+        this.address = memoryRef.allocatedAddress + memoryRef.offset;
+        cleaner = null;
+        this.isReadOnly = false;
+    }
+
+    // Invoked only by JNI: NewDirectByteBuffer(void*, long)
+    @SuppressWarnings("unused")
+    private DirectByteBuffer(long addr, int cap) {
+        super(-1, 0, cap, cap);
+        memoryRef = new MemoryRef(addr, this);
+        address = addr;
+        cleaner = null;
+    }
+
+    /** @hide */
+    public DirectByteBuffer(int cap, long addr,
+                            FileDescriptor fd,
+                            Runnable unmapper,
+                            boolean isReadOnly) {
+        super(-1, 0, cap, cap, fd);
+        this.isReadOnly = isReadOnly;
+        memoryRef = new MemoryRef(addr, null);
+        address = addr;
+        cleaner = Cleaner.create(memoryRef, unmapper);
+    }
+
+    // For duplicates and slices
+    DirectByteBuffer(MemoryRef memoryRef,         // package-private
+                     int mark, int pos, int lim, int cap,
+                     int off) {
+        this(memoryRef, mark, pos, lim, cap, off, false);
+    }
+
+    DirectByteBuffer(MemoryRef memoryRef,         // package-private
+                     int mark, int pos, int lim, int cap,
+                     int off, boolean isReadOnly) {
+        super(mark, pos, lim, cap, memoryRef.buffer, off);
+        this.isReadOnly = isReadOnly;
+        this.memoryRef = memoryRef;
+        address = memoryRef.allocatedAddress + off;
+        cleaner = null;
+    }
+
+    @Override
+    public final Object attachment() {
+        return memoryRef;
+    }
+
+    @Override
+    public final Cleaner cleaner() {
+        return cleaner;
+    }
+
+    @Override
+    public final ByteBuffer slice() {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        int off = pos + offset;
+        assert (off >= 0);
+        return new DirectByteBuffer(memoryRef, -1, 0, rem, rem, off, isReadOnly);
+    }
+
+    @Override
+    public final ByteBuffer duplicate() {
+        if (memoryRef.isFreed) {
+            throw new IllegalStateException("buffer has been freed");
+        }
+        return new DirectByteBuffer(memoryRef,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset,
+                isReadOnly);
+    }
+
+    @Override
+    public final ByteBuffer asReadOnlyBuffer() {
+        if (memoryRef.isFreed) {
+            throw new IllegalStateException("buffer has been freed");
+        }
+        return new DirectByteBuffer(memoryRef,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset,
+                true);
+    }
+
+    @Override
+    public final long address() {
+        return address;
+    }
+
+    private long ix(int i) {
+        return address + i;
+    }
+
+    private byte get(long a) {
+        return Memory.peekByte(a);
+    }
+
+    @Override
+    public final byte get() {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return get(ix(nextGetIndex()));
+    }
+
+    @Override
+    public final byte get(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return get(ix(checkIndex(i)));
+    }
+
+    // This method is not declared final because it is overridden in tests.
+    @Override
+    public ByteBuffer get(byte[] dst, int dstOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        checkBounds(dstOffset, length, dst.length);
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        if (length > rem)
+            throw new BufferUnderflowException();
+        Memory.peekByteArray(ix(pos),
+                dst, dstOffset, length);
+        position = pos + length;
+        return this;
+    }
+
+    private ByteBuffer put(long a, byte x) {
+        Memory.pokeByte(a, x);
+        return this;
+    }
+
+    @Override
+    public ByteBuffer put(ByteBuffer src) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return super.put(src);
+    }
+
+    @Override
+    public final ByteBuffer put(byte x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        put(ix(nextPutIndex()), x);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer put(int i, byte x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        put(ix(checkIndex(i)), x);
+        return this;
+    }
+
+    // This method is not declared final because it is overridden in tests.
+    @Override
+    public ByteBuffer put(byte[] src, int srcOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        checkBounds(srcOffset, length, src.length);
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        if (length > rem)
+            throw new BufferOverflowException();
+        Memory.pokeByteArray(ix(pos),
+                src, srcOffset, length);
+        position = pos + length;
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer compact() {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        int pos = position();
+        int lim = limit();
+        assert (pos <= lim);
+        int rem = (pos <= lim ? lim - pos : 0);
+        System.arraycopy(hb, position + offset, hb, offset, remaining());
+        position(rem);
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    @Override
+    public final boolean isDirect() {
+        return true;
+    }
+
+    @Override
+    public final boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    // Used by java.nio.Bits
+    @Override
+    final byte _get(int i) {                          // package-private
+        return get(i);
+    }
+
+    // Used by java.nio.Bits
+    @Override
+    final void _put(int i, byte b) {                  // package-private
+        put(i, b);
+    }
+
+    @Override
+    public final char getChar() {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        int newPosition = position + Character.BYTES;
+        if (newPosition > limit()) {
+            throw new BufferUnderflowException();
+        }
+        char x = (char) Memory.peekShort(ix(position), !nativeByteOrder);
+        position = newPosition;
+        return x;
+    }
+
+    @Override
+    public final char getChar(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        checkIndex(i, Character.BYTES);
+        return (char) Memory.peekShort(ix(i), !nativeByteOrder);
+    }
+
+    @Override
+    char getCharUnchecked(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return (char) Memory.peekShort(ix(i), !nativeByteOrder);
+    }
+
+    @Override
+    void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.peekCharArray(ix(pos),
+                dst, dstOffset, length, !nativeByteOrder);
+    }
+
+    private ByteBuffer putChar(long a, char x) {
+        Memory.pokeShort(a, (short) x, !nativeByteOrder);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putChar(char x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putChar(ix(nextPutIndex(Character.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putChar(int i, char x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putChar(ix(checkIndex(i, Character.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    void putCharUnchecked(int i, char x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        putChar(ix(i), x);
+    }
+
+    @Override
+    void putUnchecked(int pos, char[] src, int srcOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.pokeCharArray(ix(pos),
+                src, srcOffset, length, !nativeByteOrder);
+    }
+
+    @Override
+    public final CharBuffer asCharBuffer() {
+        if (memoryRef.isFreed) {
+            throw new IllegalStateException("buffer has been freed");
+        }
+        int off = this.position();
+        int lim = this.limit();
+        assert (off <= lim);
+        int rem = (off <= lim ? lim - off : 0);
+        int size = rem >> 1;
+        return new ByteBufferAsCharBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+
+    private short getShort(long a) {
+        return Memory.peekShort(a, !nativeByteOrder);
+    }
+
+    @Override
+    public final short getShort() {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getShort(ix(nextGetIndex(Short.BYTES)));
+    }
+
+    @Override
+    public final short getShort(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getShort(ix(checkIndex(i, Short.BYTES)));
+    }
+
+    @Override
+    short getShortUnchecked(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getShort(ix(i));
+    }
+
+    @Override
+    void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.peekShortArray(ix(pos),
+                dst, dstOffset, length, !nativeByteOrder);
+    }
+
+    private ByteBuffer putShort(long a, short x) {
+        Memory.pokeShort(a, x, !nativeByteOrder);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putShort(short x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putShort(ix(nextPutIndex(Short.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putShort(int i, short x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putShort(ix(checkIndex(i, Short.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    void putShortUnchecked(int i, short x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        putShort(ix(i), x);
+    }
+
+    @Override
+    void putUnchecked(int pos, short[] src, int srcOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.pokeShortArray(ix(pos),
+                src, srcOffset, length, !nativeByteOrder);
+    }
+
+    @Override
+    public final ShortBuffer asShortBuffer() {
+        if (memoryRef.isFreed) {
+            throw new IllegalStateException("buffer has been freed");
+        }
+        int off = this.position();
+        int lim = this.limit();
+        assert (off <= lim);
+        int rem = (off <= lim ? lim - off : 0);
+        int size = rem >> 1;
+        return new ByteBufferAsShortBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+
+    private int getInt(long a) {
+        return Memory.peekInt(a, !nativeByteOrder);
+    }
+
+    @Override
+    public int getInt() {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getInt(ix(nextGetIndex(Integer.BYTES)));
+    }
+
+    @Override
+    public int getInt(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getInt(ix(checkIndex(i, (Integer.BYTES))));
+    }
+
+    @Override
+    final int getIntUnchecked(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getInt(ix(i));
+    }
+
+    @Override
+    final void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.peekIntArray(ix(pos),
+                dst, dstOffset, length, !nativeByteOrder);
+    }
+
+    private ByteBuffer putInt(long a, int x) {
+        Memory.pokeInt(a, x, !nativeByteOrder);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putInt(int x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putInt(ix(nextPutIndex(Integer.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putInt(int i, int x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putInt(ix(checkIndex(i, Integer.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    final void putIntUnchecked(int i, int x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        putInt(ix(i), x);
+    }
+
+    @Override
+    final void putUnchecked(int pos, int[] src, int srcOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.pokeIntArray(ix(pos),
+                src, srcOffset, length, !nativeByteOrder);
+    }
+
+    @Override
+    public final IntBuffer asIntBuffer() {
+        if (memoryRef.isFreed) {
+            throw new IllegalStateException("buffer has been freed");
+        }
+        int off = this.position();
+        int lim = this.limit();
+        assert (off <= lim);
+        int rem = (off <= lim ? lim - off : 0);
+        int size = rem >> 2;
+        return new ByteBufferAsIntBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+
+    private long getLong(long a) {
+        return Memory.peekLong(a, !nativeByteOrder);
+    }
+
+    @Override
+    public final long getLong() {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getLong(ix(nextGetIndex(Long.BYTES)));
+    }
+
+    @Override
+    public final long getLong(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getLong(ix(checkIndex(i, Long.BYTES)));
+    }
+
+    @Override
+    final long getLongUnchecked(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getLong(ix(i));
+    }
+
+    @Override
+    final void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.peekLongArray(ix(pos),
+                dst, dstOffset, length, !nativeByteOrder);
+    }
+
+    private ByteBuffer putLong(long a, long x) {
+        Memory.pokeLong(a, x, !nativeByteOrder);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putLong(long x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putLong(ix(nextPutIndex(Long.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putLong(int i, long x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putLong(ix(checkIndex(i, Long.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    final void putLongUnchecked(int i, long x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        putLong(ix(i), x);
+    }
+
+    @Override
+    final void putUnchecked(int pos, long[] src, int srcOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.pokeLongArray(ix(pos),
+                src, srcOffset, length, !nativeByteOrder);
+    }
+
+    @Override
+    public final LongBuffer asLongBuffer() {
+        if (memoryRef.isFreed) {
+            throw new IllegalStateException("buffer has been freed");
+        }
+        int off = this.position();
+        int lim = this.limit();
+        assert (off <= lim);
+        int rem = (off <= lim ? lim - off : 0);
+        int size = rem >> 3;
+        return new ByteBufferAsLongBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+
+    private float getFloat(long a) {
+        int x = Memory.peekInt(a, !nativeByteOrder);
+        return Float.intBitsToFloat(x);
+    }
+
+    @Override
+    public final float getFloat() {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getFloat(ix(nextGetIndex(Float.BYTES)));
+    }
+
+    @Override
+    public final float getFloat(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getFloat(ix(checkIndex(i, Float.BYTES)));
+    }
+
+    @Override
+    final float getFloatUnchecked(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getFloat(ix(i));
+    }
+
+    @Override
+    final void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.peekFloatArray(ix(pos),
+                dst, dstOffset, length, !nativeByteOrder);
+    }
+
+    private ByteBuffer putFloat(long a, float x) {
+        int y = Float.floatToRawIntBits(x);
+        Memory.pokeInt(a, y, !nativeByteOrder);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putFloat(float x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putFloat(ix(nextPutIndex(Float.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putFloat(int i, float x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putFloat(ix(checkIndex(i, Float.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    final void putFloatUnchecked(int i, float x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        putFloat(ix(i), x);
+    }
+
+    @Override
+    final void putUnchecked(int pos, float[] src, int srcOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.pokeFloatArray(ix(pos),
+                src, srcOffset, length, !nativeByteOrder);
+    }
+
+    @Override
+    public final FloatBuffer asFloatBuffer() {
+        if (memoryRef.isFreed) {
+            throw new IllegalStateException("buffer has been freed");
+        }
+        int off = this.position();
+        int lim = this.limit();
+        assert (off <= lim);
+        int rem = (off <= lim ? lim - off : 0);
+        int size = rem >> 2;
+        return new ByteBufferAsFloatBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+
+    private double getDouble(long a) {
+        long x = Memory.peekLong(a, !nativeByteOrder);
+        return Double.longBitsToDouble(x);
+    }
+
+    @Override
+    public final double getDouble() {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getDouble(ix(nextGetIndex(Double.BYTES)));
+    }
+
+    @Override
+    public final double getDouble(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getDouble(ix(checkIndex(i, Double.BYTES)));
+    }
+
+    @Override
+    final double getDoubleUnchecked(int i) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        return getDouble(ix(i));
+    }
+
+    @Override
+    final void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.peekDoubleArray(ix(pos),
+                dst, dstOffset, length, !nativeByteOrder);
+    }
+
+    private ByteBuffer putDouble(long a, double x) {
+        long y = Double.doubleToRawLongBits(x);
+        Memory.pokeLong(a, y, !nativeByteOrder);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putDouble(double x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putDouble(ix(nextPutIndex(Double.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    public final ByteBuffer putDouble(int i, double x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        putDouble(ix(checkIndex(i, Double.BYTES)), x);
+        return this;
+    }
+
+    @Override
+    final void putDoubleUnchecked(int i, double x) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        putDouble(ix(i), x);
+    }
+
+    @Override
+    final void putUnchecked(int pos, double[] src, int srcOffset, int length) {
+        if (!memoryRef.isAccessible) {
+            throw new IllegalStateException("buffer is inaccessible");
+        }
+        Memory.pokeDoubleArray(ix(pos),
+                src, srcOffset, length, !nativeByteOrder);
+    }
+
+    @Override
+    public final DoubleBuffer asDoubleBuffer() {
+        if (memoryRef.isFreed) {
+            throw new IllegalStateException("buffer has been freed");
+        }
+        int off = this.position();
+        int lim = this.limit();
+        assert (off <= lim);
+        int rem = (off <= lim ? lim - off : 0);
+
+        int size = rem >> 3;
+        return new ByteBufferAsDoubleBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+
+    @Override
+    public final boolean isAccessible() {
+        return memoryRef.isAccessible;
+    }
+
+    @Override
+    public final void setAccessible(boolean value) {
+        memoryRef.isAccessible = value;
+    }
+}
diff --git a/java/nio/DoubleBuffer.java b/java/nio/DoubleBuffer.java
new file mode 100644
index 0000000..bd80f4d
--- /dev/null
+++ b/java/nio/DoubleBuffer.java
@@ -0,0 +1,873 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * A double buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * double buffers:
+ *
+ * <ul>
+ *
+ *   <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ *   {@link #put(double) <i>put</i>} methods that read and write
+ *   single doubles; </p></li>
+ *
+ *   <li><p> Relative {@link #get(double[]) <i>bulk get</i>}
+ *   methods that transfer contiguous sequences of doubles from this buffer
+ *   into an array; and</p></li>
+ *
+ *   <li><p> Relative {@link #put(double[]) <i>bulk put</i>}
+ *   methods that transfer contiguous sequences of doubles from a
+ *   double array or some other double
+ *   buffer into this buffer;&#32;and </p></li>
+ *
+ *
+ *   <li><p> Methods for {@link #compact compacting}, {@link
+ *   #duplicate duplicating}, and {@link #slice slicing}
+ *   a double buffer.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> Double buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(double[]) <i>wrapping</i>} an existing
+ * double array  into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, a double buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>.  A
+ * double buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct.  A double buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct.  Whether or not
+ * a double buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method.  </p>
+ *
+*
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked.  This allows
+ * method invocations to be chained.
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class DoubleBuffer
+    extends Buffer
+    implements Comparable<DoubleBuffer>
+{
+
+    // These fields are declared here rather than in Heap-X-Buffer in order to
+    // reduce the number of virtual method invocations needed to access these
+    // values, which is especially costly when coding small buffers.
+    //
+    final double[] hb;                  // Non-null only for heap buffers
+    final int offset;
+    boolean isReadOnly;                 // Valid only for heap buffers
+
+    // Creates a new buffer with the given mark, position, limit, capacity,
+    // backing array, and array offset
+    //
+    DoubleBuffer(int mark, int pos, int lim, int cap,   // package-private
+                 double[] hb, int offset)
+    {
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 3 /* elementSizeShift */);
+        this.hb = hb;
+        this.offset = offset;
+    }
+
+    // Creates a new buffer with the given mark, position, limit, and capacity
+    //
+    DoubleBuffer(int mark, int pos, int lim, int cap) { // package-private
+        this(mark, pos, lim, cap, null, 0);
+    }
+
+
+    /**
+     * Allocates a new double buffer.
+     *
+     * <p> The new buffer's position will be zero, its limit will be its
+     * capacity, its mark will be undefined, and each of its elements will be
+     * initialized to zero.  It will have a {@link #array backing array},
+     * and its {@link #arrayOffset array offset} will be zero.
+     *
+     * @param  capacity
+     *         The new buffer's capacity, in doubles
+     *
+     * @return  The new double buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the <tt>capacity</tt> is a negative integer
+     */
+    public static DoubleBuffer allocate(int capacity) {
+        if (capacity < 0)
+            throw new IllegalArgumentException();
+        return new HeapDoubleBuffer(capacity, capacity);
+    }
+
+    /**
+     * Wraps a double array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given double array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity will be
+     * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+     * will be <tt>offset + length</tt>, and its mark will be undefined.  Its
+     * {@link #array backing array} will be the given array, and
+     * its {@link #arrayOffset array offset} will be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back the new buffer
+     *
+     * @param  offset
+     *         The offset of the subarray to be used; must be non-negative and
+     *         no larger than <tt>array.length</tt>.  The new buffer's position
+     *         will be set to this value.
+     *
+     * @param  length
+     *         The length of the subarray to be used;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>.
+     *         The new buffer's limit will be set to <tt>offset + length</tt>.
+     *
+     * @return  The new double buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public static DoubleBuffer wrap(double[] array,
+                                    int offset, int length)
+    {
+        try {
+            return new HeapDoubleBuffer(array, offset, length);
+        } catch (IllegalArgumentException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Wraps a double array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given double array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity and limit will be
+     * <tt>array.length</tt>, its position will be zero, and its mark will be
+     * undefined.  Its {@link #array backing array} will be the
+     * given array, and its {@link #arrayOffset array offset>} will
+     * be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back this buffer
+     *
+     * @return  The new double buffer
+     */
+    public static DoubleBuffer wrap(double[] array) {
+        return wrap(array, 0, array.length);
+    }
+
+
+    /**
+     * Creates a new double buffer whose content is a shared subsequence of
+     * this buffer's content.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of doubles remaining in this buffer, and its mark
+     * will be undefined.  The new buffer will be direct if, and only if, this
+     * buffer is direct, and it will be read-only if, and only if, this buffer
+     * is read-only.  </p>
+     *
+     * @return  The new double buffer
+     */
+    public abstract DoubleBuffer slice();
+
+    /**
+     * Creates a new double buffer that shares this buffer's content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer, and vice
+     * versa; the two buffers' position, limit, and mark values will be
+     * independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.  The new buffer will be direct if,
+     * and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  The new double buffer
+     */
+    public abstract DoubleBuffer duplicate();
+
+    /**
+     * Creates a new, read-only double buffer that shares this buffer's
+     * content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer; the new
+     * buffer itself, however, will be read-only and will not allow the shared
+     * content to be modified.  The two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.
+     *
+     * <p> If this buffer is itself read-only then this method behaves in
+     * exactly the same way as the {@link #duplicate duplicate} method.  </p>
+     *
+     * @return  The new, read-only double buffer
+     */
+    public abstract DoubleBuffer asReadOnlyBuffer();
+
+
+    // -- Singleton get/put methods --
+
+    /**
+     * Relative <i>get</i> method.  Reads the double at this buffer's
+     * current position, and then increments the position.
+     *
+     * @return  The double at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If the buffer's current position is not smaller than its limit
+     */
+    public abstract double get();
+
+    /**
+     * Relative <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given double into this buffer at the current
+     * position, and then increments the position. </p>
+     *
+     * @param  d
+     *         The double to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If this buffer's current position is not smaller than its limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract DoubleBuffer put(double d);
+
+    /**
+     * Absolute <i>get</i> method.  Reads the double at the given
+     * index.
+     *
+     * @param  index
+     *         The index from which the double will be read
+     *
+     * @return  The double at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     */
+    public abstract double get(int index);
+
+    /**
+     * Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given double into this buffer at the given
+     * index. </p>
+     *
+     * @param  index
+     *         The index at which the double will be written
+     *
+     * @param  d
+     *         The double value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract DoubleBuffer put(int index, double d);
+
+
+    // -- Bulk get operations --
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers doubles from this buffer into the given
+     * destination array.  If there are fewer doubles remaining in the
+     * buffer than are required to satisfy the request, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * doubles are transferred and a {@link BufferUnderflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> doubles from this
+     * buffer into the given array, starting at the current position of this
+     * buffer and at the given offset in the array.  The position of this
+     * buffer is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>src.get(dst,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst[i] = src.get();
+     * }</pre>
+     *
+     * except that it first checks that there are sufficient doubles in
+     * this buffer and it is potentially much more efficient.
+     *
+     * @param  dst
+     *         The array into which doubles are to be written
+     *
+     * @param  offset
+     *         The offset within the array of the first double to be
+     *         written; must be non-negative and no larger than
+     *         <tt>dst.length</tt>
+     *
+     * @param  length
+     *         The maximum number of doubles to be written to the given
+     *         array; must be non-negative and no larger than
+     *         <tt>dst.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> doubles
+     *          remaining in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public DoubleBuffer get(double[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            dst[i] = get();
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers doubles from this buffer into the given
+     * destination array.  An invocation of this method of the form
+     * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     src.get(a, 0, a.length) </pre>
+     *
+     * @param   dst
+     *          The destination array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> doubles
+     *          remaining in this buffer
+     */
+    public DoubleBuffer get(double[] dst) {
+        return get(dst, 0, dst.length);
+    }
+
+
+    // -- Bulk put operations --
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the doubles remaining in the given source
+     * buffer into this buffer.  If there are more doubles remaining in the
+     * source buffer than in this buffer, that is, if
+     * <tt>src.remaining()</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>,
+     * then no doubles are transferred and a {@link
+     * BufferOverflowException} is thrown.
+     *
+     * <p> Otherwise, this method copies
+     * <i>n</i>&nbsp;=&nbsp;<tt>src.remaining()</tt> doubles from the given
+     * buffer into this buffer, starting at each buffer's current position.
+     * The positions of both buffers are then incremented by <i>n</i>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+     *
+     * <pre>
+     *     while (src.hasRemaining())
+     *         dst.put(src.get()); </pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The source buffer from which doubles are to be read;
+     *         must not be this buffer
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *          for the remaining doubles in the source buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the source buffer is this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public DoubleBuffer put(DoubleBuffer src) {
+        if (src == this)
+            throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
+        int n = src.remaining();
+        if (n > remaining())
+            throw new BufferOverflowException();
+        for (int i = 0; i < n; i++)
+            put(src.get());
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers doubles into this buffer from the given
+     * source array.  If there are more doubles to be copied from the array
+     * than remain in this buffer, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * doubles are transferred and a {@link BufferOverflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> doubles from the
+     * given array into this buffer, starting at the given offset in the array
+     * and at the current position of this buffer.  The position of this buffer
+     * is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst.put(a[i]);
+     * }</pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The array from which doubles are to be read
+     *
+     * @param  offset
+     *         The offset within the array of the first double to be read;
+     *         must be non-negative and no larger than <tt>array.length</tt>
+     *
+     * @param  length
+     *         The number of doubles to be read from the given array;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public DoubleBuffer put(double[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            this.put(src[i]);
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the entire content of the given source
+     * double array into this buffer.  An invocation of this method of the
+     * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+     * invocation
+     *
+     * <pre>
+     *     dst.put(a, 0, a.length) </pre>
+     *
+     * @param   src
+     *          The source array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public final DoubleBuffer put(double[] src) {
+        return put(src, 0, src.length);
+    }
+
+
+    // -- Other stuff --
+
+    /**
+     * Tells whether or not this buffer is backed by an accessible double
+     * array.
+     *
+     * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+     * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+     * </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer
+     *          is backed by an array and is not read-only
+     */
+    public final boolean hasArray() {
+        return (hb != null) && !isReadOnly;
+    }
+
+    /**
+     * Returns the double array that backs this
+     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Modifications to this buffer's content will cause the returned
+     * array's content to be modified, and vice versa.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The array that backs this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final double[] array() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return hb;
+    }
+
+    /**
+     * Returns the offset within this buffer's backing array of the first
+     * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> If this buffer is backed by an array then buffer position <i>p</i>
+     * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The offset within this buffer's array
+     *          of the first element of the buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final int arrayOffset() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return offset;
+    }
+
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = DoubleBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
+    /**
+     * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> The doubles between the buffer's current position and its limit,
+     * if any, are copied to the beginning of the buffer.  That is, the
+     * double at index <i>p</i>&nbsp;=&nbsp;<tt>position()</tt> is copied
+     * to index zero, the double at index <i>p</i>&nbsp;+&nbsp;1 is copied
+     * to index one, and so forth until the double at index
+     * <tt>limit()</tt>&nbsp;-&nbsp;1 is copied to index
+     * <i>n</i>&nbsp;=&nbsp;<tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>&nbsp;-&nbsp;<i>p</i>.
+     * The buffer's position is then set to <i>n+1</i> and its limit is set to
+     * its capacity.  The mark, if defined, is discarded.
+     *
+     * <p> The buffer's position is set to the number of doubles copied,
+     * rather than to zero, so that an invocation of this method can be
+     * followed immediately by an invocation of another relative <i>put</i>
+     * method. </p>
+     *
+
+     *
+     * @return  This buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract DoubleBuffer compact();
+
+    /**
+     * Tells whether or not this double buffer is direct.
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is direct
+     */
+    public abstract boolean isDirect();
+
+
+    /**
+     * Returns a string summarizing the state of this buffer.
+     *
+     * @return  A summary string
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName());
+        sb.append("[pos=");
+        sb.append(position());
+        sb.append(" lim=");
+        sb.append(limit());
+        sb.append(" cap=");
+        sb.append(capacity());
+        sb.append("]");
+        return sb.toString();
+    }
+
+
+    /**
+     * Returns the current hash code of this buffer.
+     *
+     * <p> The hash code of a double buffer depends only upon its remaining
+     * elements; that is, upon the elements from <tt>position()</tt> up to, and
+     * including, the element at <tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>.
+     *
+     * <p> Because buffer hash codes are content-dependent, it is inadvisable
+     * to use buffers as keys in hash maps or similar data structures unless it
+     * is known that their contents will not change.  </p>
+     *
+     * @return  The current hash code of this buffer
+     */
+    public int hashCode() {
+        int h = 1;
+        int p = position();
+        for (int i = limit() - 1; i >= p; i--)
+            h = 31 * h + (int) get(i);
+        return h;
+    }
+
+    /**
+     * Tells whether or not this buffer is equal to another object.
+     *
+     * <p> Two double buffers are equal if, and only if,
+     *
+     * <ol>
+     *
+     *   <li><p> They have the same element type,  </p></li>
+     *
+     *   <li><p> They have the same number of remaining elements, and
+     *   </p></li>
+     *
+     *   <li><p> The two sequences of remaining elements, considered
+     *   independently of their starting positions, are pointwise equal.
+
+     *   This method considers two double elements {@code a} and {@code b}
+     *   to be equal if
+     *   {@code (a == b) || (Double.isNaN(a) && Double.isNaN(b))}.
+     *   The values {@code -0.0} and {@code +0.0} are considered to be
+     *   equal, unlike {@link Double#equals(Object)}.
+
+     *   </p></li>
+     *
+     * </ol>
+     *
+     * <p> A double buffer is not equal to any other type of object.  </p>
+     *
+     * @param  ob  The object to which this buffer is to be compared
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is equal to the
+     *           given object
+     */
+    public boolean equals(Object ob) {
+        if (this == ob)
+            return true;
+        if (!(ob instanceof DoubleBuffer))
+            return false;
+        DoubleBuffer that = (DoubleBuffer)ob;
+        if (this.remaining() != that.remaining())
+            return false;
+        int p = this.position();
+        for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+            if (!equals(this.get(i), that.get(j)))
+                return false;
+        return true;
+    }
+
+    private static boolean equals(double x, double y) {
+
+        return (x == y) || (Double.isNaN(x) && Double.isNaN(y));
+
+
+    }
+
+    /**
+     * Compares this buffer to another.
+     *
+     * <p> Two double buffers are compared by comparing their sequences of
+     * remaining elements lexicographically, without regard to the starting
+     * position of each sequence within its corresponding buffer.
+
+     * Pairs of {@code double} elements are compared as if by invoking
+     * {@link Double#compare(double,double)}, except that
+     * {@code -0.0} and {@code 0.0} are considered to be equal.
+     * {@code Double.NaN} is considered by this method to be equal
+     * to itself and greater than all other {@code double} values
+     * (including {@code Double.POSITIVE_INFINITY}).
+
+     *
+     * <p> A double buffer is not comparable to any other type of object.
+     *
+     * @return  A negative integer, zero, or a positive integer as this buffer
+     *          is less than, equal to, or greater than the given buffer
+     */
+    public int compareTo(DoubleBuffer that) {
+        int n = this.position() + Math.min(this.remaining(), that.remaining());
+        for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+            int cmp = compare(this.get(i), that.get(j));
+            if (cmp != 0)
+                return cmp;
+        }
+        return this.remaining() - that.remaining();
+    }
+
+    private static int compare(double x, double y) {
+
+        return ((x < y)  ? -1 :
+                (x > y)  ? +1 :
+                (x == y) ?  0 :
+                Double.isNaN(x) ? (Double.isNaN(y) ? 0 : +1) : -1);
+
+    }
+
+    // -- Other char stuff --
+
+
+    // -- Other byte stuff: Access to binary data --
+
+
+    /**
+     * Retrieves this buffer's byte order.
+     *
+     * <p> The byte order of a double buffer created by allocation or by
+     * wrapping an existing <tt>double</tt> array is the {@link
+     * ByteOrder#nativeOrder native order} of the underlying
+     * hardware.  The byte order of a double buffer created as a <a
+     * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+     * byte buffer at the moment that the view is created.  </p>
+     *
+     * @return  This buffer's byte order
+     */
+    public abstract ByteOrder order();
+
+
+}
diff --git a/java/nio/FloatBuffer.java b/java/nio/FloatBuffer.java
new file mode 100644
index 0000000..3d34211
--- /dev/null
+++ b/java/nio/FloatBuffer.java
@@ -0,0 +1,874 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * A float buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * float buffers:
+ *
+ * <ul>
+ *
+ *   <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ *   {@link #put(float) <i>put</i>} methods that read and write
+ *   single floats; </p></li>
+ *
+ *   <li><p> Relative {@link #get(float[]) <i>bulk get</i>}
+ *   methods that transfer contiguous sequences of floats from this buffer
+ *   into an array; and</p></li>
+ *
+ *   <li><p> Relative {@link #put(float[]) <i>bulk put</i>}
+ *   methods that transfer contiguous sequences of floats from a
+ *   float array or some other float
+ *   buffer into this buffer;&#32;and </p></li>
+ *
+ *
+ *   <li><p> Methods for {@link #compact compacting}, {@link
+ *   #duplicate duplicating}, and {@link #slice slicing}
+ *   a float buffer.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> Float buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(float[]) <i>wrapping</i>} an existing
+ * float array  into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, a float buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>.  A
+ * float buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct.  A float buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct.  Whether or not
+ * a float buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method.  </p>
+ *
+*
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked.  This allows
+ * method invocations to be chained.
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class FloatBuffer
+    extends Buffer
+    implements Comparable<FloatBuffer>
+{
+
+    // These fields are declared here rather than in Heap-X-Buffer in order to
+    // reduce the number of virtual method invocations needed to access these
+    // values, which is especially costly when coding small buffers.
+    //
+    final float[] hb;                  // Non-null only for heap buffers
+    final int offset;
+    boolean isReadOnly;                 // Valid only for heap buffers
+
+    // Creates a new buffer with the given mark, position, limit, capacity,
+    // backing array, and array offset
+    //
+    FloatBuffer(int mark, int pos, int lim, int cap,   // package-private
+                 float[] hb, int offset)
+    {
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 2 /* elementSizeShift */);
+        this.hb = hb;
+        this.offset = offset;
+    }
+
+    // Creates a new buffer with the given mark, position, limit, and capacity
+    //
+    FloatBuffer(int mark, int pos, int lim, int cap) { // package-private
+        this(mark, pos, lim, cap, null, 0);
+    }
+
+
+    /**
+     * Allocates a new float buffer.
+     *
+     * <p> The new buffer's position will be zero, its limit will be its
+     * capacity, its mark will be undefined, and each of its elements will be
+     * initialized to zero.  It will have a {@link #array backing array},
+     * and its {@link #arrayOffset array offset} will be zero.
+     *
+     * @param  capacity
+     *         The new buffer's capacity, in floats
+     *
+     * @return  The new float buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the <tt>capacity</tt> is a negative integer
+     */
+    public static FloatBuffer allocate(int capacity) {
+        if (capacity < 0)
+            throw new IllegalArgumentException();
+        return new HeapFloatBuffer(capacity, capacity);
+    }
+
+    /**
+     * Wraps a float array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given float array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity will be
+     * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+     * will be <tt>offset + length</tt>, and its mark will be undefined.  Its
+     * {@link #array backing array} will be the given array, and
+     * its {@link #arrayOffset array offset} will be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back the new buffer
+     *
+     * @param  offset
+     *         The offset of the subarray to be used; must be non-negative and
+     *         no larger than <tt>array.length</tt>.  The new buffer's position
+     *         will be set to this value.
+     *
+     * @param  length
+     *         The length of the subarray to be used;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>.
+     *         The new buffer's limit will be set to <tt>offset + length</tt>.
+     *
+     * @return  The new float buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public static FloatBuffer wrap(float[] array,
+                                    int offset, int length)
+    {
+        try {
+            return new HeapFloatBuffer(array, offset, length);
+        } catch (IllegalArgumentException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Wraps a float array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given float array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity and limit will be
+     * <tt>array.length</tt>, its position will be zero, and its mark will be
+     * undefined.  Its {@link #array backing array} will be the
+     * given array, and its {@link #arrayOffset array offset>} will
+     * be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back this buffer
+     *
+     * @return  The new float buffer
+     */
+    public static FloatBuffer wrap(float[] array) {
+        return wrap(array, 0, array.length);
+    }
+
+
+    /**
+     * Creates a new float buffer whose content is a shared subsequence of
+     * this buffer's content.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of floats remaining in this buffer, and its mark
+     * will be undefined.  The new buffer will be direct if, and only if, this
+     * buffer is direct, and it will be read-only if, and only if, this buffer
+     * is read-only.  </p>
+     *
+     * @return  The new float buffer
+     */
+    public abstract FloatBuffer slice();
+
+    /**
+     * Creates a new float buffer that shares this buffer's content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer, and vice
+     * versa; the two buffers' position, limit, and mark values will be
+     * independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.  The new buffer will be direct if,
+     * and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  The new float buffer
+     */
+    public abstract FloatBuffer duplicate();
+
+    /**
+     * Creates a new, read-only float buffer that shares this buffer's
+     * content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer; the new
+     * buffer itself, however, will be read-only and will not allow the shared
+     * content to be modified.  The two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.
+     *
+     * <p> If this buffer is itself read-only then this method behaves in
+     * exactly the same way as the {@link #duplicate duplicate} method.  </p>
+     *
+     * @return  The new, read-only float buffer
+     */
+    public abstract FloatBuffer asReadOnlyBuffer();
+
+
+    // -- Singleton get/put methods --
+
+    /**
+     * Relative <i>get</i> method.  Reads the float at this buffer's
+     * current position, and then increments the position.
+     *
+     * @return  The float at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If the buffer's current position is not smaller than its limit
+     */
+    public abstract float get();
+
+    /**
+     * Relative <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given float into this buffer at the current
+     * position, and then increments the position. </p>
+     *
+     * @param  f
+     *         The float to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If this buffer's current position is not smaller than its limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract FloatBuffer put(float f);
+
+    /**
+     * Absolute <i>get</i> method.  Reads the float at the given
+     * index.
+     *
+     * @param  index
+     *         The index from which the float will be read
+     *
+     * @return  The float at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     */
+    public abstract float get(int index);
+
+    /**
+     * Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given float into this buffer at the given
+     * index. </p>
+     *
+     * @param  index
+     *         The index at which the float will be written
+     *
+     * @param  f
+     *         The float value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract FloatBuffer put(int index, float f);
+
+
+    // -- Bulk get operations --
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers floats from this buffer into the given
+     * destination array.  If there are fewer floats remaining in the
+     * buffer than are required to satisfy the request, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * floats are transferred and a {@link BufferUnderflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> floats from this
+     * buffer into the given array, starting at the current position of this
+     * buffer and at the given offset in the array.  The position of this
+     * buffer is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>src.get(dst,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst[i] = src.get();
+     * }</pre>
+     *
+     * except that it first checks that there are sufficient floats in
+     * this buffer and it is potentially much more efficient.
+     *
+     * @param  dst
+     *         The array into which floats are to be written
+     *
+     * @param  offset
+     *         The offset within the array of the first float to be
+     *         written; must be non-negative and no larger than
+     *         <tt>dst.length</tt>
+     *
+     * @param  length
+     *         The maximum number of floats to be written to the given
+     *         array; must be non-negative and no larger than
+     *         <tt>dst.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> floats
+     *          remaining in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public FloatBuffer get(float[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            dst[i] = get();
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers floats from this buffer into the given
+     * destination array.  An invocation of this method of the form
+     * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     src.get(a, 0, a.length) </pre>
+     *
+     * @param   dst
+     *          The destination array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> floats
+     *          remaining in this buffer
+     */
+    public FloatBuffer get(float[] dst) {
+        return get(dst, 0, dst.length);
+    }
+
+
+    // -- Bulk put operations --
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the floats remaining in the given source
+     * buffer into this buffer.  If there are more floats remaining in the
+     * source buffer than in this buffer, that is, if
+     * <tt>src.remaining()</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>,
+     * then no floats are transferred and a {@link
+     * BufferOverflowException} is thrown.
+     *
+     * <p> Otherwise, this method copies
+     * <i>n</i>&nbsp;=&nbsp;<tt>src.remaining()</tt> floats from the given
+     * buffer into this buffer, starting at each buffer's current position.
+     * The positions of both buffers are then incremented by <i>n</i>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+     *
+     * <pre>
+     *     while (src.hasRemaining())
+     *         dst.put(src.get()); </pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The source buffer from which floats are to be read;
+     *         must not be this buffer
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *          for the remaining floats in the source buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the source buffer is this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public FloatBuffer put(FloatBuffer src) {
+        if (src == this)
+            throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
+        int n = src.remaining();
+        if (n > remaining())
+            throw new BufferOverflowException();
+        for (int i = 0; i < n; i++)
+            put(src.get());
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers floats into this buffer from the given
+     * source array.  If there are more floats to be copied from the array
+     * than remain in this buffer, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * floats are transferred and a {@link BufferOverflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> floats from the
+     * given array into this buffer, starting at the given offset in the array
+     * and at the current position of this buffer.  The position of this buffer
+     * is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst.put(a[i]);
+     * }</pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The array from which floats are to be read
+     *
+     * @param  offset
+     *         The offset within the array of the first float to be read;
+     *         must be non-negative and no larger than <tt>array.length</tt>
+     *
+     * @param  length
+     *         The number of floats to be read from the given array;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public FloatBuffer put(float[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            this.put(src[i]);
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the entire content of the given source
+     * float array into this buffer.  An invocation of this method of the
+     * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+     * invocation
+     *
+     * <pre>
+     *     dst.put(a, 0, a.length) </pre>
+     *
+     * @param   src
+     *          The source array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public final FloatBuffer put(float[] src) {
+        return put(src, 0, src.length);
+    }
+
+
+    // -- Other stuff --
+
+    /**
+     * Tells whether or not this buffer is backed by an accessible float
+     * array.
+     *
+     * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+     * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+     * </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer
+     *          is backed by an array and is not read-only
+     */
+    public final boolean hasArray() {
+        return (hb != null) && !isReadOnly;
+    }
+
+    /**
+     * Returns the float array that backs this
+     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Modifications to this buffer's content will cause the returned
+     * array's content to be modified, and vice versa.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The array that backs this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final float[] array() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return hb;
+    }
+
+    /**
+     * Returns the offset within this buffer's backing array of the first
+     * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> If this buffer is backed by an array then buffer position <i>p</i>
+     * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The offset within this buffer's array
+     *          of the first element of the buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final int arrayOffset() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return offset;
+    }
+
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = FloatBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
+    /**
+     * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> The floats between the buffer's current position and its limit,
+     * if any, are copied to the beginning of the buffer.  That is, the
+     * float at index <i>p</i>&nbsp;=&nbsp;<tt>position()</tt> is copied
+     * to index zero, the float at index <i>p</i>&nbsp;+&nbsp;1 is copied
+     * to index one, and so forth until the float at index
+     * <tt>limit()</tt>&nbsp;-&nbsp;1 is copied to index
+     * <i>n</i>&nbsp;=&nbsp;<tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>&nbsp;-&nbsp;<i>p</i>.
+     * The buffer's position is then set to <i>n+1</i> and its limit is set to
+     * its capacity.  The mark, if defined, is discarded.
+     *
+     * <p> The buffer's position is set to the number of floats copied,
+     * rather than to zero, so that an invocation of this method can be
+     * followed immediately by an invocation of another relative <i>put</i>
+     * method. </p>
+     *
+
+     *
+     * @return  This buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract FloatBuffer compact();
+
+    /**
+     * Tells whether or not this float buffer is direct.
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is direct
+     */
+    public abstract boolean isDirect();
+
+
+    /**
+     * Returns a string summarizing the state of this buffer.
+     *
+     * @return  A summary string
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName());
+        sb.append("[pos=");
+        sb.append(position());
+        sb.append(" lim=");
+        sb.append(limit());
+        sb.append(" cap=");
+        sb.append(capacity());
+        sb.append("]");
+        return sb.toString();
+    }
+
+
+    /**
+     * Returns the current hash code of this buffer.
+     *
+     * <p> The hash code of a float buffer depends only upon its remaining
+     * elements; that is, upon the elements from <tt>position()</tt> up to, and
+     * including, the element at <tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>.
+     *
+     * <p> Because buffer hash codes are content-dependent, it is inadvisable
+     * to use buffers as keys in hash maps or similar data structures unless it
+     * is known that their contents will not change.  </p>
+     *
+     * @return  The current hash code of this buffer
+     */
+    public int hashCode() {
+        int h = 1;
+        int p = position();
+        for (int i = limit() - 1; i >= p; i--)
+            h = 31 * h + (int) get(i);
+        return h;
+    }
+
+    /**
+     * Tells whether or not this buffer is equal to another object.
+     *
+     * <p> Two float buffers are equal if, and only if,
+     *
+     * <ol>
+     *
+     *   <li><p> They have the same element type,  </p></li>
+     *
+     *   <li><p> They have the same number of remaining elements, and
+     *   </p></li>
+     *
+     *   <li><p> The two sequences of remaining elements, considered
+     *   independently of their starting positions, are pointwise equal.
+
+     *   This method considers two float elements {@code a} and {@code b}
+     *   to be equal if
+     *   {@code (a == b) || (Float.isNaN(a) && Float.isNaN(b))}.
+     *   The values {@code -0.0} and {@code +0.0} are considered to be
+     *   equal, unlike {@link Float#equals(Object)}.
+
+     *   </p></li>
+     *
+     * </ol>
+     *
+     * <p> A float buffer is not equal to any other type of object.  </p>
+     *
+     * @param  ob  The object to which this buffer is to be compared
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is equal to the
+     *           given object
+     */
+    public boolean equals(Object ob) {
+        if (this == ob)
+            return true;
+        if (!(ob instanceof FloatBuffer))
+            return false;
+        FloatBuffer that = (FloatBuffer)ob;
+        if (this.remaining() != that.remaining())
+            return false;
+        int p = this.position();
+        for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+            if (!equals(this.get(i), that.get(j)))
+                return false;
+        return true;
+    }
+
+    private static boolean equals(float x, float y) {
+
+        return (x == y) || (Float.isNaN(x) && Float.isNaN(y));
+
+
+    }
+
+    /**
+     * Compares this buffer to another.
+     *
+     * <p> Two float buffers are compared by comparing their sequences of
+     * remaining elements lexicographically, without regard to the starting
+     * position of each sequence within its corresponding buffer.
+
+     * Pairs of {@code float} elements are compared as if by invoking
+     * {@link Float#compare(float,float)}, except that
+     * {@code -0.0} and {@code 0.0} are considered to be equal.
+     * {@code Float.NaN} is considered by this method to be equal
+     * to itself and greater than all other {@code float} values
+     * (including {@code Float.POSITIVE_INFINITY}).
+     *
+     *
+     *
+     *
+     *
+     * <p> A float buffer is not comparable to any other type of object.
+     *
+     * @return  A negative integer, zero, or a positive integer as this buffer
+     *          is less than, equal to, or greater than the given buffer
+     */
+    public int compareTo(FloatBuffer that) {
+        int n = this.position() + Math.min(this.remaining(), that.remaining());
+        for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+            int cmp = compare(this.get(i), that.get(j));
+            if (cmp != 0)
+                return cmp;
+        }
+        return this.remaining() - that.remaining();
+    }
+
+    private static int compare(float x, float y) {
+
+        return ((x < y)  ? -1 :
+                (x > y)  ? +1 :
+                (x == y) ?  0 :
+                Float.isNaN(x) ? (Float.isNaN(y) ? 0 : +1) : -1);
+
+    }
+
+    // -- Other char stuff --
+
+    // -- Other byte stuff: Access to binary data --
+
+    /**
+     * Retrieves this buffer's byte order.
+     *
+     * <p> The byte order of a float buffer created by allocation or by
+     * wrapping an existing <tt>float</tt> array is the {@link
+     * ByteOrder#nativeOrder native order} of the underlying
+     * hardware.  The byte order of a float buffer created as a <a
+     * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+     * byte buffer at the moment that the view is created.  </p>
+     *
+     * @return  This buffer's byte order
+     */
+    public abstract ByteOrder order();
+
+
+}
diff --git a/java/nio/HeapByteBuffer.java b/java/nio/HeapByteBuffer.java
new file mode 100644
index 0000000..4666638
--- /dev/null
+++ b/java/nio/HeapByteBuffer.java
@@ -0,0 +1,561 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, 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.nio;
+
+
+import libcore.io.Memory;
+
+/**
+ * A read/write HeapByteBuffer.
+ */
+
+final class HeapByteBuffer extends ByteBuffer {
+
+    // For speed these fields are actually declared in X-Buffer;
+    // these declarations are here as documentation
+    /*
+
+      protected final byte[] hb;
+      protected final int offset;
+
+    */
+
+    HeapByteBuffer(int cap, int lim) {            // packag-private
+        this(cap, lim, false);
+    }
+
+
+    private HeapByteBuffer(int cap, int lim, boolean isReadOnly) {
+        super(-1, 0, lim, cap, new byte[cap], 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    HeapByteBuffer(byte[] buf, int off, int len) { // package-private
+        this(buf, off, len, false);
+    }
+
+    private HeapByteBuffer(byte[] buf, int off, int len, boolean isReadOnly) {
+        super(-1, off, off + len, buf.length, buf, 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    private HeapByteBuffer(byte[] buf, int mark, int pos, int lim, int cap, int off,
+            boolean isReadOnly) {
+        super(mark, pos, lim, cap, buf, off);
+        this.isReadOnly = isReadOnly;
+    }
+
+    @Override
+    public ByteBuffer slice() {
+        return new HeapByteBuffer(hb,
+                -1,
+                0,
+                remaining(),
+                remaining(),
+                position() + offset,
+                isReadOnly);
+    }
+
+    @Override
+    public ByteBuffer duplicate() {
+        return new HeapByteBuffer(hb,
+                markValue(),
+                position(),
+                limit(),
+                capacity(),
+                offset,
+                isReadOnly);
+    }
+
+    @Override
+    public ByteBuffer asReadOnlyBuffer() {
+        return new HeapByteBuffer(hb,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset, true);
+    }
+
+    protected int ix(int i) {
+        return i + offset;
+    }
+
+    @Override
+    public byte get() {
+        return hb[ix(nextGetIndex())];
+    }
+
+    @Override
+    public byte get(int i) {
+        return hb[ix(checkIndex(i))];
+    }
+
+    @Override
+    public ByteBuffer get(byte[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        System.arraycopy(hb, ix(position()), dst, offset, length);
+        position(position() + length);
+        return this;
+    }
+
+    @Override
+    public boolean isDirect() {
+        return false;
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    @Override
+    public ByteBuffer put(byte x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(nextPutIndex())] = x;
+        return this;
+    }
+
+    @Override
+    public ByteBuffer put(int i, byte x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(checkIndex(i))] = x;
+        return this;
+    }
+
+    @Override
+    public ByteBuffer put(byte[] src, int offset, int length) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        System.arraycopy(src, offset, hb, ix(position()), length);
+        position(position() + length);
+        return this;
+    }
+
+    @Override
+    public ByteBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+        position(remaining());
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    @Override
+    byte _get(int i) {                          // package-private
+        return hb[i];
+    }
+
+    @Override
+    void _put(int i, byte b) {                  // package-private
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[i] = b;
+    }
+
+    @Override
+    public char getChar() {
+        return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian);
+    }
+
+    @Override
+    public char getChar(int i) {
+        return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian);
+    }
+
+    @Override
+    char getCharUnchecked(int i) {
+        return Bits.getChar(this, ix(i), bigEndian);
+    }
+
+    @Override
+    void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
+        Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder);
+    }
+
+    @Override
+    public ByteBuffer putChar(char x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    public ByteBuffer putChar(int i, char x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    void putCharUnchecked(int i, char x) {
+        Bits.putChar(this, ix(i), x, bigEndian);
+    }
+
+    @Override
+    void putUnchecked(int pos, char[] src, int srcOffset, int length) {
+        Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder);
+    }
+
+    @Override
+    public CharBuffer asCharBuffer() {
+        int size = this.remaining() >> 1;
+        int off = position();
+        return new ByteBufferAsCharBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+
+    @Override
+    public short getShort() {
+        return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian);
+    }
+
+    @Override
+    public short getShort(int i) {
+        return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian);
+    }
+
+    @Override
+    short getShortUnchecked(int i) {
+        return Bits.getShort(this, ix(i), bigEndian);
+    }
+
+    @Override
+    void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
+        Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder);
+    }
+
+    @Override
+    public ByteBuffer putShort(short x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    public ByteBuffer putShort(int i, short x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    void putShortUnchecked(int i, short x) {
+        Bits.putShort(this, ix(i), x, bigEndian);
+    }
+
+    @Override
+    void putUnchecked(int pos, short[] src, int srcOffset, int length) {
+        Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder);
+    }
+
+    @Override
+    public ShortBuffer asShortBuffer() {
+        int size = this.remaining() >> 1;
+        int off = position();
+        return new ByteBufferAsShortBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+
+    @Override
+    public int getInt() {
+        return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
+    }
+
+    @Override
+    public int getInt(int i) {
+        return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian);
+    }
+
+    @Override
+    int getIntUnchecked(int i) {
+        return Bits.getInt(this, ix(i), bigEndian);
+    }
+
+    @Override
+    void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
+        Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder);
+    }
+
+    @Override
+    public ByteBuffer putInt(int x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    public ByteBuffer putInt(int i, int x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    void putIntUnchecked(int i, int x) {
+        Bits.putInt(this, ix(i), x, bigEndian);
+    }
+
+    @Override
+    void putUnchecked(int pos, int[] src, int srcOffset, int length) {
+        Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder);
+    }
+
+    @Override
+    public IntBuffer asIntBuffer() {
+        int size = this.remaining() >> 2;
+        int off = position();
+
+        return new ByteBufferAsIntBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+
+    @Override
+    public long getLong() {
+        return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian);
+    }
+
+    @Override
+    public long getLong(int i) {
+        return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian);
+    }
+
+    @Override
+    long getLongUnchecked(int i) {
+        return Bits.getLong(this, ix(i), bigEndian);
+    }
+
+    @Override
+    void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
+        Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder);
+    }
+
+    @Override
+    public ByteBuffer putLong(long x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    public ByteBuffer putLong(int i, long x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    void putLongUnchecked(int i, long x) {
+        Bits.putLong(this, ix(i), x, bigEndian);
+    }
+
+    @Override
+    void putUnchecked(int pos, long[] src, int srcOffset, int length) {
+        Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder);
+    }
+
+    @Override
+    public LongBuffer asLongBuffer() {
+        int size = this.remaining() >> 3;
+        int off = position();
+        return new ByteBufferAsLongBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+
+    @Override
+    public float getFloat() {
+        return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian);
+    }
+
+    @Override
+    public float getFloat(int i) {
+        return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian);
+    }
+
+    @Override
+    float getFloatUnchecked(int i) {
+        return Bits.getFloat(this, ix(i), bigEndian);
+    }
+
+    @Override
+    void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
+        Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder);
+    }
+
+    @Override
+    public ByteBuffer putFloat(float x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    public ByteBuffer putFloat(int i, float x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    void putFloatUnchecked(int i, float x) {
+        Bits.putFloat(this, ix(i), x, bigEndian);
+    }
+
+    @Override
+    void putUnchecked(int pos, float[] src, int srcOffset, int length) {
+        Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder);
+    }
+
+    @Override
+    public FloatBuffer asFloatBuffer() {
+        int size = this.remaining() >> 2;
+        int off = position();
+        return new ByteBufferAsFloatBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+
+    @Override
+    public double getDouble() {
+        return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian);
+    }
+
+    @Override
+    public double getDouble(int i) {
+        return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian);
+    }
+
+    @Override
+    double getDoubleUnchecked(int i) {
+        return Bits.getDouble(this, ix(i), bigEndian);
+    }
+
+    @Override
+    void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
+        Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder);
+    }
+
+    @Override
+    public ByteBuffer putDouble(double x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    public ByteBuffer putDouble(int i, double x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian);
+        return this;
+    }
+
+    @Override
+    void putDoubleUnchecked(int i, double x) {
+        Bits.putDouble(this, ix(i), x, bigEndian);
+    }
+
+    @Override
+    void putUnchecked(int pos, double[] src, int srcOffset, int length) {
+        Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder);
+    }
+
+    @Override
+    public DoubleBuffer asDoubleBuffer() {
+        int size = this.remaining() >> 3;
+        int off = position();
+        return new ByteBufferAsDoubleBuffer(this,
+                -1,
+                0,
+                size,
+                size,
+                off,
+                order());
+    }
+}
diff --git a/java/nio/HeapCharBuffer.java b/java/nio/HeapCharBuffer.java
new file mode 100644
index 0000000..fad4fa6
--- /dev/null
+++ b/java/nio/HeapCharBuffer.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio;
+
+/**
+ * A read/write HeapCharBuffer.
+ */
+
+class HeapCharBuffer extends CharBuffer {
+
+    // For speed these fields are actually declared in X-Buffer;
+    // these declarations are here as documentation
+    /*
+
+      protected final char[] hb;
+      protected final int offset;
+
+    */
+
+    HeapCharBuffer(int cap, int lim) {            // package-private
+        this(cap, lim, false);
+    }
+
+    HeapCharBuffer(int cap, int lim, boolean isReadOnly) {            // package-private
+        super(-1, 0, lim, cap, new char[cap], 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    HeapCharBuffer(char[] buf, int off, int len) { // package-private
+        this(buf, off, len, false);
+    }
+
+    HeapCharBuffer(char[] buf, int off, int len, boolean isReadOnly) { // package-private
+        super(-1, off, off + len, buf.length, buf, 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    protected HeapCharBuffer(char[] buf,
+                             int mark, int pos, int lim, int cap,
+                             int off) {
+        this(buf, mark, pos, lim, cap, off, false);
+    }
+
+    protected HeapCharBuffer(char[] buf,
+                             int mark, int pos, int lim, int cap,
+                             int off, boolean isReadOnly) {
+        super(mark, pos, lim, cap, buf, off);
+        this.isReadOnly = isReadOnly;
+    }
+
+    public CharBuffer slice() {
+        return new HeapCharBuffer(hb,
+                -1,
+                0,
+                this.remaining(),
+                this.remaining(),
+                this.position() + offset,
+                isReadOnly);
+    }
+
+    public CharBuffer duplicate() {
+        return new HeapCharBuffer(hb,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset,
+                isReadOnly);
+    }
+
+    public CharBuffer asReadOnlyBuffer() {
+
+        return new HeapCharBuffer(hb,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset,
+                true);
+    }
+
+    protected int ix(int i) {
+        return i + offset;
+    }
+
+    public char get() {
+        return hb[ix(nextGetIndex())];
+    }
+
+    public char get(int i) {
+        return hb[ix(checkIndex(i))];
+    }
+
+    char getUnchecked(int i) {
+        return hb[ix(i)];
+    }
+
+    public CharBuffer get(char[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        System.arraycopy(hb, ix(position()), dst, offset, length);
+        position(position() + length);
+        return this;
+    }
+
+    public boolean isDirect() {
+        return false;
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public CharBuffer put(char x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(nextPutIndex())] = x;
+        return this;
+    }
+
+    public CharBuffer put(int i, char x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(checkIndex(i))] = x;
+        return this;
+    }
+
+    public CharBuffer put(char[] src, int offset, int length) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        System.arraycopy(src, offset, hb, ix(position()), length);
+        position(position() + length);
+        return this;
+    }
+
+    public CharBuffer put(CharBuffer src) {
+        if (src == this) {
+            throw new IllegalArgumentException();
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        if (src instanceof HeapCharBuffer) {
+            HeapCharBuffer sb = (HeapCharBuffer) src;
+            int n = sb.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            System.arraycopy(sb.hb, sb.ix(sb.position()),
+                    hb, ix(position()), n);
+            sb.position(sb.position() + n);
+            position(position() + n);
+        } else if (src.isDirect()) {
+            int n = src.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            src.get(hb, ix(position()), n);
+            position(position() + n);
+        } else {
+            super.put(src);
+        }
+        return this;
+    }
+
+    public CharBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+        position(remaining());
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    String toString(int start, int end) {               // package-private
+        try {
+            return new String(hb, start + offset, end - start);
+        } catch (StringIndexOutOfBoundsException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    public CharBuffer subSequence(int start, int end) {
+        if ((start < 0)
+                || (end > length())
+                || (start > end))
+            throw new IndexOutOfBoundsException();
+        int pos = position();
+        return new HeapCharBuffer(hb,
+                -1,
+                pos + start,
+                pos + end,
+                capacity(),
+                offset, isReadOnly);
+    }
+
+    public ByteOrder order() {
+        return ByteOrder.nativeOrder();
+    }
+}
diff --git a/java/nio/HeapDoubleBuffer.java b/java/nio/HeapDoubleBuffer.java
new file mode 100644
index 0000000..02634dd
--- /dev/null
+++ b/java/nio/HeapDoubleBuffer.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, 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.nio;
+
+/**
+ * A read/write HeapDoubleBuffer.
+ */
+
+class HeapDoubleBuffer extends DoubleBuffer {
+
+    // For speed these fields are actually declared in X-Buffer;
+    // these declarations are here as documentation
+    /*
+
+      protected final double[] hb;
+      protected final int offset;
+
+    */
+
+    HeapDoubleBuffer(int cap, int lim) {            // package-private
+        this(cap, lim, false);
+    }
+
+    HeapDoubleBuffer(double[] buf, int off, int len) { // package-private
+        this(buf, off, len, false);
+    }
+
+    protected HeapDoubleBuffer(double[] buf,
+                               int mark, int pos, int lim, int cap,
+                               int off) {
+        this(buf, mark, pos, lim, cap, off, false);
+    }
+
+    HeapDoubleBuffer(int cap, int lim, boolean isReadOnly) {            // package-private
+        super(-1, 0, lim, cap, new double[cap], 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    HeapDoubleBuffer(double[] buf, int off, int len, boolean isReadOnly) { // package-private
+        super(-1, off, off + len, buf.length, buf, 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    protected HeapDoubleBuffer(double[] buf,
+                               int mark, int pos, int lim, int cap,
+                               int off, boolean isReadOnly) {
+        super(mark, pos, lim, cap, buf, off);
+        this.isReadOnly = isReadOnly;
+    }
+
+
+    public DoubleBuffer slice() {
+        return new HeapDoubleBuffer(hb,
+                                    -1,
+                                    0,
+                                    this.remaining(),
+                                    this.remaining(),
+                                    this.position() + offset,
+                                    isReadOnly);
+    }
+
+    public DoubleBuffer duplicate() {
+        return new HeapDoubleBuffer(hb,
+                                    this.markValue(),
+                                    this.position(),
+                                    this.limit(),
+                                    this.capacity(),
+                                    offset,
+                                    isReadOnly);
+    }
+
+    public DoubleBuffer asReadOnlyBuffer() {
+        return new HeapDoubleBuffer(hb,
+                                     this.markValue(),
+                                     this.position(),
+                                     this.limit(),
+                                     this.capacity(),
+                                     offset, true);
+    }
+
+    protected int ix(int i) {
+        return i + offset;
+    }
+
+    public double get() {
+        return hb[ix(nextGetIndex())];
+    }
+
+    public double get(int i) {
+        return hb[ix(checkIndex(i))];
+    }
+
+    public DoubleBuffer get(double[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        System.arraycopy(hb, ix(position()), dst, offset, length);
+        position(position() + length);
+        return this;
+    }
+
+    public boolean isDirect() {
+        return false;
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public DoubleBuffer put(double x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(nextPutIndex())] = x;
+        return this;
+    }
+
+    public DoubleBuffer put(int i, double x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(checkIndex(i))] = x;
+        return this;
+    }
+
+    public DoubleBuffer put(double[] src, int offset, int length) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        System.arraycopy(src, offset, hb, ix(position()), length);
+        position(position() + length);
+        return this;
+    }
+
+    public DoubleBuffer put(DoubleBuffer src) {
+        if (src == this) {
+            throw new IllegalArgumentException();
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        if (src instanceof HeapDoubleBuffer) {
+            HeapDoubleBuffer sb = (HeapDoubleBuffer)src;
+            int n = sb.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            System.arraycopy(sb.hb, sb.ix(sb.position()),
+                             hb, ix(position()), n);
+            sb.position(sb.position() + n);
+            position(position() + n);
+        } else if (src.isDirect()) {
+            int n = src.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            src.get(hb, ix(position()), n);
+            position(position() + n);
+        } else {
+            super.put(src);
+        }
+        return this;
+    }
+
+    public DoubleBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+        position(remaining());
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    public ByteOrder order() {
+        return ByteOrder.nativeOrder();
+    }
+}
diff --git a/java/nio/HeapFloatBuffer.java b/java/nio/HeapFloatBuffer.java
new file mode 100644
index 0000000..42dd8ce
--- /dev/null
+++ b/java/nio/HeapFloatBuffer.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, 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.nio;
+
+/**
+ * A read/write HeapFloatBuffer.
+ */
+
+class HeapFloatBuffer extends FloatBuffer {
+
+    // For speed these fields are actually declared in X-Buffer;
+    // these declarations are here as documentation
+    /*
+
+      protected final float[] hb;
+      protected final int offset;
+
+    */
+
+    HeapFloatBuffer(int cap, int lim) {            // package-private
+        this(cap, lim, false);
+    }
+
+    HeapFloatBuffer(int cap, int lim, boolean isReadOnly) {            // package-private
+        super(-1, 0, lim, cap, new float[cap], 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    HeapFloatBuffer(float[] buf, int off, int len) { // package-private
+        this(buf, off, len, false);
+    }
+
+    HeapFloatBuffer(float[] buf, int off, int len, boolean isReadOnly) { // package-private
+        super(-1, off, off + len, buf.length, buf, 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    protected HeapFloatBuffer(float[] buf,
+                              int mark, int pos, int lim, int cap,
+                              int off) {
+        this(buf, mark, pos, lim, cap, off, false);
+    }
+
+    protected HeapFloatBuffer(float[] buf,
+                              int mark, int pos, int lim, int cap,
+                              int off, boolean isReadOnly) {
+        super(mark, pos, lim, cap, buf, off);
+        this.isReadOnly = isReadOnly;
+    }
+
+    public FloatBuffer slice() {
+        return new HeapFloatBuffer(hb,
+                -1,
+                0,
+                this.remaining(),
+                this.remaining(),
+                this.position() + offset,
+                isReadOnly);
+    }
+
+    public FloatBuffer duplicate() {
+        return new HeapFloatBuffer(hb,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset,
+                isReadOnly);
+    }
+
+    public FloatBuffer asReadOnlyBuffer() {
+        return new HeapFloatBuffer(hb,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset, true);
+    }
+
+    protected int ix(int i) {
+        return i + offset;
+    }
+
+    public float get() {
+        return hb[ix(nextGetIndex())];
+    }
+
+    public float get(int i) {
+        return hb[ix(checkIndex(i))];
+    }
+
+    public FloatBuffer get(float[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        System.arraycopy(hb, ix(position()), dst, offset, length);
+        position(position() + length);
+        return this;
+    }
+
+    public boolean isDirect() {
+        return false;
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public FloatBuffer put(float x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(nextPutIndex())] = x;
+        return this;
+    }
+
+    public FloatBuffer put(int i, float x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(checkIndex(i))] = x;
+        return this;
+    }
+
+    public FloatBuffer put(float[] src, int offset, int length) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        System.arraycopy(src, offset, hb, ix(position()), length);
+        position(position() + length);
+        return this;
+    }
+
+    public FloatBuffer put(FloatBuffer src) {
+        if (src == this) {
+            throw new IllegalArgumentException();
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        if (src instanceof HeapFloatBuffer) {
+            HeapFloatBuffer sb = (HeapFloatBuffer) src;
+            int n = sb.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            System.arraycopy(sb.hb, sb.ix(sb.position()),
+                    hb, ix(position()), n);
+            sb.position(sb.position() + n);
+            position(position() + n);
+        } else if (src.isDirect()) {
+            int n = src.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            src.get(hb, ix(position()), n);
+            position(position() + n);
+        } else {
+            super.put(src);
+        }
+        return this;
+    }
+
+    public FloatBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+        position(remaining());
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    public ByteOrder order() {
+        return ByteOrder.nativeOrder();
+    }
+}
diff --git a/java/nio/HeapIntBuffer.java b/java/nio/HeapIntBuffer.java
new file mode 100644
index 0000000..b4f3bf7
--- /dev/null
+++ b/java/nio/HeapIntBuffer.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, 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.nio;
+
+/**
+ * A read/write HeapIntBuffer.
+ */
+
+class HeapIntBuffer extends IntBuffer {
+
+    // For speed these fields are actually declared in X-Buffer;
+    // these declarations are here as documentation
+    /*
+
+      protected final int[] hb;
+      protected final int offset;
+
+    */
+
+    HeapIntBuffer(int cap, int lim) {            // package-private
+        this(cap, lim, false);
+    }
+
+    HeapIntBuffer(int cap, int lim, boolean isReadOnly) {            // package-private
+        super(-1, 0, lim, cap, new int[cap], 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    HeapIntBuffer(int[] buf, int off, int len) { // package-private
+        this(buf, off, len, false);
+    }
+
+    HeapIntBuffer(int[] buf, int off, int len, boolean isReadOnly) { // package-private
+        super(-1, off, off + len, buf.length, buf, 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    protected HeapIntBuffer(int[] buf,
+                            int mark, int pos, int lim, int cap,
+                            int off) {
+        this(buf, mark, pos, lim, cap, off, false);
+    }
+
+    protected HeapIntBuffer(int[] buf,
+                            int mark, int pos, int lim, int cap,
+                            int off, boolean isReadOnly) {
+        super(mark, pos, lim, cap, buf, off);
+        this.isReadOnly = isReadOnly;
+    }
+
+    public IntBuffer slice() {
+        return new HeapIntBuffer(hb,
+                -1,
+                0,
+                this.remaining(),
+                this.remaining(),
+                this.position() + offset,
+                isReadOnly);
+    }
+
+    public IntBuffer duplicate() {
+        return new HeapIntBuffer(hb,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset,
+                isReadOnly);
+    }
+
+    public IntBuffer asReadOnlyBuffer() {
+
+        return new HeapIntBuffer(hb,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset, true);
+    }
+
+    protected int ix(int i) {
+        return i + offset;
+    }
+
+    public int get() {
+        return hb[ix(nextGetIndex())];
+    }
+
+    public int get(int i) {
+        return hb[ix(checkIndex(i))];
+    }
+
+    public IntBuffer get(int[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        System.arraycopy(hb, ix(position()), dst, offset, length);
+        position(position() + length);
+        return this;
+    }
+
+    public boolean isDirect() {
+        return false;
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public IntBuffer put(int x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(nextPutIndex())] = x;
+        return this;
+    }
+
+    public IntBuffer put(int i, int x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(checkIndex(i))] = x;
+        return this;
+    }
+
+    public IntBuffer put(int[] src, int offset, int length) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        System.arraycopy(src, offset, hb, ix(position()), length);
+        position(position() + length);
+        return this;
+    }
+
+    public IntBuffer put(IntBuffer src) {
+        if (src == this) {
+            throw new IllegalArgumentException();
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        if (src instanceof HeapIntBuffer) {
+            HeapIntBuffer sb = (HeapIntBuffer) src;
+            int n = sb.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            System.arraycopy(sb.hb, sb.ix(sb.position()),
+                    hb, ix(position()), n);
+            sb.position(sb.position() + n);
+            position(position() + n);
+        } else if (src.isDirect()) {
+            int n = src.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            src.get(hb, ix(position()), n);
+            position(position() + n);
+        } else {
+            super.put(src);
+        }
+        return this;
+    }
+
+    public IntBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+        position(remaining());
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    public ByteOrder order() {
+        return ByteOrder.nativeOrder();
+    }
+}
diff --git a/java/nio/HeapLongBuffer.java b/java/nio/HeapLongBuffer.java
new file mode 100644
index 0000000..c0678b3
--- /dev/null
+++ b/java/nio/HeapLongBuffer.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, 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.nio;
+
+/**
+ * A read/write HeapLongBuffer.
+ */
+
+class HeapLongBuffer
+        extends LongBuffer {
+
+    // For speed these fields are actually declared in X-Buffer;
+    // these declarations are here as documentation
+    /*
+
+      protected final long[] hb;
+      protected final int offset;
+
+    */
+
+    HeapLongBuffer(int cap, int lim) {            // package-private
+        this(cap, lim, false);
+    }
+
+    HeapLongBuffer(int cap, int lim, boolean isReadOnly) {            // package-private
+        super(-1, 0, lim, cap, new long[cap], 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    HeapLongBuffer(long[] buf, int off, int len) { // package-private
+        this(buf, off, len, false);
+    }
+
+    HeapLongBuffer(long[] buf, int off, int len, boolean isReadOnly) { // package-private
+        super(-1, off, off + len, buf.length, buf, 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    protected HeapLongBuffer(long[] buf,
+                             int mark, int pos, int lim, int cap,
+                             int off) {
+        this(buf, mark, pos, lim, cap, off, false);
+    }
+
+    protected HeapLongBuffer(long[] buf,
+                             int mark, int pos, int lim, int cap,
+                             int off, boolean isReadOnly) {
+        super(mark, pos, lim, cap, buf, off);
+        this.isReadOnly = isReadOnly;
+    }
+
+    public LongBuffer slice() {
+        return new HeapLongBuffer(hb,
+                -1,
+                0,
+                this.remaining(),
+                this.remaining(),
+                this.position() + offset,
+                isReadOnly);
+    }
+
+    public LongBuffer duplicate() {
+        return new HeapLongBuffer(hb,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset,
+                isReadOnly);
+    }
+
+    public LongBuffer asReadOnlyBuffer() {
+        return new HeapLongBuffer(hb,
+                this.markValue(),
+                this.position(),
+                this.limit(),
+                this.capacity(),
+                offset, true);
+    }
+
+
+    protected int ix(int i) {
+        return i + offset;
+    }
+
+    public long get() {
+        return hb[ix(nextGetIndex())];
+    }
+
+    public long get(int i) {
+        return hb[ix(checkIndex(i))];
+    }
+
+    public LongBuffer get(long[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        System.arraycopy(hb, ix(position()), dst, offset, length);
+        position(position() + length);
+        return this;
+    }
+
+    public boolean isDirect() {
+        return false;
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public LongBuffer put(long x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(nextPutIndex())] = x;
+        return this;
+    }
+
+    public LongBuffer put(int i, long x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(checkIndex(i))] = x;
+        return this;
+    }
+
+    public LongBuffer put(long[] src, int offset, int length) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        System.arraycopy(src, offset, hb, ix(position()), length);
+        position(position() + length);
+        return this;
+    }
+
+    public LongBuffer put(LongBuffer src) {
+        if (src == this) {
+            throw new IllegalArgumentException();
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        if (src instanceof HeapLongBuffer) {
+            HeapLongBuffer sb = (HeapLongBuffer) src;
+            int n = sb.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            System.arraycopy(sb.hb, sb.ix(sb.position()),
+                    hb, ix(position()), n);
+            sb.position(sb.position() + n);
+            position(position() + n);
+        } else if (src.isDirect()) {
+            int n = src.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            src.get(hb, ix(position()), n);
+            position(position() + n);
+        } else {
+            super.put(src);
+        }
+        return this;
+    }
+
+    public LongBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+        position(remaining());
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    public ByteOrder order() {
+        return ByteOrder.nativeOrder();
+    }
+}
diff --git a/java/nio/HeapShortBuffer.java b/java/nio/HeapShortBuffer.java
new file mode 100644
index 0000000..af39261
--- /dev/null
+++ b/java/nio/HeapShortBuffer.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, 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.nio;
+
+/**
+ * A read/write HeapShortBuffer.
+ */
+
+class HeapShortBuffer extends ShortBuffer {
+
+    // For speed these fields are actually declared in X-Buffer;
+    // these declarations are here as documentation
+    /*
+
+      protected final short[] hb;
+      protected final int offset;
+
+    */
+
+    HeapShortBuffer(int cap, int lim) {            // package-private
+        this(cap, lim, false);
+    }
+
+    HeapShortBuffer(int cap, int lim, boolean isReadOnly) {            // package-private
+        super(-1, 0, lim, cap, new short[cap], 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    HeapShortBuffer(short[] buf, int off, int len) { // package-private
+        this(buf, off, len, false);
+    }
+
+    HeapShortBuffer(short[] buf, int off, int len, boolean isReadOnly) { // package-private
+        super(-1, off, off + len, buf.length, buf, 0);
+        this.isReadOnly = isReadOnly;
+    }
+
+    protected HeapShortBuffer(short[] buf,
+                              int mark, int pos, int lim, int cap,
+                              int off) {
+        this(buf, mark, pos, lim, cap, off, false);
+    }
+
+    protected HeapShortBuffer(short[] buf,
+                              int mark, int pos, int lim, int cap,
+                              int off, boolean isReadOnly) {
+        super(mark, pos, lim, cap, buf, off);
+        this.isReadOnly = isReadOnly;
+    }
+
+    public ShortBuffer slice() {
+        return new HeapShortBuffer(hb,
+                                   -1,
+                                   0,
+                                   this.remaining(),
+                                   this.remaining(),
+                                   this.position() + offset,
+                                   isReadOnly);
+    }
+
+    public ShortBuffer duplicate() {
+        return new HeapShortBuffer(hb,
+                                   this.markValue(),
+                                   this.position(),
+                                   this.limit(),
+                                   this.capacity(),
+                                   offset,
+                                   isReadOnly);
+    }
+
+    public ShortBuffer asReadOnlyBuffer() {
+
+        return new HeapShortBuffer(hb,
+                                    this.markValue(),
+                                    this.position(),
+                                    this.limit(),
+                                    this.capacity(),
+                                    offset, true);
+    }
+
+    protected int ix(int i) {
+        return i + offset;
+    }
+
+    public short get() {
+        return hb[ix(nextGetIndex())];
+    }
+
+    public short get(int i) {
+        return hb[ix(checkIndex(i))];
+    }
+
+    public ShortBuffer get(short[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        System.arraycopy(hb, ix(position()), dst, offset, length);
+        position(position() + length);
+        return this;
+    }
+
+    public boolean isDirect() {
+        return false;
+    }
+
+    public boolean isReadOnly() {
+        return isReadOnly;
+    }
+
+    public ShortBuffer put(short x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(nextPutIndex())] = x;
+        return this;
+    }
+
+    public ShortBuffer put(int i, short x) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        hb[ix(checkIndex(i))] = x;
+        return this;
+    }
+
+    public ShortBuffer put(short[] src, int offset, int length) {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        System.arraycopy(src, offset, hb, ix(position()), length);
+        position(position() + length);
+        return this;
+    }
+
+    public ShortBuffer put(ShortBuffer src) {
+        if (src == this) {
+            throw new IllegalArgumentException();
+        }
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        if (src instanceof HeapShortBuffer) {
+            HeapShortBuffer sb = (HeapShortBuffer)src;
+            int n = sb.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            System.arraycopy(sb.hb, sb.ix(sb.position()),
+                             hb, ix(position()), n);
+            sb.position(sb.position() + n);
+            position(position() + n);
+        } else if (src.isDirect()) {
+            int n = src.remaining();
+            if (n > remaining())
+                throw new BufferOverflowException();
+            src.get(hb, ix(position()), n);
+            position(position() + n);
+        } else {
+            super.put(src);
+        }
+        return this;
+    }
+
+    public ShortBuffer compact() {
+        if (isReadOnly) {
+            throw new ReadOnlyBufferException();
+        }
+        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
+        position(remaining());
+        limit(capacity());
+        discardMark();
+        return this;
+    }
+
+    public ByteOrder order() {
+        return ByteOrder.nativeOrder();
+    }
+}
diff --git a/java/nio/IntBuffer.java b/java/nio/IntBuffer.java
new file mode 100644
index 0000000..7e34229
--- /dev/null
+++ b/java/nio/IntBuffer.java
@@ -0,0 +1,875 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * An int buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * int buffers:
+ *
+ * <ul>
+ *
+ *   <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ *   {@link #put(int) <i>put</i>} methods that read and write
+ *   single ints; </p></li>
+ *
+ *   <li><p> Relative {@link #get(int[]) <i>bulk get</i>}
+ *   methods that transfer contiguous sequences of ints from this buffer
+ *   into an array; and</p></li>
+ *
+ *   <li><p> Relative {@link #put(int[]) <i>bulk put</i>}
+ *   methods that transfer contiguous sequences of ints from an
+ *   int array or some other int
+ *   buffer into this buffer;&#32;and </p></li>
+ *
+ *
+ *   <li><p> Methods for {@link #compact compacting}, {@link
+ *   #duplicate duplicating}, and {@link #slice slicing}
+ *   an int buffer.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> Int buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(int[]) <i>wrapping</i>} an existing
+ * int array  into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, an int buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>.  A
+ * int buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct.  An int buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct.  Whether or not
+ * an int buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method.  </p>
+ *
+*
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked.  This allows
+ * method invocations to be chained.
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class IntBuffer
+    extends Buffer
+    implements Comparable<IntBuffer>
+{
+
+    // These fields are declared here rather than in Heap-X-Buffer in order to
+    // reduce the number of virtual method invocations needed to access these
+    // values, which is especially costly when coding small buffers.
+    //
+    final int[] hb;                  // Non-null only for heap buffers
+    final int offset;
+    boolean isReadOnly;                 // Valid only for heap buffers
+
+    // Creates a new buffer with the given mark, position, limit, capacity,
+    // backing array, and array offset
+    //
+    IntBuffer(int mark, int pos, int lim, int cap,   // package-private
+                 int[] hb, int offset)
+    {
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 2 /* elementSizeShift */);
+        this.hb = hb;
+        this.offset = offset;
+    }
+
+    // Creates a new buffer with the given mark, position, limit, and capacity
+    //
+    IntBuffer(int mark, int pos, int lim, int cap) { // package-private
+        this(mark, pos, lim, cap, null, 0);
+    }
+
+
+    /**
+     * Allocates a new int buffer.
+     *
+     * <p> The new buffer's position will be zero, its limit will be its
+     * capacity, its mark will be undefined, and each of its elements will be
+     * initialized to zero.  It will have a {@link #array backing array},
+     * and its {@link #arrayOffset array offset} will be zero.
+     *
+     * @param  capacity
+     *         The new buffer's capacity, in ints
+     *
+     * @return  The new int buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the <tt>capacity</tt> is a negative integer
+     */
+    public static IntBuffer allocate(int capacity) {
+        if (capacity < 0)
+            throw new IllegalArgumentException();
+        return new HeapIntBuffer(capacity, capacity);
+    }
+
+    /**
+     * Wraps an int array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given int array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity will be
+     * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+     * will be <tt>offset + length</tt>, and its mark will be undefined.  Its
+     * {@link #array backing array} will be the given array, and
+     * its {@link #arrayOffset array offset} will be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back the new buffer
+     *
+     * @param  offset
+     *         The offset of the subarray to be used; must be non-negative and
+     *         no larger than <tt>array.length</tt>.  The new buffer's position
+     *         will be set to this value.
+     *
+     * @param  length
+     *         The length of the subarray to be used;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>.
+     *         The new buffer's limit will be set to <tt>offset + length</tt>.
+     *
+     * @return  The new int buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public static IntBuffer wrap(int[] array,
+                                    int offset, int length)
+    {
+        try {
+            return new HeapIntBuffer(array, offset, length);
+        } catch (IllegalArgumentException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Wraps an int array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given int array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity and limit will be
+     * <tt>array.length</tt>, its position will be zero, and its mark will be
+     * undefined.  Its {@link #array backing array} will be the
+     * given array, and its {@link #arrayOffset array offset>} will
+     * be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back this buffer
+     *
+     * @return  The new int buffer
+     */
+    public static IntBuffer wrap(int[] array) {
+        return wrap(array, 0, array.length);
+    }
+
+
+    /**
+     * Creates a new int buffer whose content is a shared subsequence of
+     * this buffer's content.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of ints remaining in this buffer, and its mark
+     * will be undefined.  The new buffer will be direct if, and only if, this
+     * buffer is direct, and it will be read-only if, and only if, this buffer
+     * is read-only.  </p>
+     *
+     * @return  The new int buffer
+     */
+    public abstract IntBuffer slice();
+
+    /**
+     * Creates a new int buffer that shares this buffer's content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer, and vice
+     * versa; the two buffers' position, limit, and mark values will be
+     * independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.  The new buffer will be direct if,
+     * and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  The new int buffer
+     */
+    public abstract IntBuffer duplicate();
+
+    /**
+     * Creates a new, read-only int buffer that shares this buffer's
+     * content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer; the new
+     * buffer itself, however, will be read-only and will not allow the shared
+     * content to be modified.  The two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.
+     *
+     * <p> If this buffer is itself read-only then this method behaves in
+     * exactly the same way as the {@link #duplicate duplicate} method.  </p>
+     *
+     * @return  The new, read-only int buffer
+     */
+    public abstract IntBuffer asReadOnlyBuffer();
+
+
+    // -- Singleton get/put methods --
+
+    /**
+     * Relative <i>get</i> method.  Reads the int at this buffer's
+     * current position, and then increments the position.
+     *
+     * @return  The int at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If the buffer's current position is not smaller than its limit
+     */
+    public abstract int get();
+
+    /**
+     * Relative <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given int into this buffer at the current
+     * position, and then increments the position. </p>
+     *
+     * @param  i
+     *         The int to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If this buffer's current position is not smaller than its limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract IntBuffer put(int i);
+
+    /**
+     * Absolute <i>get</i> method.  Reads the int at the given
+     * index.
+     *
+     * @param  index
+     *         The index from which the int will be read
+     *
+     * @return  The int at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     */
+    public abstract int get(int index);
+
+    /**
+     * Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given int into this buffer at the given
+     * index. </p>
+     *
+     * @param  index
+     *         The index at which the int will be written
+     *
+     * @param  i
+     *         The int value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract IntBuffer put(int index, int i);
+
+
+    // -- Bulk get operations --
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers ints from this buffer into the given
+     * destination array.  If there are fewer ints remaining in the
+     * buffer than are required to satisfy the request, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * ints are transferred and a {@link BufferUnderflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> ints from this
+     * buffer into the given array, starting at the current position of this
+     * buffer and at the given offset in the array.  The position of this
+     * buffer is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>src.get(dst,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst[i] = src.get();
+     * }</pre>
+     *
+     * except that it first checks that there are sufficient ints in
+     * this buffer and it is potentially much more efficient.
+     *
+     * @param  dst
+     *         The array into which ints are to be written
+     *
+     * @param  offset
+     *         The offset within the array of the first int to be
+     *         written; must be non-negative and no larger than
+     *         <tt>dst.length</tt>
+     *
+     * @param  length
+     *         The maximum number of ints to be written to the given
+     *         array; must be non-negative and no larger than
+     *         <tt>dst.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> ints
+     *          remaining in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public IntBuffer get(int[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            dst[i] = get();
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers ints from this buffer into the given
+     * destination array.  An invocation of this method of the form
+     * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     src.get(a, 0, a.length) </pre>
+     *
+     * @param   dst
+     *          The destination array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> ints
+     *          remaining in this buffer
+     */
+    public IntBuffer get(int[] dst) {
+        return get(dst, 0, dst.length);
+    }
+
+
+    // -- Bulk put operations --
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the ints remaining in the given source
+     * buffer into this buffer.  If there are more ints remaining in the
+     * source buffer than in this buffer, that is, if
+     * <tt>src.remaining()</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>,
+     * then no ints are transferred and a {@link
+     * BufferOverflowException} is thrown.
+     *
+     * <p> Otherwise, this method copies
+     * <i>n</i>&nbsp;=&nbsp;<tt>src.remaining()</tt> ints from the given
+     * buffer into this buffer, starting at each buffer's current position.
+     * The positions of both buffers are then incremented by <i>n</i>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+     *
+     * <pre>
+     *     while (src.hasRemaining())
+     *         dst.put(src.get()); </pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The source buffer from which ints are to be read;
+     *         must not be this buffer
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *          for the remaining ints in the source buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the source buffer is this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public IntBuffer put(IntBuffer src) {
+        if (src == this)
+            throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
+        int n = src.remaining();
+        if (n > remaining())
+            throw new BufferOverflowException();
+        for (int i = 0; i < n; i++)
+            put(src.get());
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers ints into this buffer from the given
+     * source array.  If there are more ints to be copied from the array
+     * than remain in this buffer, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * ints are transferred and a {@link BufferOverflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> ints from the
+     * given array into this buffer, starting at the given offset in the array
+     * and at the current position of this buffer.  The position of this buffer
+     * is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst.put(a[i]);
+     * }</pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The array from which ints are to be read
+     *
+     * @param  offset
+     *         The offset within the array of the first int to be read;
+     *         must be non-negative and no larger than <tt>array.length</tt>
+     *
+     * @param  length
+     *         The number of ints to be read from the given array;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public IntBuffer put(int[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            this.put(src[i]);
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the entire content of the given source
+     * int array into this buffer.  An invocation of this method of the
+     * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+     * invocation
+     *
+     * <pre>
+     *     dst.put(a, 0, a.length) </pre>
+     *
+     * @param   src
+     *          The source array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public final IntBuffer put(int[] src) {
+        return put(src, 0, src.length);
+    }
+
+
+    // -- Other stuff --
+
+    /**
+     * Tells whether or not this buffer is backed by an accessible int
+     * array.
+     *
+     * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+     * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+     * </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer
+     *          is backed by an array and is not read-only
+     */
+    public final boolean hasArray() {
+        return (hb != null) && !isReadOnly;
+    }
+
+    /**
+     * Returns the int array that backs this
+     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Modifications to this buffer's content will cause the returned
+     * array's content to be modified, and vice versa.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The array that backs this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final int[] array() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return hb;
+    }
+
+    /**
+     * Returns the offset within this buffer's backing array of the first
+     * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> If this buffer is backed by an array then buffer position <i>p</i>
+     * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The offset within this buffer's array
+     *          of the first element of the buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final int arrayOffset() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return offset;
+    }
+
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = IntBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
+    /**
+     * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> The ints between the buffer's current position and its limit,
+     * if any, are copied to the beginning of the buffer.  That is, the
+     * int at index <i>p</i>&nbsp;=&nbsp;<tt>position()</tt> is copied
+     * to index zero, the int at index <i>p</i>&nbsp;+&nbsp;1 is copied
+     * to index one, and so forth until the int at index
+     * <tt>limit()</tt>&nbsp;-&nbsp;1 is copied to index
+     * <i>n</i>&nbsp;=&nbsp;<tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>&nbsp;-&nbsp;<i>p</i>.
+     * The buffer's position is then set to <i>n+1</i> and its limit is set to
+     * its capacity.  The mark, if defined, is discarded.
+     *
+     * <p> The buffer's position is set to the number of ints copied,
+     * rather than to zero, so that an invocation of this method can be
+     * followed immediately by an invocation of another relative <i>put</i>
+     * method. </p>
+     *
+
+     *
+     * @return  This buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract IntBuffer compact();
+
+    /**
+     * Tells whether or not this int buffer is direct.
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is direct
+     */
+    public abstract boolean isDirect();
+
+
+    /**
+     * Returns a string summarizing the state of this buffer.
+     *
+     * @return  A summary string
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName());
+        sb.append("[pos=");
+        sb.append(position());
+        sb.append(" lim=");
+        sb.append(limit());
+        sb.append(" cap=");
+        sb.append(capacity());
+        sb.append("]");
+        return sb.toString();
+    }
+
+
+    /**
+     * Returns the current hash code of this buffer.
+     *
+     * <p> The hash code of a int buffer depends only upon its remaining
+     * elements; that is, upon the elements from <tt>position()</tt> up to, and
+     * including, the element at <tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>.
+     *
+     * <p> Because buffer hash codes are content-dependent, it is inadvisable
+     * to use buffers as keys in hash maps or similar data structures unless it
+     * is known that their contents will not change.  </p>
+     *
+     * @return  The current hash code of this buffer
+     */
+    public int hashCode() {
+        int h = 1;
+        int p = position();
+        for (int i = limit() - 1; i >= p; i--)
+            h = 31 * h + (int) get(i);
+        return h;
+    }
+
+    /**
+     * Tells whether or not this buffer is equal to another object.
+     *
+     * <p> Two int buffers are equal if, and only if,
+     *
+     * <ol>
+     *
+     *   <li><p> They have the same element type,  </p></li>
+     *
+     *   <li><p> They have the same number of remaining elements, and
+     *   </p></li>
+     *
+     *   <li><p> The two sequences of remaining elements, considered
+     *   independently of their starting positions, are pointwise equal.
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     *   </p></li>
+     *
+     * </ol>
+     *
+     * <p> A int buffer is not equal to any other type of object.  </p>
+     *
+     * @param  ob  The object to which this buffer is to be compared
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is equal to the
+     *           given object
+     */
+    public boolean equals(Object ob) {
+        if (this == ob)
+            return true;
+        if (!(ob instanceof IntBuffer))
+            return false;
+        IntBuffer that = (IntBuffer)ob;
+        if (this.remaining() != that.remaining())
+            return false;
+        int p = this.position();
+        for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+            if (!equals(this.get(i), that.get(j)))
+                return false;
+        return true;
+    }
+
+    private static boolean equals(int x, int y) {
+
+
+        return x == y;
+
+    }
+
+    /**
+     * Compares this buffer to another.
+     *
+     * <p> Two int buffers are compared by comparing their sequences of
+     * remaining elements lexicographically, without regard to the starting
+     * position of each sequence within its corresponding buffer.
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     * Pairs of {@code int} elements are compared as if by invoking
+     * {@link Integer#compare(int,int)}.
+
+     *
+     * <p> A int buffer is not comparable to any other type of object.
+     *
+     * @return  A negative integer, zero, or a positive integer as this buffer
+     *          is less than, equal to, or greater than the given buffer
+     */
+    public int compareTo(IntBuffer that) {
+        int n = this.position() + Math.min(this.remaining(), that.remaining());
+        for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+            int cmp = compare(this.get(i), that.get(j));
+            if (cmp != 0)
+                return cmp;
+        }
+        return this.remaining() - that.remaining();
+    }
+
+    private static int compare(int x, int y) {
+
+
+        return Integer.compare(x, y);
+
+    }
+
+    // -- Other char stuff --
+
+
+    // -- Other byte stuff: Access to binary data --
+
+
+    /**
+     * Retrieves this buffer's byte order.
+     *
+     * <p> The byte order of an int buffer created by allocation or by
+     * wrapping an existing <tt>int</tt> array is the {@link
+     * ByteOrder#nativeOrder native order} of the underlying
+     * hardware.  The byte order of an int buffer created as a <a
+     * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+     * byte buffer at the moment that the view is created.  </p>
+     *
+     * @return  This buffer's byte order
+     */
+    public abstract ByteOrder order();
+
+
+}
diff --git a/java/nio/InvalidMarkException.java b/java/nio/InvalidMarkException.java
new file mode 100644
index 0000000..ed1a059
--- /dev/null
+++ b/java/nio/InvalidMarkException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to reset a buffer
+ * when its mark is not defined.
+ *
+ * @since 1.4
+ */
+
+public class InvalidMarkException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = 1698329710438510774L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public InvalidMarkException() { }
+
+}
diff --git a/java/nio/LongBuffer.java b/java/nio/LongBuffer.java
new file mode 100644
index 0000000..5e5fa18
--- /dev/null
+++ b/java/nio/LongBuffer.java
@@ -0,0 +1,868 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * A long buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * long buffers:
+ *
+ * <ul>
+ *
+ *   <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ *   {@link #put(long) <i>put</i>} methods that read and write
+ *   single longs; </p></li>
+ *
+ *   <li><p> Relative {@link #get(long[]) <i>bulk get</i>}
+ *   methods that transfer contiguous sequences of longs from this buffer
+ *   into an array; and</p></li>
+ *
+ *   <li><p> Relative {@link #put(long[]) <i>bulk put</i>}
+ *   methods that transfer contiguous sequences of longs from a
+ *   long array or some other long
+ *   buffer into this buffer;&#32;and </p></li>
+ *
+ *
+ *   <li><p> Methods for {@link #compact compacting}, {@link
+ *   #duplicate duplicating}, and {@link #slice slicing}
+ *   a long buffer.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> Long buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(long[]) <i>wrapping</i>} an existing
+ * long array  into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, a long buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>.  A
+ * long buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct.  A long buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct.  Whether or not
+ * a long buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method.  </p>
+ *
+*
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked.  This allows
+ * method invocations to be chained.
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class LongBuffer
+    extends Buffer
+    implements Comparable<LongBuffer>
+{
+
+    // These fields are declared here rather than in Heap-X-Buffer in order to
+    // reduce the number of virtual method invocations needed to access these
+    // values, which is especially costly when coding small buffers.
+    //
+    final long[] hb;                  // Non-null only for heap buffers
+    final int offset;
+    boolean isReadOnly;                 // Valid only for heap buffers
+
+    // Creates a new buffer with the given mark, position, limit, capacity,
+    // backing array, and array offset
+    //
+    LongBuffer(int mark, int pos, int lim, int cap,   // package-private
+                 long[] hb, int offset)
+    {
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 3 /* elementSizeShift */);
+        this.hb = hb;
+        this.offset = offset;
+    }
+
+    // Creates a new buffer with the given mark, position, limit, and capacity
+    //
+    LongBuffer(int mark, int pos, int lim, int cap) { // package-private
+        this(mark, pos, lim, cap, null, 0);
+    }
+
+
+    /**
+     * Allocates a new long buffer.
+     *
+     * <p> The new buffer's position will be zero, its limit will be its
+     * capacity, its mark will be undefined, and each of its elements will be
+     * initialized to zero.  It will have a {@link #array backing array},
+     * and its {@link #arrayOffset array offset} will be zero.
+     *
+     * @param  capacity
+     *         The new buffer's capacity, in longs
+     *
+     * @return  The new long buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the <tt>capacity</tt> is a negative integer
+     */
+    public static LongBuffer allocate(int capacity) {
+        if (capacity < 0)
+            throw new IllegalArgumentException();
+        return new HeapLongBuffer(capacity, capacity);
+    }
+
+    /**
+     * Wraps a long array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given long array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity will be
+     * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+     * will be <tt>offset + length</tt>, and its mark will be undefined.  Its
+     * {@link #array backing array} will be the given array, and
+     * its {@link #arrayOffset array offset} will be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back the new buffer
+     *
+     * @param  offset
+     *         The offset of the subarray to be used; must be non-negative and
+     *         no larger than <tt>array.length</tt>.  The new buffer's position
+     *         will be set to this value.
+     *
+     * @param  length
+     *         The length of the subarray to be used;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>.
+     *         The new buffer's limit will be set to <tt>offset + length</tt>.
+     *
+     * @return  The new long buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public static LongBuffer wrap(long[] array,
+                                    int offset, int length)
+    {
+        try {
+            return new HeapLongBuffer(array, offset, length);
+        } catch (IllegalArgumentException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Wraps a long array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given long array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity and limit will be
+     * <tt>array.length</tt>, its position will be zero, and its mark will be
+     * undefined.  Its {@link #array backing array} will be the
+     * given array, and its {@link #arrayOffset array offset>} will
+     * be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back this buffer
+     *
+     * @return  The new long buffer
+     */
+    public static LongBuffer wrap(long[] array) {
+        return wrap(array, 0, array.length);
+    }
+
+
+    /**
+     * Creates a new long buffer whose content is a shared subsequence of
+     * this buffer's content.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of longs remaining in this buffer, and its mark
+     * will be undefined.  The new buffer will be direct if, and only if, this
+     * buffer is direct, and it will be read-only if, and only if, this buffer
+     * is read-only.  </p>
+     *
+     * @return  The new long buffer
+     */
+    public abstract LongBuffer slice();
+
+    /**
+     * Creates a new long buffer that shares this buffer's content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer, and vice
+     * versa; the two buffers' position, limit, and mark values will be
+     * independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.  The new buffer will be direct if,
+     * and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  The new long buffer
+     */
+    public abstract LongBuffer duplicate();
+
+    /**
+     * Creates a new, read-only long buffer that shares this buffer's
+     * content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer; the new
+     * buffer itself, however, will be read-only and will not allow the shared
+     * content to be modified.  The two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.
+     *
+     * <p> If this buffer is itself read-only then this method behaves in
+     * exactly the same way as the {@link #duplicate duplicate} method.  </p>
+     *
+     * @return  The new, read-only long buffer
+     */
+    public abstract LongBuffer asReadOnlyBuffer();
+
+
+    // -- Singleton get/put methods --
+
+    /**
+     * Relative <i>get</i> method.  Reads the long at this buffer's
+     * current position, and then increments the position.
+     *
+     * @return  The long at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If the buffer's current position is not smaller than its limit
+     */
+    public abstract long get();
+
+    /**
+     * Relative <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given long into this buffer at the current
+     * position, and then increments the position. </p>
+     *
+     * @param  l
+     *         The long to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If this buffer's current position is not smaller than its limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract LongBuffer put(long l);
+
+    /**
+     * Absolute <i>get</i> method.  Reads the long at the given
+     * index.
+     *
+     * @param  index
+     *         The index from which the long will be read
+     *
+     * @return  The long at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     */
+    public abstract long get(int index);
+
+    /**
+     * Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given long into this buffer at the given
+     * index. </p>
+     *
+     * @param  index
+     *         The index at which the long will be written
+     *
+     * @param  l
+     *         The long value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract LongBuffer put(int index, long l);
+
+
+    // -- Bulk get operations --
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers longs from this buffer into the given
+     * destination array.  If there are fewer longs remaining in the
+     * buffer than are required to satisfy the request, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * longs are transferred and a {@link BufferUnderflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> longs from this
+     * buffer into the given array, starting at the current position of this
+     * buffer and at the given offset in the array.  The position of this
+     * buffer is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>src.get(dst,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst[i] = src.get();
+     * }</pre>
+     *
+     * except that it first checks that there are sufficient longs in
+     * this buffer and it is potentially much more efficient.
+     *
+     * @param  dst
+     *         The array into which longs are to be written
+     *
+     * @param  offset
+     *         The offset within the array of the first long to be
+     *         written; must be non-negative and no larger than
+     *         <tt>dst.length</tt>
+     *
+     * @param  length
+     *         The maximum number of longs to be written to the given
+     *         array; must be non-negative and no larger than
+     *         <tt>dst.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> longs
+     *          remaining in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public LongBuffer get(long[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            dst[i] = get();
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers longs from this buffer into the given
+     * destination array.  An invocation of this method of the form
+     * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     src.get(a, 0, a.length) </pre>
+     *
+     * @param   dst
+     *          The destination array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> longs
+     *          remaining in this buffer
+     */
+    public LongBuffer get(long[] dst) {
+        return get(dst, 0, dst.length);
+    }
+
+
+    // -- Bulk put operations --
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the longs remaining in the given source
+     * buffer into this buffer.  If there are more longs remaining in the
+     * source buffer than in this buffer, that is, if
+     * <tt>src.remaining()</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>,
+     * then no longs are transferred and a {@link
+     * BufferOverflowException} is thrown.
+     *
+     * <p> Otherwise, this method copies
+     * <i>n</i>&nbsp;=&nbsp;<tt>src.remaining()</tt> longs from the given
+     * buffer into this buffer, starting at each buffer's current position.
+     * The positions of both buffers are then incremented by <i>n</i>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+     *
+     * <pre>
+     *     while (src.hasRemaining())
+     *         dst.put(src.get()); </pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The source buffer from which longs are to be read;
+     *         must not be this buffer
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *          for the remaining longs in the source buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the source buffer is this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public LongBuffer put(LongBuffer src) {
+        if (src == this)
+            throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
+        int n = src.remaining();
+        if (n > remaining())
+            throw new BufferOverflowException();
+        for (int i = 0; i < n; i++)
+            put(src.get());
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers longs into this buffer from the given
+     * source array.  If there are more longs to be copied from the array
+     * than remain in this buffer, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * longs are transferred and a {@link BufferOverflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> longs from the
+     * given array into this buffer, starting at the given offset in the array
+     * and at the current position of this buffer.  The position of this buffer
+     * is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst.put(a[i]);
+     * }</pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The array from which longs are to be read
+     *
+     * @param  offset
+     *         The offset within the array of the first long to be read;
+     *         must be non-negative and no larger than <tt>array.length</tt>
+     *
+     * @param  length
+     *         The number of longs to be read from the given array;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public LongBuffer put(long[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            this.put(src[i]);
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the entire content of the given source
+     * long array into this buffer.  An invocation of this method of the
+     * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+     * invocation
+     *
+     * <pre>
+     *     dst.put(a, 0, a.length) </pre>
+     *
+     * @param   src
+     *          The source array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public final LongBuffer put(long[] src) {
+        return put(src, 0, src.length);
+    }
+
+
+    // -- Other stuff --
+
+    /**
+     * Tells whether or not this buffer is backed by an accessible long
+     * array.
+     *
+     * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+     * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+     * </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer
+     *          is backed by an array and is not read-only
+     */
+    public final boolean hasArray() {
+        return (hb != null) && !isReadOnly;
+    }
+
+    /**
+     * Returns the long array that backs this
+     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Modifications to this buffer's content will cause the returned
+     * array's content to be modified, and vice versa.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The array that backs this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final long[] array() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return hb;
+    }
+
+    /**
+     * Returns the offset within this buffer's backing array of the first
+     * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> If this buffer is backed by an array then buffer position <i>p</i>
+     * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The offset within this buffer's array
+     *          of the first element of the buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final int arrayOffset() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return offset;
+    }
+
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = LongBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
+    /**
+     * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> The longs between the buffer's current position and its limit,
+     * if any, are copied to the beginning of the buffer.  That is, the
+     * long at index <i>p</i>&nbsp;=&nbsp;<tt>position()</tt> is copied
+     * to index zero, the long at index <i>p</i>&nbsp;+&nbsp;1 is copied
+     * to index one, and so forth until the long at index
+     * <tt>limit()</tt>&nbsp;-&nbsp;1 is copied to index
+     * <i>n</i>&nbsp;=&nbsp;<tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>&nbsp;-&nbsp;<i>p</i>.
+     * The buffer's position is then set to <i>n+1</i> and its limit is set to
+     * its capacity.  The mark, if defined, is discarded.
+     *
+     * <p> The buffer's position is set to the number of longs copied,
+     * rather than to zero, so that an invocation of this method can be
+     * followed immediately by an invocation of another relative <i>put</i>
+     * method. </p>
+     *
+
+     *
+     * @return  This buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract LongBuffer compact();
+
+    /**
+     * Tells whether or not this long buffer is direct.
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is direct
+     */
+    public abstract boolean isDirect();
+
+
+    /**
+     * Returns a string summarizing the state of this buffer.
+     *
+     * @return  A summary string
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName());
+        sb.append("[pos=");
+        sb.append(position());
+        sb.append(" lim=");
+        sb.append(limit());
+        sb.append(" cap=");
+        sb.append(capacity());
+        sb.append("]");
+        return sb.toString();
+    }
+
+
+    /**
+     * Returns the current hash code of this buffer.
+     *
+     * <p> The hash code of a long buffer depends only upon its remaining
+     * elements; that is, upon the elements from <tt>position()</tt> up to, and
+     * including, the element at <tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>.
+     *
+     * <p> Because buffer hash codes are content-dependent, it is inadvisable
+     * to use buffers as keys in hash maps or similar data structures unless it
+     * is known that their contents will not change.  </p>
+     *
+     * @return  The current hash code of this buffer
+     */
+    public int hashCode() {
+        int h = 1;
+        int p = position();
+        for (int i = limit() - 1; i >= p; i--)
+            h = 31 * h + (int) get(i);
+        return h;
+    }
+
+    /**
+     * Tells whether or not this buffer is equal to another object.
+     *
+     * <p> Two long buffers are equal if, and only if,
+     *
+     * <ol>
+     *
+     *   <li><p> They have the same element type,  </p></li>
+     *
+     *   <li><p> They have the same number of remaining elements, and
+     *   </p></li>
+     *
+     *   <li><p> The two sequences of remaining elements, considered
+     *   independently of their starting positions, are pointwise equal.
+
+     *   </p></li>
+     *
+     * </ol>
+     *
+     * <p> A long buffer is not equal to any other type of object.  </p>
+     *
+     * @param  ob  The object to which this buffer is to be compared
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is equal to the
+     *           given object
+     */
+    public boolean equals(Object ob) {
+        if (this == ob)
+            return true;
+        if (!(ob instanceof LongBuffer))
+            return false;
+        LongBuffer that = (LongBuffer)ob;
+        if (this.remaining() != that.remaining())
+            return false;
+        int p = this.position();
+        for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+            if (!equals(this.get(i), that.get(j)))
+                return false;
+        return true;
+    }
+
+    private static boolean equals(long x, long y) {
+
+
+        return x == y;
+
+    }
+
+    /**
+     * Compares this buffer to another.
+     *
+     * <p> Two long buffers are compared by comparing their sequences of
+     * remaining elements lexicographically, without regard to the starting
+     * position of each sequence within its corresponding buffer.
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     * Pairs of {@code long} elements are compared as if by invoking
+     * {@link Long#compare(long,long)}.
+
+     *
+     * <p> A long buffer is not comparable to any other type of object.
+     *
+     * @return  A negative integer, zero, or a positive integer as this buffer
+     *          is less than, equal to, or greater than the given buffer
+     */
+    public int compareTo(LongBuffer that) {
+        int n = this.position() + Math.min(this.remaining(), that.remaining());
+        for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+            int cmp = compare(this.get(i), that.get(j));
+            if (cmp != 0)
+                return cmp;
+        }
+        return this.remaining() - that.remaining();
+    }
+
+    private static int compare(long x, long y) {
+
+
+        return Long.compare(x, y);
+
+    }
+
+    // -- Other char stuff --
+
+
+    // -- Other byte stuff: Access to binary data --
+
+
+    /**
+     * Retrieves this buffer's byte order.
+     *
+     * <p> The byte order of a long buffer created by allocation or by
+     * wrapping an existing <tt>long</tt> array is the {@link
+     * ByteOrder#nativeOrder native order} of the underlying
+     * hardware.  The byte order of a long buffer created as a <a
+     * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+     * byte buffer at the moment that the view is created.  </p>
+     *
+     * @return  This buffer's byte order
+     */
+    public abstract ByteOrder order();
+
+
+}
diff --git a/java/nio/MappedByteBuffer.java b/java/nio/MappedByteBuffer.java
new file mode 100644
index 0000000..2ea6cbd
--- /dev/null
+++ b/java/nio/MappedByteBuffer.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio;
+
+import java.io.FileDescriptor;
+import sun.misc.Unsafe;
+
+
+/**
+ * A direct byte buffer whose content is a memory-mapped region of a file.
+ *
+ * <p> Mapped byte buffers are created via the {@link
+ * java.nio.channels.FileChannel#map FileChannel.map} method.  This class
+ * extends the {@link ByteBuffer} class with operations that are specific to
+ * memory-mapped file regions.
+ *
+ * <p> A mapped byte buffer and the file mapping that it represents remain
+ * valid until the buffer itself is garbage-collected.
+ *
+ * <p> The content of a mapped byte buffer can change at any time, for example
+ * if the content of the corresponding region of the mapped file is changed by
+ * this program or another.  Whether or not such changes occur, and when they
+ * occur, is operating-system dependent and therefore unspecified.
+ *
+ * <a name="inaccess"></a><p> All or part of a mapped byte buffer may become
+ * inaccessible at any time, for example if the mapped file is truncated.  An
+ * attempt to access an inaccessible region of a mapped byte buffer will not
+ * change the buffer's content and will cause an unspecified exception to be
+ * thrown either at the time of the access or at some later time.  It is
+ * therefore strongly recommended that appropriate precautions be taken to
+ * avoid the manipulation of a mapped file by this program, or by a
+ * concurrently running program, except to read or write the file's content.
+ *
+ * <p> Mapped byte buffers otherwise behave no differently than ordinary direct
+ * byte buffers. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class MappedByteBuffer
+    extends ByteBuffer
+{
+
+    // This is a little bit backwards: By rights MappedByteBuffer should be a
+    // subclass of DirectByteBuffer, but to keep the spec clear and simple, and
+    // for optimization purposes, it's easier to do it the other way around.
+    // This works because DirectByteBuffer is a package-private class.
+
+    // For mapped buffers, a FileDescriptor that may be used for mapping
+    // operations if valid; null if the buffer is not mapped.
+    private final FileDescriptor fd;
+
+    // This should only be invoked by the DirectByteBuffer constructors
+    //
+    MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
+                     FileDescriptor fd)
+    {
+        super(mark, pos, lim, cap);
+        this.fd = fd;
+    }
+
+    // Android-added: Additional constructor for use by Android's DirectByteBuffer.
+    MappedByteBuffer(int mark, int pos, int lim, int cap, byte[] buf, int offset) {
+        super(mark, pos, lim, cap, buf, offset);
+        this.fd = null;
+    }
+
+    MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private
+        super(mark, pos, lim, cap);
+        this.fd = null;
+    }
+
+    private void checkMapped() {
+        if (fd == null)
+            // Can only happen if a luser explicitly casts a direct byte buffer
+            throw new UnsupportedOperationException();
+    }
+
+    // Returns the distance (in bytes) of the buffer from the page aligned address
+    // of the mapping. Computed each time to avoid storing in every direct buffer.
+    private long mappingOffset() {
+        int ps = Bits.pageSize();
+        long offset = address % ps;
+        return (offset >= 0) ? offset : (ps + offset);
+    }
+
+    private long mappingAddress(long mappingOffset) {
+        return address - mappingOffset;
+    }
+
+    private long mappingLength(long mappingOffset) {
+        return (long)capacity() + mappingOffset;
+    }
+
+    /**
+     * Tells whether or not this buffer's content is resident in physical
+     * memory.
+     *
+     * <p> A return value of <tt>true</tt> implies that it is highly likely
+     * that all of the data in this buffer is resident in physical memory and
+     * may therefore be accessed without incurring any virtual-memory page
+     * faults or I/O operations.  A return value of <tt>false</tt> does not
+     * necessarily imply that the buffer's content is not resident in physical
+     * memory.
+     *
+     * <p> The returned value is a hint, rather than a guarantee, because the
+     * underlying operating system may have paged out some of the buffer's data
+     * by the time that an invocation of this method returns.  </p>
+     *
+     * @return  <tt>true</tt> if it is likely that this buffer's content
+     *          is resident in physical memory
+     */
+    public final boolean isLoaded() {
+        checkMapped();
+        if ((address == 0) || (capacity() == 0))
+            return true;
+        long offset = mappingOffset();
+        long length = mappingLength(offset);
+        return isLoaded0(mappingAddress(offset), length, Bits.pageCount(length));
+    }
+
+    // not used, but a potential target for a store, see load() for details.
+    private static byte unused;
+
+    /**
+     * Loads this buffer's content into physical memory.
+     *
+     * <p> This method makes a best effort to ensure that, when it returns,
+     * this buffer's content is resident in physical memory.  Invoking this
+     * method may cause some number of page faults and I/O operations to
+     * occur. </p>
+     *
+     * @return  This buffer
+     */
+    public final MappedByteBuffer load() {
+        checkMapped();
+        if ((address == 0) || (capacity() == 0))
+            return this;
+        long offset = mappingOffset();
+        long length = mappingLength(offset);
+        load0(mappingAddress(offset), length);
+
+        // Read a byte from each page to bring it into memory. A checksum
+        // is computed as we go along to prevent the compiler from otherwise
+        // considering the loop as dead code.
+        Unsafe unsafe = Unsafe.getUnsafe();
+        int ps = Bits.pageSize();
+        int count = Bits.pageCount(length);
+        long a = mappingAddress(offset);
+        byte x = 0;
+        for (int i=0; i<count; i++) {
+            x ^= unsafe.getByte(a);
+            a += ps;
+        }
+        if (unused != 0)
+            unused = x;
+
+        return this;
+    }
+
+    /**
+     * Forces any changes made to this buffer's content to be written to the
+     * storage device containing the mapped file.
+     *
+     * <p> If the file mapped into this buffer resides on a local storage
+     * device then when this method returns it is guaranteed that all changes
+     * made to the buffer since it was created, or since this method was last
+     * invoked, will have been written to that device.
+     *
+     * <p> If the file does not reside on a local device then no such guarantee
+     * is made.
+     *
+     * <p> If this buffer was not mapped in read/write mode ({@link
+     * java.nio.channels.FileChannel.MapMode#READ_WRITE}) then invoking this
+     * method has no effect. </p>
+     *
+     * @return  This buffer
+     */
+    public final MappedByteBuffer force() {
+        checkMapped();
+        if ((address != 0) && (capacity() != 0)) {
+            long offset = mappingOffset();
+            force0(fd, mappingAddress(offset), mappingLength(offset));
+        }
+        return this;
+    }
+
+    private native boolean isLoaded0(long address, long length, int pageCount);
+    private native void load0(long address, long length);
+    private native void force0(FileDescriptor fd, long address, long length);
+}
diff --git a/java/nio/NIOAccess.java b/java/nio/NIOAccess.java
new file mode 100644
index 0000000..7345379
--- /dev/null
+++ b/java/nio/NIOAccess.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.nio;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+/**
+ * This class is used via JNI by code in frameworks/base/ and
+ * by the JniConstants cache in libnativehelper/.
+ * @hide
+ */
+// @VisibleForTesting : was default
[email protected]
+public final class NIOAccess {
+
+    /**
+     * Returns the underlying native pointer to the data of the given
+     * Buffer starting at the Buffer's current position, or 0 if the
+     * Buffer is not backed by native heap storage.
+     * @hide
+     */
+    // @VisibleForTesting : was default
+    @UnsupportedAppUsage
+    public static long getBasePointer(Buffer b) {
+        long address = b.address;
+        if (address == 0L) {
+            return 0L;
+        }
+        return address + (b.position << b._elementSizeShift);
+    }
+
+    /**
+     * Returns the underlying Java array containing the data of the
+     * given Buffer, or null if the Buffer is not backed by a Java array.
+     */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static Object getBaseArray(Buffer b) {
+        return b.hasArray() ? b.array() : null;
+    }
+
+    /**
+     * Returns the offset in bytes from the start of the underlying
+     * Java array object containing the data of the given Buffer to
+     * the actual start of the data. The start of the data takes into
+     * account the Buffer's current position. This method is only
+     * meaningful if getBaseArray() returns non-null.
+     */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static int getBaseArrayOffset(Buffer b) {
+        return b.hasArray() ? ((b.arrayOffset() + b.position) << b._elementSizeShift) : 0;
+    }
+}
diff --git a/java/nio/NioUtils.java b/java/nio/NioUtils.java
new file mode 100644
index 0000000..aca91b0
--- /dev/null
+++ b/java/nio/NioUtils.java
@@ -0,0 +1,92 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.nio;
+
+import android.compat.annotation.UnsupportedAppUsage;
+
+import java.io.Closeable;
+import java.io.FileDescriptor;
+import java.nio.channels.FileChannel;
+
+import sun.nio.ch.FileChannelImpl;
+
+import static android.system.OsConstants.O_ACCMODE;
+import static android.system.OsConstants.O_APPEND;
+import static android.system.OsConstants.O_RDONLY;
+import static android.system.OsConstants.O_WRONLY;
+
+/**
+ * @hide internal use only
+ */
[email protected]
+public final class NioUtils {
+    private NioUtils() {
+    }
+
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static void freeDirectBuffer(ByteBuffer buffer) {
+        if (buffer == null) {
+            return;
+        }
+
+        DirectByteBuffer dbb = (DirectByteBuffer) buffer;
+        // Run the cleaner early, if one is defined.
+        if (dbb.cleaner != null) {
+            dbb.cleaner.clean();
+        }
+
+        dbb.memoryRef.free();
+    }
+
+    /**
+     * Returns the int file descriptor from within the given FileChannel 'fc'.
+     */
+    public static FileDescriptor getFD(FileChannel fc) {
+        return ((FileChannelImpl) fc).fd;
+    }
+
+    /**
+     * Helps bridge between io and nio.
+     */
+    public static FileChannel newFileChannel(Closeable ioObject, FileDescriptor fd, int mode) {
+        boolean readable = (mode & O_ACCMODE) != O_WRONLY;
+        boolean writable = (mode & O_ACCMODE) != O_RDONLY;
+        boolean append = (mode & O_APPEND) != 0;
+        return FileChannelImpl.open(fd, null, readable, writable, append, ioObject);
+    }
+
+    /**
+     * Exposes the array backing a non-direct ByteBuffer, even if the ByteBuffer is read-only.
+     * Normally, attempting to access the array backing a read-only buffer throws.
+     */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static byte[] unsafeArray(ByteBuffer b) {
+        return b.array();
+    }
+
+    /**
+     * Exposes the array offset for the array backing a non-direct ByteBuffer,
+     * even if the ByteBuffer is read-only.
+     */
+    @UnsupportedAppUsage
+    @libcore.api.CorePlatformApi
+    public static int unsafeArrayOffset(ByteBuffer b) {
+        return b.arrayOffset();
+    }
+}
diff --git a/java/nio/ReadOnlyBufferException.java b/java/nio/ReadOnlyBufferException.java
new file mode 100644
index 0000000..5eb4b95
--- /dev/null
+++ b/java/nio/ReadOnlyBufferException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+/**
+ * Unchecked exception thrown when a content-mutation method such as
+ * <tt>put</tt> or <tt>compact</tt> is invoked upon a read-only buffer.
+ *
+ * @since 1.4
+ */
+
+public class ReadOnlyBufferException
+    extends UnsupportedOperationException
+{
+
+    private static final long serialVersionUID = -1210063976496234090L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ReadOnlyBufferException() { }
+
+}
diff --git a/java/nio/ShortBuffer.java b/java/nio/ShortBuffer.java
new file mode 100644
index 0000000..b2a479c
--- /dev/null
+++ b/java/nio/ShortBuffer.java
@@ -0,0 +1,868 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio;
+
+
+import dalvik.annotation.codegen.CovariantReturnType;
+
+/**
+ * A short buffer.
+ *
+ * <p> This class defines four categories of operations upon
+ * short buffers:
+ *
+ * <ul>
+ *
+ *   <li><p> Absolute and relative {@link #get() <i>get</i>} and
+ *   {@link #put(short) <i>put</i>} methods that read and write
+ *   single shorts; </p></li>
+ *
+ *   <li><p> Relative {@link #get(short[]) <i>bulk get</i>}
+ *   methods that transfer contiguous sequences of shorts from this buffer
+ *   into an array; and</p></li>
+ *
+ *   <li><p> Relative {@link #put(short[]) <i>bulk put</i>}
+ *   methods that transfer contiguous sequences of shorts from a
+ *   short array or some other short
+ *   buffer into this buffer;&#32;and </p></li>
+ *
+ *
+ *   <li><p> Methods for {@link #compact compacting}, {@link
+ *   #duplicate duplicating}, and {@link #slice slicing}
+ *   a short buffer.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> Short buffers can be created either by {@link #allocate
+ * <i>allocation</i>}, which allocates space for the buffer's
+ *
+ *
+ * content, by {@link #wrap(short[]) <i>wrapping</i>} an existing
+ * short array  into a buffer, or by creating a
+ * <a href="ByteBuffer.html#views"><i>view</i></a> of an existing byte buffer.
+ *
+ *
+*
+ *
+ * <p> Like a byte buffer, a short buffer is either <a
+ * href="ByteBuffer.html#direct"><i>direct</i> or <i>non-direct</i></a>.  A
+ * short buffer created via the <tt>wrap</tt> methods of this class will
+ * be non-direct.  A short buffer created as a view of a byte buffer will
+ * be direct if, and only if, the byte buffer itself is direct.  Whether or not
+ * a short buffer is direct may be determined by invoking the {@link
+ * #isDirect isDirect} method.  </p>
+ *
+*
+ *
+ *
+ * <p> Methods in this class that do not otherwise have a value to return are
+ * specified to return the buffer upon which they are invoked.  This allows
+ * method invocations to be chained.
+ *
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class ShortBuffer
+    extends Buffer
+    implements Comparable<ShortBuffer>
+{
+
+    // These fields are declared here rather than in Heap-X-Buffer in order to
+    // reduce the number of virtual method invocations needed to access these
+    // values, which is especially costly when coding small buffers.
+    //
+    final short[] hb;                  // Non-null only for heap buffers
+    final int offset;
+    boolean isReadOnly;                 // Valid only for heap buffers
+
+    // Creates a new buffer with the given mark, position, limit, capacity,
+    // backing array, and array offset
+    //
+    ShortBuffer(int mark, int pos, int lim, int cap,   // package-private
+                 short[] hb, int offset)
+    {
+        // Android-added: elementSizeShift parameter (log2 of element size).
+        super(mark, pos, lim, cap, 1 /* elementSizeShift */);
+        this.hb = hb;
+        this.offset = offset;
+    }
+
+    // Creates a new buffer with the given mark, position, limit, and capacity
+    //
+    ShortBuffer(int mark, int pos, int lim, int cap) { // package-private
+        this(mark, pos, lim, cap, null, 0);
+    }
+
+
+    /**
+     * Allocates a new short buffer.
+     *
+     * <p> The new buffer's position will be zero, its limit will be its
+     * capacity, its mark will be undefined, and each of its elements will be
+     * initialized to zero.  It will have a {@link #array backing array},
+     * and its {@link #arrayOffset array offset} will be zero.
+     *
+     * @param  capacity
+     *         The new buffer's capacity, in shorts
+     *
+     * @return  The new short buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the <tt>capacity</tt> is a negative integer
+     */
+    public static ShortBuffer allocate(int capacity) {
+        if (capacity < 0)
+            throw new IllegalArgumentException();
+        return new HeapShortBuffer(capacity, capacity);
+    }
+
+    /**
+     * Wraps a short array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given short array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity will be
+     * <tt>array.length</tt>, its position will be <tt>offset</tt>, its limit
+     * will be <tt>offset + length</tt>, and its mark will be undefined.  Its
+     * {@link #array backing array} will be the given array, and
+     * its {@link #arrayOffset array offset} will be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back the new buffer
+     *
+     * @param  offset
+     *         The offset of the subarray to be used; must be non-negative and
+     *         no larger than <tt>array.length</tt>.  The new buffer's position
+     *         will be set to this value.
+     *
+     * @param  length
+     *         The length of the subarray to be used;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>.
+     *         The new buffer's limit will be set to <tt>offset + length</tt>.
+     *
+     * @return  The new short buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public static ShortBuffer wrap(short[] array,
+                                    int offset, int length)
+    {
+        try {
+            return new HeapShortBuffer(array, offset, length);
+        } catch (IllegalArgumentException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /**
+     * Wraps a short array into a buffer.
+     *
+     * <p> The new buffer will be backed by the given short array;
+     * that is, modifications to the buffer will cause the array to be modified
+     * and vice versa.  The new buffer's capacity and limit will be
+     * <tt>array.length</tt>, its position will be zero, and its mark will be
+     * undefined.  Its {@link #array backing array} will be the
+     * given array, and its {@link #arrayOffset array offset>} will
+     * be zero.  </p>
+     *
+     * @param  array
+     *         The array that will back this buffer
+     *
+     * @return  The new short buffer
+     */
+    public static ShortBuffer wrap(short[] array) {
+        return wrap(array, 0, array.length);
+    }
+
+
+    /**
+     * Creates a new short buffer whose content is a shared subsequence of
+     * this buffer's content.
+     *
+     * <p> The content of the new buffer will start at this buffer's current
+     * position.  Changes to this buffer's content will be visible in the new
+     * buffer, and vice versa; the two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's position will be zero, its capacity and its limit
+     * will be the number of shorts remaining in this buffer, and its mark
+     * will be undefined.  The new buffer will be direct if, and only if, this
+     * buffer is direct, and it will be read-only if, and only if, this buffer
+     * is read-only.  </p>
+     *
+     * @return  The new short buffer
+     */
+    public abstract ShortBuffer slice();
+
+    /**
+     * Creates a new short buffer that shares this buffer's content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer, and vice
+     * versa; the two buffers' position, limit, and mark values will be
+     * independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.  The new buffer will be direct if,
+     * and only if, this buffer is direct, and it will be read-only if, and
+     * only if, this buffer is read-only.  </p>
+     *
+     * @return  The new short buffer
+     */
+    public abstract ShortBuffer duplicate();
+
+    /**
+     * Creates a new, read-only short buffer that shares this buffer's
+     * content.
+     *
+     * <p> The content of the new buffer will be that of this buffer.  Changes
+     * to this buffer's content will be visible in the new buffer; the new
+     * buffer itself, however, will be read-only and will not allow the shared
+     * content to be modified.  The two buffers' position, limit, and mark
+     * values will be independent.
+     *
+     * <p> The new buffer's capacity, limit, position, and mark values will be
+     * identical to those of this buffer.
+     *
+     * <p> If this buffer is itself read-only then this method behaves in
+     * exactly the same way as the {@link #duplicate duplicate} method.  </p>
+     *
+     * @return  The new, read-only short buffer
+     */
+    public abstract ShortBuffer asReadOnlyBuffer();
+
+
+    // -- Singleton get/put methods --
+
+    /**
+     * Relative <i>get</i> method.  Reads the short at this buffer's
+     * current position, and then increments the position.
+     *
+     * @return  The short at the buffer's current position
+     *
+     * @throws  BufferUnderflowException
+     *          If the buffer's current position is not smaller than its limit
+     */
+    public abstract short get();
+
+    /**
+     * Relative <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given short into this buffer at the current
+     * position, and then increments the position. </p>
+     *
+     * @param  s
+     *         The short to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If this buffer's current position is not smaller than its limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ShortBuffer put(short s);
+
+    /**
+     * Absolute <i>get</i> method.  Reads the short at the given
+     * index.
+     *
+     * @param  index
+     *         The index from which the short will be read
+     *
+     * @return  The short at the given index
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     */
+    public abstract short get(int index);
+
+    /**
+     * Absolute <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Writes the given short into this buffer at the given
+     * index. </p>
+     *
+     * @param  index
+     *         The index at which the short will be written
+     *
+     * @param  s
+     *         The short value to be written
+     *
+     * @return  This buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If <tt>index</tt> is negative
+     *          or not smaller than the buffer's limit
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ShortBuffer put(int index, short s);
+
+
+    // -- Bulk get operations --
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers shorts from this buffer into the given
+     * destination array.  If there are fewer shorts remaining in the
+     * buffer than are required to satisfy the request, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * shorts are transferred and a {@link BufferUnderflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> shorts from this
+     * buffer into the given array, starting at the current position of this
+     * buffer and at the given offset in the array.  The position of this
+     * buffer is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>src.get(dst,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst[i] = src.get();
+     * }</pre>
+     *
+     * except that it first checks that there are sufficient shorts in
+     * this buffer and it is potentially much more efficient.
+     *
+     * @param  dst
+     *         The array into which shorts are to be written
+     *
+     * @param  offset
+     *         The offset within the array of the first short to be
+     *         written; must be non-negative and no larger than
+     *         <tt>dst.length</tt>
+     *
+     * @param  length
+     *         The maximum number of shorts to be written to the given
+     *         array; must be non-negative and no larger than
+     *         <tt>dst.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> shorts
+     *          remaining in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     */
+    public ShortBuffer get(short[] dst, int offset, int length) {
+        checkBounds(offset, length, dst.length);
+        if (length > remaining())
+            throw new BufferUnderflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            dst[i] = get();
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>get</i> method.
+     *
+     * <p> This method transfers shorts from this buffer into the given
+     * destination array.  An invocation of this method of the form
+     * <tt>src.get(a)</tt> behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     src.get(a, 0, a.length) </pre>
+     *
+     * @param   dst
+     *          The destination array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferUnderflowException
+     *          If there are fewer than <tt>length</tt> shorts
+     *          remaining in this buffer
+     */
+    public ShortBuffer get(short[] dst) {
+        return get(dst, 0, dst.length);
+    }
+
+
+    // -- Bulk put operations --
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the shorts remaining in the given source
+     * buffer into this buffer.  If there are more shorts remaining in the
+     * source buffer than in this buffer, that is, if
+     * <tt>src.remaining()</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>,
+     * then no shorts are transferred and a {@link
+     * BufferOverflowException} is thrown.
+     *
+     * <p> Otherwise, this method copies
+     * <i>n</i>&nbsp;=&nbsp;<tt>src.remaining()</tt> shorts from the given
+     * buffer into this buffer, starting at each buffer's current position.
+     * The positions of both buffers are then incremented by <i>n</i>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src)</tt> has exactly the same effect as the loop
+     *
+     * <pre>
+     *     while (src.hasRemaining())
+     *         dst.put(src.get()); </pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The source buffer from which shorts are to be read;
+     *         must not be this buffer
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *          for the remaining shorts in the source buffer
+     *
+     * @throws  IllegalArgumentException
+     *          If the source buffer is this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public ShortBuffer put(ShortBuffer src) {
+        if (src == this)
+            throw new IllegalArgumentException();
+        if (isReadOnly())
+            throw new ReadOnlyBufferException();
+        int n = src.remaining();
+        if (n > remaining())
+            throw new BufferOverflowException();
+        for (int i = 0; i < n; i++)
+            put(src.get());
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers shorts into this buffer from the given
+     * source array.  If there are more shorts to be copied from the array
+     * than remain in this buffer, that is, if
+     * <tt>length</tt>&nbsp;<tt>&gt;</tt>&nbsp;<tt>remaining()</tt>, then no
+     * shorts are transferred and a {@link BufferOverflowException} is
+     * thrown.
+     *
+     * <p> Otherwise, this method copies <tt>length</tt> shorts from the
+     * given array into this buffer, starting at the given offset in the array
+     * and at the current position of this buffer.  The position of this buffer
+     * is then incremented by <tt>length</tt>.
+     *
+     * <p> In other words, an invocation of this method of the form
+     * <tt>dst.put(src,&nbsp;off,&nbsp;len)</tt> has exactly the same effect as
+     * the loop
+     *
+     * <pre>{@code
+     *     for (int i = off; i < off + len; i++)
+     *         dst.put(a[i]);
+     * }</pre>
+     *
+     * except that it first checks that there is sufficient space in this
+     * buffer and it is potentially much more efficient.
+     *
+     * @param  src
+     *         The array from which shorts are to be read
+     *
+     * @param  offset
+     *         The offset within the array of the first short to be read;
+     *         must be non-negative and no larger than <tt>array.length</tt>
+     *
+     * @param  length
+     *         The number of shorts to be read from the given array;
+     *         must be non-negative and no larger than
+     *         <tt>array.length - offset</tt>
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public ShortBuffer put(short[] src, int offset, int length) {
+        checkBounds(offset, length, src.length);
+        if (length > remaining())
+            throw new BufferOverflowException();
+        int end = offset + length;
+        for (int i = offset; i < end; i++)
+            this.put(src[i]);
+        return this;
+    }
+
+    /**
+     * Relative bulk <i>put</i> method&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> This method transfers the entire content of the given source
+     * short array into this buffer.  An invocation of this method of the
+     * form <tt>dst.put(a)</tt> behaves in exactly the same way as the
+     * invocation
+     *
+     * <pre>
+     *     dst.put(a, 0, a.length) </pre>
+     *
+     * @param   src
+     *          The source array
+     *
+     * @return  This buffer
+     *
+     * @throws  BufferOverflowException
+     *          If there is insufficient space in this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public final ShortBuffer put(short[] src) {
+        return put(src, 0, src.length);
+    }
+
+
+    // -- Other stuff --
+
+    /**
+     * Tells whether or not this buffer is backed by an accessible short
+     * array.
+     *
+     * <p> If this method returns <tt>true</tt> then the {@link #array() array}
+     * and {@link #arrayOffset() arrayOffset} methods may safely be invoked.
+     * </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer
+     *          is backed by an array and is not read-only
+     */
+    public final boolean hasArray() {
+        return (hb != null) && !isReadOnly;
+    }
+
+    /**
+     * Returns the short array that backs this
+     * buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> Modifications to this buffer's content will cause the returned
+     * array's content to be modified, and vice versa.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The array that backs this buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final short[] array() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return hb;
+    }
+
+    /**
+     * Returns the offset within this buffer's backing array of the first
+     * element of the buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> If this buffer is backed by an array then buffer position <i>p</i>
+     * corresponds to array index <i>p</i>&nbsp;+&nbsp;<tt>arrayOffset()</tt>.
+     *
+     * <p> Invoke the {@link #hasArray hasArray} method before invoking this
+     * method in order to ensure that this buffer has an accessible backing
+     * array.  </p>
+     *
+     * @return  The offset within this buffer's array
+     *          of the first element of the buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is backed by an array but is read-only
+     *
+     * @throws  UnsupportedOperationException
+     *          If this buffer is not backed by an accessible array
+     */
+    public final int arrayOffset() {
+        if (hb == null)
+            throw new UnsupportedOperationException();
+        if (isReadOnly)
+            throw new ReadOnlyBufferException();
+        return offset;
+    }
+
+    // BEGIN Android-added: covariant overloads of *Buffer methods that return this.
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer position(int newPosition) {
+        return super.position(newPosition);
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer limit(int newLimit) {
+        return super.limit(newLimit);
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer mark() {
+        return super.mark();
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer reset() {
+        return super.reset();
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer clear() {
+        return super.clear();
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer flip() {
+        return super.flip();
+    }
+
+    @CovariantReturnType(returnType = ShortBuffer.class, presentAfter = 28)
+    @Override
+    public Buffer rewind() {
+        return super.rewind();
+    }
+    // END Android-added: covariant overloads of *Buffer methods that return this.
+
+    /**
+     * Compacts this buffer&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> The shorts between the buffer's current position and its limit,
+     * if any, are copied to the beginning of the buffer.  That is, the
+     * short at index <i>p</i>&nbsp;=&nbsp;<tt>position()</tt> is copied
+     * to index zero, the short at index <i>p</i>&nbsp;+&nbsp;1 is copied
+     * to index one, and so forth until the short at index
+     * <tt>limit()</tt>&nbsp;-&nbsp;1 is copied to index
+     * <i>n</i>&nbsp;=&nbsp;<tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>&nbsp;-&nbsp;<i>p</i>.
+     * The buffer's position is then set to <i>n+1</i> and its limit is set to
+     * its capacity.  The mark, if defined, is discarded.
+     *
+     * <p> The buffer's position is set to the number of shorts copied,
+     * rather than to zero, so that an invocation of this method can be
+     * followed immediately by an invocation of another relative <i>put</i>
+     * method. </p>
+     *
+
+     *
+     * @return  This buffer
+     *
+     * @throws  ReadOnlyBufferException
+     *          If this buffer is read-only
+     */
+    public abstract ShortBuffer compact();
+
+    /**
+     * Tells whether or not this short buffer is direct.
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is direct
+     */
+    public abstract boolean isDirect();
+
+
+    /**
+     * Returns a string summarizing the state of this buffer.
+     *
+     * @return  A summary string
+     */
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getClass().getName());
+        sb.append("[pos=");
+        sb.append(position());
+        sb.append(" lim=");
+        sb.append(limit());
+        sb.append(" cap=");
+        sb.append(capacity());
+        sb.append("]");
+        return sb.toString();
+    }
+
+
+    /**
+     * Returns the current hash code of this buffer.
+     *
+     * <p> The hash code of a short buffer depends only upon its remaining
+     * elements; that is, upon the elements from <tt>position()</tt> up to, and
+     * including, the element at <tt>limit()</tt>&nbsp;-&nbsp;<tt>1</tt>.
+     *
+     * <p> Because buffer hash codes are content-dependent, it is inadvisable
+     * to use buffers as keys in hash maps or similar data structures unless it
+     * is known that their contents will not change.  </p>
+     *
+     * @return  The current hash code of this buffer
+     */
+    public int hashCode() {
+        int h = 1;
+        int p = position();
+        for (int i = limit() - 1; i >= p; i--)
+            h = 31 * h + (int) get(i);
+        return h;
+    }
+
+    /**
+     * Tells whether or not this buffer is equal to another object.
+     *
+     * <p> Two short buffers are equal if, and only if,
+     *
+     * <ol>
+     *
+     *   <li><p> They have the same element type,  </p></li>
+     *
+     *   <li><p> They have the same number of remaining elements, and
+     *   </p></li>
+     *
+     *   <li><p> The two sequences of remaining elements, considered
+     *   independently of their starting positions, are pointwise equal.
+
+     *   </p></li>
+     *
+     * </ol>
+     *
+     * <p> A short buffer is not equal to any other type of object.  </p>
+     *
+     * @param  ob  The object to which this buffer is to be compared
+     *
+     * @return  <tt>true</tt> if, and only if, this buffer is equal to the
+     *           given object
+     */
+    public boolean equals(Object ob) {
+        if (this == ob)
+            return true;
+        if (!(ob instanceof ShortBuffer))
+            return false;
+        ShortBuffer that = (ShortBuffer)ob;
+        if (this.remaining() != that.remaining())
+            return false;
+        int p = this.position();
+        for (int i = this.limit() - 1, j = that.limit() - 1; i >= p; i--, j--)
+            if (!equals(this.get(i), that.get(j)))
+                return false;
+        return true;
+    }
+
+    private static boolean equals(short x, short y) {
+
+
+        return x == y;
+
+    }
+
+    /**
+     * Compares this buffer to another.
+     *
+     * <p> Two short buffers are compared by comparing their sequences of
+     * remaining elements lexicographically, without regard to the starting
+     * position of each sequence within its corresponding buffer.
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     *
+     * Pairs of {@code short} elements are compared as if by invoking
+     * {@link Short#compare(short,short)}.
+
+     *
+     * <p> A short buffer is not comparable to any other type of object.
+     *
+     * @return  A negative integer, zero, or a positive integer as this buffer
+     *          is less than, equal to, or greater than the given buffer
+     */
+    public int compareTo(ShortBuffer that) {
+        int n = this.position() + Math.min(this.remaining(), that.remaining());
+        for (int i = this.position(), j = that.position(); i < n; i++, j++) {
+            int cmp = compare(this.get(i), that.get(j));
+            if (cmp != 0)
+                return cmp;
+        }
+        return this.remaining() - that.remaining();
+    }
+
+    private static int compare(short x, short y) {
+
+
+        return Short.compare(x, y);
+
+    }
+
+    // -- Other char stuff --
+
+
+    // -- Other byte stuff: Access to binary data --
+
+
+    /**
+     * Retrieves this buffer's byte order.
+     *
+     * <p> The byte order of a short buffer created by allocation or by
+     * wrapping an existing <tt>short</tt> array is the {@link
+     * ByteOrder#nativeOrder native order} of the underlying
+     * hardware.  The byte order of a short buffer created as a <a
+     * href="ByteBuffer.html#views">view</a> of a byte buffer is that of the
+     * byte buffer at the moment that the view is created.  </p>
+     *
+     * @return  This buffer's byte order
+     */
+    public abstract ByteOrder order();
+
+
+}
diff --git a/java/nio/StringCharBuffer.java b/java/nio/StringCharBuffer.java
new file mode 100644
index 0000000..0c20fa6
--- /dev/null
+++ b/java/nio/StringCharBuffer.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio;
+
+
+// ## If the sequence is a string, use reflection to share its array
+
+class StringCharBuffer                                  // package-private
+    extends CharBuffer
+{
+    CharSequence str;
+
+    StringCharBuffer(CharSequence s, int start, int end) { // package-private
+        super(-1, start, end, s.length());
+        int n = s.length();
+        if ((start < 0) || (start > n) || (end < start) || (end > n))
+            throw new IndexOutOfBoundsException();
+        str = s;
+    }
+
+    public CharBuffer slice() {
+        return new StringCharBuffer(str,
+                                    -1,
+                                    0,
+                                    this.remaining(),
+                                    this.remaining(),
+                                    offset + this.position());
+    }
+
+    private StringCharBuffer(CharSequence s,
+                             int mark,
+                             int pos,
+                             int limit,
+                             int cap,
+                             int offset) {
+        super(mark, pos, limit, cap, null, offset);
+        str = s;
+    }
+
+    public CharBuffer duplicate() {
+        return new StringCharBuffer(str, markValue(),
+                                    position(), limit(), capacity(), offset);
+    }
+
+    public CharBuffer asReadOnlyBuffer() {
+        return duplicate();
+    }
+
+    public final char get() {
+        return str.charAt(nextGetIndex() + offset);
+    }
+
+    public final char get(int index) {
+        return str.charAt(checkIndex(index) + offset);
+    }
+
+    char getUnchecked(int index) {
+        return str.charAt(index + offset);
+    }
+
+    // ## Override bulk get methods for better performance
+
+    public final CharBuffer put(char c) {
+        throw new ReadOnlyBufferException();
+    }
+
+    public final CharBuffer put(int index, char c) {
+        throw new ReadOnlyBufferException();
+    }
+
+    public final CharBuffer compact() {
+        throw new ReadOnlyBufferException();
+    }
+
+    public final boolean isReadOnly() {
+        return true;
+    }
+
+    final String toString(int start, int end) {
+        return str.toString().substring(start + offset, end + offset);
+    }
+
+    public final CharBuffer subSequence(int start, int end) {
+        try {
+            int pos = position();
+            return new StringCharBuffer(str,
+                                        -1,
+                                        pos + checkIndex(start, pos),
+                                        pos + checkIndex(end, pos),
+                                        capacity(),
+                                        offset);
+        } catch (IllegalArgumentException x) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    public boolean isDirect() {
+        return false;
+    }
+
+    public ByteOrder order() {
+        return ByteOrder.nativeOrder();
+    }
+
+}
diff --git a/java/nio/channels/AcceptPendingException.java b/java/nio/channels/AcceptPendingException.java
new file mode 100644
index 0000000..dc357f0
--- /dev/null
+++ b/java/nio/channels/AcceptPendingException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to initiate an accept
+ * operation on a channel and a previous accept operation has not completed.
+ *
+ * @since 1.7
+ */
+
+public class AcceptPendingException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = 2721339977965416421L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public AcceptPendingException() { }
+
+}
diff --git a/java/nio/channels/AlreadyBoundException.java b/java/nio/channels/AlreadyBoundException.java
new file mode 100644
index 0000000..38d1033
--- /dev/null
+++ b/java/nio/channels/AlreadyBoundException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to bind the socket a
+ * network oriented channel that is already bound.
+ *
+ * @since 1.7
+ */
+
+public class AlreadyBoundException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = 6796072983322737592L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public AlreadyBoundException() { }
+
+}
diff --git a/java/nio/channels/AlreadyConnectedException.java b/java/nio/channels/AlreadyConnectedException.java
new file mode 100644
index 0000000..931efff
--- /dev/null
+++ b/java/nio/channels/AlreadyConnectedException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to connect a {@link
+ * SocketChannel} that is already connected.
+ *
+ * @since 1.4
+ */
+
+public class AlreadyConnectedException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = -7331895245053773357L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public AlreadyConnectedException() { }
+
+}
diff --git a/java/nio/channels/AsynchronousByteChannel.java b/java/nio/channels/AsynchronousByteChannel.java
new file mode 100644
index 0000000..b96a239
--- /dev/null
+++ b/java/nio/channels/AsynchronousByteChannel.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2007, 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.nio.channels;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.Future;
+
+/**
+ * An asynchronous channel that can read and write bytes.
+ *
+ * <p> Some channels may not allow more than one read or write to be outstanding
+ * at any given time. If a thread invokes a read method before a previous read
+ * operation has completed then a {@link ReadPendingException} will be thrown.
+ * Similarly, if a write method is invoked before a previous write has completed
+ * then {@link WritePendingException} is thrown. Whether or not other kinds of
+ * I/O operations may proceed concurrently with a read operation depends upon
+ * the type of the channel.
+ *
+ * <p> Note that {@link java.nio.ByteBuffer ByteBuffers} are not safe for use by
+ * multiple concurrent threads. When a read or write operation is initiated then
+ * care must be taken to ensure that the buffer is not accessed until the
+ * operation completes.
+ *
+ * @see Channels#newInputStream(AsynchronousByteChannel)
+ * @see Channels#newOutputStream(AsynchronousByteChannel)
+ *
+ * @since 1.7
+ */
+
+public interface AsynchronousByteChannel
+    extends AsynchronousChannel
+{
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * <p> This method initiates an asynchronous read operation to read a
+     * sequence of bytes from this channel into the given buffer. The {@code
+     * handler} parameter is a completion handler that is invoked when the read
+     * operation completes (or fails). The result passed to the completion
+     * handler is the number of bytes read or {@code -1} if no bytes could be
+     * read because the channel has reached end-of-stream.
+     *
+     * <p> The read operation may read up to <i>r</i> bytes from the channel,
+     * where <i>r</i> is the number of bytes remaining in the buffer, that is,
+     * {@code dst.remaining()} at the time that the read is attempted. Where
+     * <i>r</i> is 0, the read operation completes immediately with a result of
+     * {@code 0} without initiating an I/O operation.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is read, where
+     * <tt>0</tt>&nbsp;<tt>&lt;</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * This byte sequence will be transferred into the buffer so that the first
+     * byte in the sequence is at index <i>p</i> and the last byte is at index
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>&nbsp;<tt>-</tt>&nbsp;<tt>1</tt>,
+     * where <i>p</i> is the buffer's position at the moment the read is
+     * performed. Upon completion the buffer's position will be equal to
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>; its limit will not have changed.
+     *
+     * <p> Buffers are not safe for use by multiple concurrent threads so care
+     * should be taken to not access the buffer until the operation has
+     * completed.
+     *
+     * <p> This method may be invoked at any time. Some channel types may not
+     * allow more than one read to be outstanding at any given time. If a thread
+     * initiates a read operation before a previous read operation has
+     * completed then a {@link ReadPendingException} will be thrown.
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   dst
+     *          The buffer into which bytes are to be transferred
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The completion handler
+     *
+     * @throws  IllegalArgumentException
+     *          If the buffer is read-only
+     * @throws  ReadPendingException
+     *          If the channel does not allow more than one read to be outstanding
+     *          and a previous read has not completed
+     * @throws  ShutdownChannelGroupException
+     *          If the channel is associated with a {@link AsynchronousChannelGroup
+     *          group} that has terminated
+     */
+    <A> void read(ByteBuffer dst,
+                  A attachment,
+                  CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * <p> This method initiates an asynchronous read operation to read a
+     * sequence of bytes from this channel into the given buffer. The method
+     * behaves in exactly the same manner as the {@link
+     * #read(ByteBuffer,Object,CompletionHandler)
+     * read(ByteBuffer,Object,CompletionHandler)} method except that instead
+     * of specifying a completion handler, this method returns a {@code Future}
+     * representing the pending result. The {@code Future}'s {@link Future#get()
+     * get} method returns the number of bytes read or {@code -1} if no bytes
+     * could be read because the channel has reached end-of-stream.
+     *
+     * @param   dst
+     *          The buffer into which bytes are to be transferred
+     *
+     * @return  A Future representing the result of the operation
+     *
+     * @throws  IllegalArgumentException
+     *          If the buffer is read-only
+     * @throws  ReadPendingException
+     *          If the channel does not allow more than one read to be outstanding
+     *          and a previous read has not completed
+     */
+    Future<Integer> read(ByteBuffer dst);
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * <p> This method initiates an asynchronous write operation to write a
+     * sequence of bytes to this channel from the given buffer. The {@code
+     * handler} parameter is a completion handler that is invoked when the write
+     * operation completes (or fails). The result passed to the completion
+     * handler is the number of bytes written.
+     *
+     * <p> The write operation may write up to <i>r</i> bytes to the channel,
+     * where <i>r</i> is the number of bytes remaining in the buffer, that is,
+     * {@code src.remaining()} at the time that the write is attempted. Where
+     * <i>r</i> is 0, the write operation completes immediately with a result of
+     * {@code 0} without initiating an I/O operation.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is written, where
+     * <tt>0</tt>&nbsp;<tt>&lt;</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * This byte sequence will be transferred from the buffer starting at index
+     * <i>p</i>, where <i>p</i> is the buffer's position at the moment the
+     * write is performed; the index of the last byte written will be
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>&nbsp;<tt>-</tt>&nbsp;<tt>1</tt>.
+     * Upon completion the buffer's position will be equal to
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>; its limit will not have changed.
+     *
+     * <p> Buffers are not safe for use by multiple concurrent threads so care
+     * should be taken to not access the buffer until the operation has
+     * completed.
+     *
+     * <p> This method may be invoked at any time. Some channel types may not
+     * allow more than one write to be outstanding at any given time. If a thread
+     * initiates a write operation before a previous write operation has
+     * completed then a {@link WritePendingException} will be thrown.
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   src
+     *          The buffer from which bytes are to be retrieved
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The completion handler object
+     *
+     * @throws  WritePendingException
+     *          If the channel does not allow more than one write to be outstanding
+     *          and a previous write has not completed
+     * @throws  ShutdownChannelGroupException
+     *          If the channel is associated with a {@link AsynchronousChannelGroup
+     *          group} that has terminated
+     */
+    <A> void write(ByteBuffer src,
+                   A attachment,
+                   CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * <p> This method initiates an asynchronous write operation to write a
+     * sequence of bytes to this channel from the given buffer. The method
+     * behaves in exactly the same manner as the {@link
+     * #write(ByteBuffer,Object,CompletionHandler)
+     * write(ByteBuffer,Object,CompletionHandler)} method except that instead
+     * of specifying a completion handler, this method returns a {@code Future}
+     * representing the pending result. The {@code Future}'s {@link Future#get()
+     * get} method returns the number of bytes written.
+     *
+     * @param   src
+     *          The buffer from which bytes are to be retrieved
+     *
+     * @return A Future representing the result of the operation
+     *
+     * @throws  WritePendingException
+     *          If the channel does not allow more than one write to be outstanding
+     *          and a previous write has not completed
+     */
+    Future<Integer> write(ByteBuffer src);
+}
diff --git a/java/nio/channels/AsynchronousChannel.java b/java/nio/channels/AsynchronousChannel.java
new file mode 100644
index 0000000..4668d09
--- /dev/null
+++ b/java/nio/channels/AsynchronousChannel.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2007, 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.nio.channels;
+
+import java.io.IOException;
+import java.util.concurrent.Future;  // javadoc
+
+/**
+ * A channel that supports asynchronous I/O operations. Asynchronous I/O
+ * operations will usually take one of two forms:
+ *
+ * <ol>
+ * <li><pre>{@link Future}&lt;V&gt; <em>operation</em>(<em>...</em>)</pre></li>
+ * <li><pre>void <em>operation</em>(<em>...</em> A attachment, {@link
+ *   CompletionHandler}&lt;V,? super A&gt; handler)</pre></li>
+ * </ol>
+ *
+ * where <i>operation</i> is the name of the I/O operation (read or write for
+ * example), <i>V</i> is the result type of the I/O operation, and <i>A</i> is
+ * the type of an object attached to the I/O operation to provide context when
+ * consuming the result. The attachment is important for cases where a
+ * <em>state-less</em> {@code CompletionHandler} is used to consume the result
+ * of many I/O operations.
+ *
+ * <p> In the first form, the methods defined by the {@link Future Future}
+ * interface may be used to check if the operation has completed, wait for its
+ * completion, and to retrieve the result. In the second form, a {@link
+ * CompletionHandler} is invoked to consume the result of the I/O operation when
+ * it completes or fails.
+ *
+ * <p> A channel that implements this interface is <em>asynchronously
+ * closeable</em>: If an I/O operation is outstanding on the channel and the
+ * channel's {@link #close close} method is invoked, then the I/O operation
+ * fails with the exception {@link AsynchronousCloseException}.
+ *
+ * <p> Asynchronous channels are safe for use by multiple concurrent threads.
+ * Some channel implementations may support concurrent reading and writing, but
+ * may not allow more than one read and one write operation to be outstanding at
+ * any given time.
+ *
+ * <h2>Cancellation</h2>
+ *
+ * <p> The {@code Future} interface defines the {@link Future#cancel cancel}
+ * method to cancel execution. This causes all threads waiting on the result of
+ * the I/O operation to throw {@link java.util.concurrent.CancellationException}.
+ * Whether the underlying I/O operation can be cancelled is highly implementation
+ * specific and therefore not specified. Where cancellation leaves the channel,
+ * or the entity to which it is connected, in an inconsistent state, then the
+ * channel is put into an implementation specific <em>error state</em> that
+ * prevents further attempts to initiate I/O operations that are <i>similar</i>
+ * to the operation that was cancelled. For example, if a read operation is
+ * cancelled but the implementation cannot guarantee that bytes have not been
+ * read from the channel then it puts the channel into an error state; further
+ * attempts to initiate a {@code read} operation cause an unspecified runtime
+ * exception to be thrown. Similarly, if a write operation is cancelled but the
+ * implementation cannot guarantee that bytes have not been written to the
+ * channel then subsequent attempts to initiate a {@code write} will fail with
+ * an unspecified runtime exception.
+ *
+ * <p> Where the {@link Future#cancel cancel} method is invoked with the {@code
+ * mayInterruptIfRunning} parameter set to {@code true} then the I/O operation
+ * may be interrupted by closing the channel. In that case all threads waiting
+ * on the result of the I/O operation throw {@code CancellationException} and
+ * any other I/O operations outstanding on the channel complete with the
+ * exception {@link AsynchronousCloseException}.
+ *
+ * <p> Where the {@code cancel} method is invoked to cancel read or write
+ * operations then it is recommended that all buffers used in the I/O operations
+ * be discarded or care taken to ensure that the buffers are not accessed while
+ * the channel remains open.
+ *
+ *  @since 1.7
+ */
+
+public interface AsynchronousChannel
+    extends Channel
+{
+    /**
+     * Closes this channel.
+     *
+     * <p> Any outstanding asynchronous operations upon this channel will
+     * complete with the exception {@link AsynchronousCloseException}. After a
+     * channel is closed, further attempts to initiate asynchronous I/O
+     * operations complete immediately with cause {@link ClosedChannelException}.
+     *
+     * <p>  This method otherwise behaves exactly as specified by the {@link
+     * Channel} interface.
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    @Override
+    void close() throws IOException;
+}
diff --git a/java/nio/channels/AsynchronousChannelGroup.java b/java/nio/channels/AsynchronousChannelGroup.java
new file mode 100644
index 0000000..92b7e66
--- /dev/null
+++ b/java/nio/channels/AsynchronousChannelGroup.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 2007, 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.nio.channels;
+
+import java.nio.channels.spi.AsynchronousChannelProvider;
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A grouping of asynchronous channels for the purpose of resource sharing.
+ *
+ * <p> An asynchronous channel group encapsulates the mechanics required to
+ * handle the completion of I/O operations initiated by {@link AsynchronousChannel
+ * asynchronous channels} that are bound to the group. A group has an associated
+ * thread pool to which tasks are submitted to handle I/O events and dispatch to
+ * {@link CompletionHandler completion-handlers} that consume the result of
+ * asynchronous operations performed on channels in the group. In addition to
+ * handling I/O events, the pooled threads may also execute other tasks required
+ * to support the execution of asynchronous I/O operations.
+ *
+ * <p> An asynchronous channel group is created by invoking the {@link
+ * #withFixedThreadPool withFixedThreadPool} or {@link #withCachedThreadPool
+ * withCachedThreadPool} methods defined here. Channels are bound to a group by
+ * specifying the group when constructing the channel. The associated thread
+ * pool is <em>owned</em> by the group; termination of the group results in the
+ * shutdown of the associated thread pool.
+ *
+ * <p> In addition to groups created explicitly, the Java virtual machine
+ * maintains a system-wide <em>default group</em> that is constructed
+ * automatically. Asynchronous channels that do not specify a group at
+ * construction time are bound to the default group. The default group has an
+ * associated thread pool that creates new threads as needed. The default group
+ * may be configured by means of system properties defined in the table below.
+ * Where the {@link java.util.concurrent.ThreadFactory ThreadFactory} for the
+ * default group is not configured then the pooled threads of the default group
+ * are {@link Thread#isDaemon daemon} threads.
+ *
+ * <table border summary="System properties">
+ *   <tr>
+ *     <th>System property</th>
+ *     <th>Description</th>
+ *   </tr>
+ *   <tr>
+ *     <td> {@code java.nio.channels.DefaultThreadPool.threadFactory} </td>
+ *     <td> The value of this property is taken to be the fully-qualified name
+ *     of a concrete {@link java.util.concurrent.ThreadFactory ThreadFactory}
+ *     class. The class is loaded using the system class loader and instantiated.
+ *     The factory's {@link java.util.concurrent.ThreadFactory#newThread
+ *     newThread} method is invoked to create each thread for the default
+ *     group's thread pool. If the process to load and instantiate the value
+ *     of the property fails then an unspecified error is thrown during the
+ *     construction of the default group. </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@code java.nio.channels.DefaultThreadPool.initialSize} </td>
+ *     <td> The value of the {@code initialSize} parameter for the default
+ *     group (see {@link #withCachedThreadPool withCachedThreadPool}).
+ *     The value of the property is taken to be the {@code String}
+ *     representation of an {@code Integer} that is the initial size parameter.
+ *     If the value cannot be parsed as an {@code Integer} it causes an
+ *     unspecified error to be thrown during the construction of the default
+ *     group. </td>
+ *   </tr>
+ * </table>
+ *
+ * <a name="threading"></a><h2>Threading</h2>
+ *
+ * <p> The completion handler for an I/O operation initiated on a channel bound
+ * to a group is guaranteed to be invoked by one of the pooled threads in the
+ * group. This ensures that the completion handler is run by a thread with the
+ * expected <em>identity</em>.
+ *
+ * <p> Where an I/O operation completes immediately, and the initiating thread
+ * is one of the pooled threads in the group then the completion handler may
+ * be invoked directly by the initiating thread. To avoid stack overflow, an
+ * implementation may impose a limit as to the number of activations on the
+ * thread stack. Some I/O operations may prohibit invoking the completion
+ * handler directly by the initiating thread (see {@link
+ * AsynchronousServerSocketChannel#accept(Object,CompletionHandler) accept}).
+ *
+ * <a name="shutdown"></a><h2>Shutdown and Termination</h2>
+ *
+ * <p> The {@link #shutdown() shutdown} method is used to initiate an <em>orderly
+ * shutdown</em> of a group. An orderly shutdown marks the group as shutdown;
+ * further attempts to construct a channel that binds to the group will throw
+ * {@link ShutdownChannelGroupException}. Whether or not a group is shutdown can
+ * be tested using the {@link #isShutdown() isShutdown} method. Once shutdown,
+ * the group <em>terminates</em> when all asynchronous channels that are bound to
+ * the group are closed, all actively executing completion handlers have run to
+ * completion, and resources used by the group are released. No attempt is made
+ * to stop or interrupt threads that are executing completion handlers. The
+ * {@link #isTerminated() isTerminated} method is used to test if the group has
+ * terminated, and the {@link #awaitTermination awaitTermination} method can be
+ * used to block until the group has terminated.
+ *
+ * <p> The {@link #shutdownNow() shutdownNow} method can be used to initiate a
+ * <em>forceful shutdown</em> of the group. In addition to the actions performed
+ * by an orderly shutdown, the {@code shutdownNow} method closes all open channels
+ * in the group as if by invoking the {@link AsynchronousChannel#close close}
+ * method.
+ *
+ * @since 1.7
+ *
+ * @see AsynchronousSocketChannel#open(AsynchronousChannelGroup)
+ * @see AsynchronousServerSocketChannel#open(AsynchronousChannelGroup)
+ */
+
+public abstract class AsynchronousChannelGroup {
+    private final AsynchronousChannelProvider provider;
+
+    /**
+     * Initialize a new instance of this class.
+     *
+     * @param   provider
+     *          The asynchronous channel provider for this group
+     */
+    protected AsynchronousChannelGroup(AsynchronousChannelProvider provider) {
+        this.provider = provider;
+    }
+
+    /**
+     * Returns the provider that created this channel group.
+     *
+     * @return  The provider that created this channel group
+     */
+    public final AsynchronousChannelProvider provider() {
+        return provider;
+    }
+
+    /**
+     * Creates an asynchronous channel group with a fixed thread pool.
+     *
+     * <p> The resulting asynchronous channel group reuses a fixed number of
+     * threads. At any point, at most {@code nThreads} threads will be active
+     * processing tasks that are submitted to handle I/O events and dispatch
+     * completion results for operations initiated on asynchronous channels in
+     * the group.
+     *
+     * <p> The group is created by invoking the {@link
+     * AsynchronousChannelProvider#openAsynchronousChannelGroup(int,ThreadFactory)
+     * openAsynchronousChannelGroup(int,ThreadFactory)} method of the system-wide
+     * default {@link AsynchronousChannelProvider} object.
+     *
+     * @param   nThreads
+     *          The number of threads in the pool
+     * @param   threadFactory
+     *          The factory to use when creating new threads
+     *
+     * @return  A new asynchronous channel group
+     *
+     * @throws  IllegalArgumentException
+     *          If {@code nThreads <= 0}
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousChannelGroup withFixedThreadPool(int nThreads,
+                                                               ThreadFactory threadFactory)
+        throws IOException
+    {
+        return AsynchronousChannelProvider.provider()
+            .openAsynchronousChannelGroup(nThreads, threadFactory);
+    }
+
+    /**
+     * Creates an asynchronous channel group with a given thread pool that
+     * creates new threads as needed.
+     *
+     * <p> The {@code executor} parameter is an {@code ExecutorService} that
+     * creates new threads as needed to execute tasks that are submitted to
+     * handle I/O events and dispatch completion results for operations initiated
+     * on asynchronous channels in the group. It may reuse previously constructed
+     * threads when they are available.
+     *
+     * <p> The {@code initialSize} parameter may be used by the implementation
+     * as a <em>hint</em> as to the initial number of tasks it may submit. For
+     * example, it may be used to indicate the initial number of threads that
+     * wait on I/O events.
+     *
+     * <p> The executor is intended to be used exclusively by the resulting
+     * asynchronous channel group. Termination of the group results in the
+     * orderly  {@link ExecutorService#shutdown shutdown} of the executor
+     * service. Shutting down the executor service by other means results in
+     * unspecified behavior.
+     *
+     * <p> The group is created by invoking the {@link
+     * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int)
+     * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide
+     * default {@link AsynchronousChannelProvider} object.
+     *
+     * @param   executor
+     *          The thread pool for the resulting group
+     * @param   initialSize
+     *          A value {@code >=0} or a negative value for implementation
+     *          specific default
+     *
+     * @return  A new asynchronous channel group
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @see java.util.concurrent.Executors#newCachedThreadPool
+     */
+    public static AsynchronousChannelGroup withCachedThreadPool(ExecutorService executor,
+                                                                int initialSize)
+        throws IOException
+    {
+        return AsynchronousChannelProvider.provider()
+            .openAsynchronousChannelGroup(executor, initialSize);
+    }
+
+    /**
+     * Creates an asynchronous channel group with a given thread pool.
+     *
+     * <p> The {@code executor} parameter is an {@code ExecutorService} that
+     * executes tasks submitted to dispatch completion results for operations
+     * initiated on asynchronous channels in the group.
+     *
+     * <p> Care should be taken when configuring the executor service. It
+     * should support <em>direct handoff</em> or <em>unbounded queuing</em> of
+     * submitted tasks, and the thread that invokes the {@link
+     * ExecutorService#execute execute} method should never invoke the task
+     * directly. An implementation may mandate additional constraints.
+     *
+     * <p> The executor is intended to be used exclusively by the resulting
+     * asynchronous channel group. Termination of the group results in the
+     * orderly  {@link ExecutorService#shutdown shutdown} of the executor
+     * service. Shutting down the executor service by other means results in
+     * unspecified behavior.
+     *
+     * <p> The group is created by invoking the {@link
+     * AsynchronousChannelProvider#openAsynchronousChannelGroup(ExecutorService,int)
+     * openAsynchronousChannelGroup(ExecutorService,int)} method of the system-wide
+     * default {@link AsynchronousChannelProvider} object with an {@code
+     * initialSize} of {@code 0}.
+     *
+     * @param   executor
+     *          The thread pool for the resulting group
+     *
+     * @return  A new asynchronous channel group
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousChannelGroup withThreadPool(ExecutorService executor)
+        throws IOException
+    {
+        return AsynchronousChannelProvider.provider()
+            .openAsynchronousChannelGroup(executor, 0);
+    }
+
+    /**
+     * Tells whether or not this asynchronous channel group is shutdown.
+     *
+     * @return  {@code true} if this asynchronous channel group is shutdown or
+     *          has been marked for shutdown.
+     */
+    public abstract boolean isShutdown();
+
+    /**
+     * Tells whether or not this group has terminated.
+     *
+     * <p> Where this method returns {@code true}, then the associated thread
+     * pool has also {@link ExecutorService#isTerminated terminated}.
+     *
+     * @return  {@code true} if this group has terminated
+     */
+    public abstract boolean isTerminated();
+
+    /**
+     * Initiates an orderly shutdown of the group.
+     *
+     * <p> This method marks the group as shutdown. Further attempts to construct
+     * channel that binds to this group will throw {@link ShutdownChannelGroupException}.
+     * The group terminates when all asynchronous channels in the group are
+     * closed, all actively executing completion handlers have run to completion,
+     * and all resources have been released. This method has no effect if the
+     * group is already shutdown.
+     */
+    public abstract void shutdown();
+
+    /**
+     * Shuts down the group and closes all open channels in the group.
+     *
+     * <p> In addition to the actions performed by the {@link #shutdown() shutdown}
+     * method, this method invokes the {@link AsynchronousChannel#close close}
+     * method on all open channels in the group. This method does not attempt to
+     * stop or interrupt threads that are executing completion handlers. The
+     * group terminates when all actively executing completion handlers have run
+     * to completion and all resources have been released. This method may be
+     * invoked at any time. If some other thread has already invoked it, then
+     * another invocation will block until the first invocation is complete,
+     * after which it will return without effect.
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract void shutdownNow() throws IOException;
+
+    /**
+     * Awaits termination of the group.
+
+     * <p> This method blocks until the group has terminated, or the timeout
+     * occurs, or the current thread is interrupted, whichever happens first.
+     *
+     * @param   timeout
+     *          The maximum time to wait, or zero or less to not wait
+     * @param   unit
+     *          The time unit of the timeout argument
+     *
+     * @return  {@code true} if the group has terminated; {@code false} if the
+     *          timeout elapsed before termination
+     *
+     * @throws  InterruptedException
+     *          If interrupted while waiting
+     */
+    public abstract boolean awaitTermination(long timeout, TimeUnit unit)
+        throws InterruptedException;
+}
diff --git a/java/nio/channels/AsynchronousCloseException.java b/java/nio/channels/AsynchronousCloseException.java
new file mode 100644
index 0000000..6fb5e57
--- /dev/null
+++ b/java/nio/channels/AsynchronousCloseException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Checked exception received by a thread when another thread closes the
+ * channel or the part of the channel upon which it is blocked in an I/O
+ * operation.
+ *
+ * @since 1.4
+ */
+
+public class AsynchronousCloseException
+    extends ClosedChannelException
+{
+
+    private static final long serialVersionUID = 6891178312432313966L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public AsynchronousCloseException() { }
+
+}
diff --git a/java/nio/channels/AsynchronousFileChannel.java b/java/nio/channels/AsynchronousFileChannel.java
new file mode 100644
index 0000000..b985d77
--- /dev/null
+++ b/java/nio/channels/AsynchronousFileChannel.java
@@ -0,0 +1,779 @@
+/*
+ * Copyright (c) 2007, 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.nio.channels;
+
+import java.nio.file.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.spi.*;
+import java.nio.ByteBuffer;
+import java.io.IOException;
+import java.util.concurrent.Future;
+import java.util.concurrent.ExecutorService;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+
+/**
+ * An asynchronous channel for reading, writing, and manipulating a file.
+ *
+ * <p> An asynchronous file channel is created when a file is opened by invoking
+ * one of the {@link #open open} methods defined by this class. The file contains
+ * a variable-length sequence of bytes that can be read and written and whose
+ * current size can be {@link #size() queried}. The size of the file increases
+ * when bytes are written beyond its  current size; the size of the file decreases
+ * when it is {@link #truncate truncated}.
+ *
+ * <p> An asynchronous file channel does not have a <i>current position</i>
+ * within the file. Instead, the file position is specified to each read and
+ * write method that initiates asynchronous operations. A {@link CompletionHandler}
+ * is specified as a parameter and is invoked to consume the result of the I/O
+ * operation. This class also defines read and write methods that initiate
+ * asynchronous operations, returning a {@link Future} to represent the pending
+ * result of the operation. The {@code Future} may be used to check if the
+ * operation has completed, wait for its completion, and retrieve the result.
+ *
+ * <p> In addition to read and write operations, this class defines the
+ * following operations: </p>
+ *
+ * <ul>
+ *
+ *   <li><p> Updates made to a file may be {@link #force <i>forced
+ *   out</i>} to the underlying storage device, ensuring that data are not
+ *   lost in the event of a system crash.  </p></li>
+ *
+ *   <li><p> A region of a file may be {@link #lock <i>locked</i>} against
+ *   access by other programs.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> An {@code AsynchronousFileChannel} is associated with a thread pool to
+ * which tasks are submitted to handle I/O events and dispatch to completion
+ * handlers that consume the results of I/O operations on the channel. The
+ * completion handler for an I/O operation initiated on a channel is guaranteed
+ * to be invoked by one of the threads in the thread pool (This ensures that the
+ * completion handler is run by a thread with the expected <em>identity</em>).
+ * Where an I/O operation completes immediately, and the initiating thread is
+ * itself a thread in the thread pool, then the completion handler may be invoked
+ * directly by the initiating thread. When an {@code AsynchronousFileChannel} is
+ * created without specifying a thread pool then the channel is associated with
+ * a system-dependent default thread pool that may be shared with other
+ * channels. The default thread pool is configured by the system properties
+ * defined by the {@link AsynchronousChannelGroup} class.
+ *
+ * <p> Channels of this type are safe for use by multiple concurrent threads. The
+ * {@link Channel#close close} method may be invoked at any time, as specified
+ * by the {@link Channel} interface. This causes all outstanding asynchronous
+ * operations on the channel to complete with the exception {@link
+ * AsynchronousCloseException}. Multiple read and write operations may be
+ * outstanding at the same time. When multiple read and write operations are
+ * outstanding then the ordering of the I/O operations, and the order that the
+ * completion handlers are invoked, is not specified; they are not, in particular,
+ * guaranteed to execute in the order that the operations were initiated. The
+ * {@link java.nio.ByteBuffer ByteBuffers} used when reading or writing are not
+ * safe for use by multiple concurrent I/O operations. Furthermore, after an I/O
+ * operation is initiated then care should be taken to ensure that the buffer is
+ * not accessed until after the operation has completed.
+ *
+ * <p> As with {@link FileChannel}, the view of a file provided by an instance of
+ * this class is guaranteed to be consistent with other views of the same file
+ * provided by other instances in the same program.  The view provided by an
+ * instance of this class may or may not, however, be consistent with the views
+ * seen by other concurrently-running programs due to caching performed by the
+ * underlying operating system and delays induced by network-filesystem protocols.
+ * This is true regardless of the language in which these other programs are
+ * written, and whether they are running on the same machine or on some other
+ * machine.  The exact nature of any such inconsistencies are system-dependent
+ * and are therefore unspecified.
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousFileChannel
+    implements AsynchronousChannel
+{
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected AsynchronousFileChannel() {
+    }
+
+    /**
+     * Opens or creates a file for reading and/or writing, returning an
+     * asynchronous file channel to access the file.
+     *
+     * <p> The {@code options} parameter determines how the file is opened.
+     * The {@link StandardOpenOption#READ READ} and {@link StandardOpenOption#WRITE
+     * WRITE} options determines if the file should be opened for reading and/or
+     * writing. If neither option is contained in the array then an existing file
+     * is opened for  reading.
+     *
+     * <p> In addition to {@code READ} and {@code WRITE}, the following options
+     * may be present:
+     *
+     * <table border=1 cellpadding=5 summary="">
+     * <tr> <th>Option</th> <th>Description</th> </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
+     *   <td> When opening an existing file, the file is first truncated to a
+     *   size of 0 bytes. This option is ignored when the file is opened only
+     *   for reading.</td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
+     *   <td> If this option is present then a new file is created, failing if
+     *   the file already exists. When creating a file the check for the
+     *   existence of the file and the creation of the file if it does not exist
+     *   is atomic with respect to other file system operations. This option is
+     *   ignored when the file is opened only for reading. </td>
+     * </tr>
+     * <tr>
+     *   <td > {@link StandardOpenOption#CREATE CREATE} </td>
+     *   <td> If this option is present then an existing file is opened if it
+     *   exists, otherwise a new file is created. When creating a file the check
+     *   for the existence of the file and the creation of the file if it does
+     *   not exist is atomic with respect to other file system operations. This
+     *   option is ignored if the {@code CREATE_NEW} option is also present or
+     *   the file is opened only for reading. </td>
+     * </tr>
+     * <tr>
+     *   <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
+     *   <td> When this option is present then the implementation makes a
+     *   <em>best effort</em> attempt to delete the file when closed by the
+     *   the {@link #close close} method. If the {@code close} method is not
+     *   invoked then a <em>best effort</em> attempt is made to delete the file
+     *   when the Java virtual machine terminates. </td>
+     * </tr>
+     * <tr>
+     *   <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
+     *   <td> When creating a new file this option is a <em>hint</em> that the
+     *   new file will be sparse. This option is ignored when not creating
+     *   a new file. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#SYNC SYNC} </td>
+     *   <td> Requires that every update to the file's content or metadata be
+     *   written synchronously to the underlying storage device. (see <a
+     *   href="../file/package-summary.html#integrity"> Synchronized I/O file
+     *   integrity</a>). </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
+     *   <td> Requires that every update to the file's content be written
+     *   synchronously to the underlying storage device. (see <a
+     *   href="../file/package-summary.html#integrity"> Synchronized I/O file
+     *   integrity</a>). </td>
+     * </tr>
+     * </table>
+     *
+     * <p> An implementation may also support additional options.
+     *
+     * <p> The {@code executor} parameter is the {@link ExecutorService} to
+     * which tasks are submitted to handle I/O events and dispatch completion
+     * results for operations initiated on resulting channel.
+     * The nature of these tasks is highly implementation specific and so care
+     * should be taken when configuring the {@code Executor}. Minimally it
+     * should support an unbounded work queue and should not run tasks on the
+     * caller thread of the {@link ExecutorService#execute execute} method.
+     * Shutting down the executor service while the channel is open results in
+     * unspecified behavior.
+     *
+     * <p> The {@code attrs} parameter is an optional array of file {@link
+     * FileAttribute file-attributes} to set atomically when creating the file.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * FileSystemProvider#newFileChannel newFileChannel} method on the
+     * provider that created the {@code Path}.
+     *
+     * @param   file
+     *          The path of the file to open or create
+     * @param   options
+     *          Options specifying how the file is opened
+     * @param   executor
+     *          The thread pool or {@code null} to associate the channel with
+     *          the default thread pool
+     * @param   attrs
+     *          An optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  A new asynchronous file channel
+     *
+     * @throws  IllegalArgumentException
+     *          If the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          If the {@code file} is associated with a provider that does not
+     *          support creating asynchronous file channels, or an unsupported
+     *          open option is specified, or the array contains an attribute that
+     *          cannot be set atomically when creating the file
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an
+     *          unspecified permission required by the implementation.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     */
+    public static AsynchronousFileChannel open(Path file,
+                                               Set<? extends OpenOption> options,
+                                               ExecutorService executor,
+                                               FileAttribute<?>... attrs)
+        throws IOException
+    {
+        FileSystemProvider provider = file.getFileSystem().provider();
+        return provider.newAsynchronousFileChannel(file, options, executor, attrs);
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"}) // generic array construction
+    private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
+
+    /**
+     * Opens or creates a file for reading and/or writing, returning an
+     * asynchronous file channel to access the file.
+     *
+     * <p> An invocation of this method behaves in exactly the same way as the
+     * invocation
+     * <pre>
+     *     ch.{@link #open(Path,Set,ExecutorService,FileAttribute[])
+     *       open}(file, opts, null, new FileAttribute&lt;?&gt;[0]);
+     * </pre>
+     * where {@code opts} is a {@code Set} containing the options specified to
+     * this method.
+     *
+     * <p> The resulting channel is associated with default thread pool to which
+     * tasks are submitted to handle I/O events and dispatch to completion
+     * handlers that consume the result of asynchronous operations performed on
+     * the resulting channel.
+     *
+     * @param   file
+     *          The path of the file to open or create
+     * @param   options
+     *          Options specifying how the file is opened
+     *
+     * @return  A new asynchronous file channel
+     *
+     * @throws  IllegalArgumentException
+     *          If the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          If the {@code file} is associated with a provider that does not
+     *          support creating file channels, or an unsupported open option is
+     *          specified
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an
+     *          unspecified permission required by the implementation.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     */
+    public static AsynchronousFileChannel open(Path file, OpenOption... options)
+        throws IOException
+    {
+        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+        Collections.addAll(set, options);
+        return open(file, set, null, NO_ATTRIBUTES);
+    }
+
+    /**
+     * Returns the current size of this channel's file.
+     *
+     * @return  The current size of this channel's file, measured in bytes
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract long size() throws IOException;
+
+    /**
+     * Truncates this channel's file to the given size.
+     *
+     * <p> If the given size is less than the file's current size then the file
+     * is truncated, discarding any bytes beyond the new end of the file.  If
+     * the given size is greater than or equal to the file's current size then
+     * the file is not modified. </p>
+     *
+     * @param  size
+     *         The new size, a non-negative byte count
+     *
+     * @return  This file channel
+     *
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  IllegalArgumentException
+     *          If the new size is negative
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract AsynchronousFileChannel truncate(long size) throws IOException;
+
+    /**
+     * Forces any updates to this channel's file to be written to the storage
+     * device that contains it.
+     *
+     * <p> If this channel's file resides on a local storage device then when
+     * this method returns it is guaranteed that all changes made to the file
+     * since this channel was created, or since this method was last invoked,
+     * will have been written to that device.  This is useful for ensuring that
+     * critical information is not lost in the event of a system crash.
+     *
+     * <p> If the file does not reside on a local device then no such guarantee
+     * is made.
+     *
+     * <p> The {@code metaData} parameter can be used to limit the number of
+     * I/O operations that this method is required to perform.  Passing
+     * {@code false} for this parameter indicates that only updates to the
+     * file's content need be written to storage; passing {@code true}
+     * indicates that updates to both the file's content and metadata must be
+     * written, which generally requires at least one more I/O operation.
+     * Whether this parameter actually has any effect is dependent upon the
+     * underlying operating system and is therefore unspecified.
+     *
+     * <p> Invoking this method may cause an I/O operation to occur even if the
+     * channel was only opened for reading.  Some operating systems, for
+     * example, maintain a last-access time as part of a file's metadata, and
+     * this time is updated whenever the file is read.  Whether or not this is
+     * actually done is system-dependent and is therefore unspecified.
+     *
+     * <p> This method is only guaranteed to force changes that were made to
+     * this channel's file via the methods defined in this class.
+     *
+     * @param   metaData
+     *          If {@code true} then this method is required to force changes
+     *          to both the file's content and metadata to be written to
+     *          storage; otherwise, it need only force content changes to be
+     *          written
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract void force(boolean metaData) throws IOException;
+
+    /**
+     * Acquires a lock on the given region of this channel's file.
+     *
+     * <p> This method initiates an operation to acquire a lock on the given
+     * region of this channel's file. The {@code handler} parameter is a
+     * completion handler that is invoked when the lock is acquired (or the
+     * operation fails). The result passed to the completion handler is the
+     * resulting {@code FileLock}.
+     *
+     * <p> The region specified by the {@code position} and {@code size}
+     * parameters need not be contained within, or even overlap, the actual
+     * underlying file.  Lock regions are fixed in size; if a locked region
+     * initially contains the end of the file and the file grows beyond the
+     * region then the new portion of the file will not be covered by the lock.
+     * If a file is expected to grow in size and a lock on the entire file is
+     * required then a region starting at zero, and no smaller than the
+     * expected maximum size of the file, should be locked.  The two-argument
+     * {@link #lock(Object,CompletionHandler)} method simply locks a region
+     * of size {@link Long#MAX_VALUE}. If a lock that overlaps the requested
+     * region is already held by this Java virtual machine, or this method has
+     * been invoked to lock an overlapping region and that operation has not
+     * completed, then this method throws {@link OverlappingFileLockException}.
+     *
+     * <p> Some operating systems do not support a mechanism to acquire a file
+     * lock in an asynchronous manner. Consequently an implementation may
+     * acquire the file lock in a background thread or from a task executed by
+     * a thread in the associated thread pool. If there are many lock operations
+     * outstanding then it may consume threads in the Java virtual machine for
+     * indefinite periods.
+     *
+     * <p> Some operating systems do not support shared locks, in which case a
+     * request for a shared lock is automatically converted into a request for
+     * an exclusive lock.  Whether the newly-acquired lock is shared or
+     * exclusive may be tested by invoking the resulting lock object's {@link
+     * FileLock#isShared() isShared} method.
+     *
+     * <p> File locks are held on behalf of the entire Java virtual machine.
+     * They are not suitable for controlling access to a file by multiple
+     * threads within the same virtual machine.
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   position
+     *          The position at which the locked region is to start; must be
+     *          non-negative
+     * @param   size
+     *          The size of the locked region; must be non-negative, and the sum
+     *          {@code position}&nbsp;+&nbsp;{@code size} must be non-negative
+     * @param   shared
+     *          {@code true} to request a shared lock, in which case this
+     *          channel must be open for reading (and possibly writing);
+     *          {@code false} to request an exclusive lock, in which case this
+     *          channel must be open for writing (and possibly reading)
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result
+     *
+     * @throws  OverlappingFileLockException
+     *          If a lock that overlaps the requested region is already held by
+     *          this Java virtual machine, or there is already a pending attempt
+     *          to lock an overlapping region
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameters do not hold
+     * @throws  NonReadableChannelException
+     *          If {@code shared} is true but this channel was not opened for reading
+     * @throws  NonWritableChannelException
+     *          If {@code shared} is false but this channel was not opened for writing
+     */
+    public abstract <A> void lock(long position,
+                                  long size,
+                                  boolean shared,
+                                  A attachment,
+                                  CompletionHandler<FileLock,? super A> handler);
+
+    /**
+     * Acquires an exclusive lock on this channel's file.
+     *
+     * <p> This method initiates an operation to acquire a lock on the given
+     * region of this channel's file. The {@code handler} parameter is a
+     * completion handler that is invoked when the lock is acquired (or the
+     * operation fails). The result passed to the completion handler is the
+     * resulting {@code FileLock}.
+     *
+     * <p> An invocation of this method of the form {@code ch.lock(att,handler)}
+     * behaves in exactly the same way as the invocation
+     * <pre>
+     *     ch.{@link #lock(long,long,boolean,Object,CompletionHandler) lock}(0L, Long.MAX_VALUE, false, att, handler)
+     * </pre>
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result
+     *
+     * @throws  OverlappingFileLockException
+     *          If a lock is already held by this Java virtual machine, or there
+     *          is already a pending attempt to lock a region
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     */
+    public final <A> void lock(A attachment,
+                               CompletionHandler<FileLock,? super A> handler)
+    {
+        lock(0L, Long.MAX_VALUE, false, attachment, handler);
+    }
+
+    /**
+     * Acquires a lock on the given region of this channel's file.
+     *
+     * <p> This method initiates an operation to acquire a lock on the given
+     * region of this channel's file.  The method behaves in exactly the same
+     * manner as the {@link #lock(long, long, boolean, Object, CompletionHandler)}
+     * method except that instead of specifying a completion handler, this
+     * method returns a {@code Future} representing the pending result. The
+     * {@code Future}'s {@link Future#get() get} method returns the {@link
+     * FileLock} on successful completion.
+     *
+     * @param   position
+     *          The position at which the locked region is to start; must be
+     *          non-negative
+     * @param   size
+     *          The size of the locked region; must be non-negative, and the sum
+     *          {@code position}&nbsp;+&nbsp;{@code size} must be non-negative
+     * @param   shared
+     *          {@code true} to request a shared lock, in which case this
+     *          channel must be open for reading (and possibly writing);
+     *          {@code false} to request an exclusive lock, in which case this
+     *          channel must be open for writing (and possibly reading)
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  OverlappingFileLockException
+     *          If a lock is already held by this Java virtual machine, or there
+     *          is already a pending attempt to lock a region
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameters do not hold
+     * @throws  NonReadableChannelException
+     *          If {@code shared} is true but this channel was not opened for reading
+     * @throws  NonWritableChannelException
+     *          If {@code shared} is false but this channel was not opened for writing
+     */
+    public abstract Future<FileLock> lock(long position, long size, boolean shared);
+
+    /**
+     * Acquires an exclusive lock on this channel's file.
+     *
+     * <p> This method initiates an operation to acquire an exclusive lock on this
+     * channel's file. The method returns a {@code Future} representing the
+     * pending result of the operation. The {@code Future}'s {@link Future#get()
+     * get} method returns the {@link FileLock} on successful completion.
+     *
+     * <p> An invocation of this method behaves in exactly the same way as the
+     * invocation
+     * <pre>
+     *     ch.{@link #lock(long,long,boolean) lock}(0L, Long.MAX_VALUE, false)
+     * </pre>
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  OverlappingFileLockException
+     *          If a lock is already held by this Java virtual machine, or there
+     *          is already a pending attempt to lock a region
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     */
+    public final Future<FileLock> lock() {
+        return lock(0L, Long.MAX_VALUE, false);
+    }
+
+    /**
+     * Attempts to acquire a lock on the given region of this channel's file.
+     *
+     * <p> This method does not block. An invocation always returns immediately,
+     * either having acquired a lock on the requested region or having failed to
+     * do so.  If it fails to acquire a lock because an overlapping lock is held
+     * by another program then it returns {@code null}.  If it fails to acquire
+     * a lock for any other reason then an appropriate exception is thrown.
+     *
+     * @param  position
+     *         The position at which the locked region is to start; must be
+     *         non-negative
+     *
+     * @param  size
+     *         The size of the locked region; must be non-negative, and the sum
+     *         {@code position}&nbsp;+&nbsp;{@code size} must be non-negative
+     *
+     * @param  shared
+     *         {@code true} to request a shared lock,
+     *         {@code false} to request an exclusive lock
+     *
+     * @return  A lock object representing the newly-acquired lock,
+     *          or {@code null} if the lock could not be acquired
+     *          because another program holds an overlapping lock
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameters do not hold
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  OverlappingFileLockException
+     *          If a lock that overlaps the requested region is already held by
+     *          this Java virtual machine, or if another thread is already
+     *          blocked in this method and is attempting to lock an overlapping
+     *          region of the same file
+     * @throws  NonReadableChannelException
+     *          If {@code shared} is true but this channel was not opened for reading
+     * @throws  NonWritableChannelException
+     *          If {@code shared} is false but this channel was not opened for writing
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     *
+     * @see     #lock(Object,CompletionHandler)
+     * @see     #lock(long,long,boolean,Object,CompletionHandler)
+     * @see     #tryLock()
+     */
+    public abstract FileLock tryLock(long position, long size, boolean shared)
+        throws IOException;
+
+    /**
+     * Attempts to acquire an exclusive lock on this channel's file.
+     *
+     * <p> An invocation of this method of the form {@code ch.tryLock()}
+     * behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     ch.{@link #tryLock(long,long,boolean) tryLock}(0L, Long.MAX_VALUE, false) </pre>
+     *
+     * @return  A lock object representing the newly-acquired lock,
+     *          or {@code null} if the lock could not be acquired
+     *          because another program holds an overlapping lock
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  OverlappingFileLockException
+     *          If a lock that overlaps the requested region is already held by
+     *          this Java virtual machine, or if another thread is already
+     *          blocked in this method and is attempting to lock an overlapping
+     *          region
+     * @throws  NonWritableChannelException
+     *          If {@code shared} is false but this channel was not opened for writing
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     *
+     * @see     #lock(Object,CompletionHandler)
+     * @see     #lock(long,long,boolean,Object,CompletionHandler)
+     * @see     #tryLock(long,long,boolean)
+     */
+    public final FileLock tryLock() throws IOException {
+        return tryLock(0L, Long.MAX_VALUE, false);
+    }
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer,
+     * starting at the given file position.
+     *
+     * <p> This method initiates the reading of a sequence of bytes from this
+     * channel into the given buffer, starting at the given file position. The
+     * result of the read is the number of bytes read or {@code -1} if the given
+     * position is greater than or equal to the file's size at the time that the
+     * read is attempted.
+     *
+     * <p> This method works in the same manner as the {@link
+     * AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)}
+     * method, except that bytes are read starting at the given file position.
+     * If the given file position is greater than the file's size at the time
+     * that the read is attempted then no bytes are read.
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   dst
+     *          The buffer into which bytes are to be transferred
+     * @param   position
+     *          The file position at which the transfer is to begin;
+     *          must be non-negative
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result
+     *
+     * @throws  IllegalArgumentException
+     *          If the position is negative or the buffer is read-only
+     * @throws  NonReadableChannelException
+     *          If this channel was not opened for reading
+     */
+    public abstract <A> void read(ByteBuffer dst,
+                                  long position,
+                                  A attachment,
+                                  CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer,
+     * starting at the given file position.
+     *
+     * <p> This method initiates the reading of a sequence of bytes from this
+     * channel into the given buffer, starting at the given file position. This
+     * method returns a {@code Future} representing the pending result of the
+     * operation. The {@code Future}'s {@link Future#get() get} method returns
+     * the number of bytes read or {@code -1} if the given position is greater
+     * than or equal to the file's size at the time that the read is attempted.
+     *
+     * <p> This method works in the same manner as the {@link
+     * AsynchronousByteChannel#read(ByteBuffer)} method, except that bytes are
+     * read starting at the given file position. If the given file position is
+     * greater than the file's size at the time that the read is attempted then
+     * no bytes are read.
+     *
+     * @param   dst
+     *          The buffer into which bytes are to be transferred
+     * @param   position
+     *          The file position at which the transfer is to begin;
+     *          must be non-negative
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the position is negative or the buffer is read-only
+     * @throws  NonReadableChannelException
+     *          If this channel was not opened for reading
+     */
+    public abstract Future<Integer> read(ByteBuffer dst, long position);
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer, starting
+     * at the given file position.
+     *
+     * <p> This method works in the same manner as the {@link
+     * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
+     * method, except that bytes are written starting at the given file position.
+     * If the given position is greater than the file's size, at the time that
+     * the write is attempted, then the file will be grown to accommodate the new
+     * bytes; the values of any bytes between the previous end-of-file and the
+     * newly-written bytes are unspecified.
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   src
+     *          The buffer from which bytes are to be transferred
+     * @param   position
+     *          The file position at which the transfer is to begin;
+     *          must be non-negative
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result
+     *
+     * @throws  IllegalArgumentException
+     *          If the position is negative
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     */
+    public abstract <A> void write(ByteBuffer src,
+                                   long position,
+                                   A attachment,
+                                   CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer, starting
+     * at the given file position.
+     *
+     * <p> This method initiates the writing of a sequence of bytes to this
+     * channel from the given buffer, starting at the given file position. The
+     * method returns a {@code Future} representing the pending result of the
+     * write operation. The {@code Future}'s {@link Future#get() get} method
+     * returns the number of bytes written.
+     *
+     * <p> This method works in the same manner as the {@link
+     * AsynchronousByteChannel#write(ByteBuffer)} method, except that bytes are
+     * written starting at the given file position. If the given position is
+     * greater than the file's size, at the time that the write is attempted,
+     * then the file will be grown to accommodate the new bytes; the values of
+     * any bytes between the previous end-of-file and the newly-written bytes
+     * are unspecified.
+     *
+     * @param   src
+     *          The buffer from which bytes are to be transferred
+     * @param   position
+     *          The file position at which the transfer is to begin;
+     *          must be non-negative
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  IllegalArgumentException
+     *          If the position is negative
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     */
+    public abstract Future<Integer> write(ByteBuffer src, long position);
+}
diff --git a/java/nio/channels/AsynchronousServerSocketChannel.java b/java/nio/channels/AsynchronousServerSocketChannel.java
new file mode 100644
index 0000000..29ecbd6
--- /dev/null
+++ b/java/nio/channels/AsynchronousServerSocketChannel.java
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2007, 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.nio.channels;
+
+import java.nio.channels.spi.*;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.util.concurrent.Future;
+import java.io.IOException;
+
+/**
+ * An asynchronous channel for stream-oriented listening sockets.
+ *
+ * <p> An asynchronous server-socket channel is created by invoking the
+ * {@link #open open} method of this class.
+ * A newly-created asynchronous server-socket channel is open but not yet bound.
+ * It can be bound to a local address and configured to listen for connections
+ * by invoking the {@link #bind(SocketAddress,int) bind} method. Once bound,
+ * the {@link #accept(Object,CompletionHandler) accept} method
+ * is used to initiate the accepting of connections to the channel's socket.
+ * An attempt to invoke the <tt>accept</tt> method on an unbound channel will
+ * cause a {@link NotYetBoundException} to be thrown.
+ *
+ * <p> Channels of this type are safe for use by multiple concurrent threads
+ * though at most one accept operation can be outstanding at any time.
+ * If a thread initiates an accept operation before a previous accept operation
+ * has completed then an {@link AcceptPendingException} will be thrown.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. Channels of this type support the following options:
+ * <blockquote>
+ * <table border summary="Socket options">
+ *   <tr>
+ *     <th>Option Name</th>
+ *     <th>Description</th>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> The size of the socket receive buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> Re-use address </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ *  final AsynchronousServerSocketChannel listener =
+ *      AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(5000));
+ *
+ *  listener.accept(null, new CompletionHandler&lt;AsynchronousSocketChannel,Void&gt;() {
+ *      public void completed(AsynchronousSocketChannel ch, Void att) {
+ *          // accept the next connection
+ *          listener.accept(null, this);
+ *
+ *          // handle this connection
+ *          handle(ch);
+ *      }
+ *      public void failed(Throwable exc, Void att) {
+ *          ...
+ *      }
+ *  });
+ * </pre>
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousServerSocketChannel
+    implements AsynchronousChannel, NetworkChannel
+{
+    private final AsynchronousChannelProvider provider;
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @param  provider
+     *         The provider that created this channel
+     */
+    protected AsynchronousServerSocketChannel(AsynchronousChannelProvider provider) {
+        this.provider = provider;
+    }
+
+    /**
+     * Returns the provider that created this channel.
+     *
+     * @return  The provider that created this channel
+     */
+    public final AsynchronousChannelProvider provider() {
+        return provider;
+    }
+
+    /**
+     * Opens an asynchronous server-socket channel.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * java.nio.channels.spi.AsynchronousChannelProvider#openAsynchronousServerSocketChannel
+     * openAsynchronousServerSocketChannel} method on the {@link
+     * java.nio.channels.spi.AsynchronousChannelProvider} object that created
+     * the given group. If the group parameter is <tt>null</tt> then the
+     * resulting channel is created by the system-wide default provider, and
+     * bound to the <em>default group</em>.
+     *
+     * @param   group
+     *          The group to which the newly constructed channel should be bound,
+     *          or <tt>null</tt> for the default group
+     *
+     * @return  A new asynchronous server socket channel
+     *
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group is shutdown
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousServerSocketChannel open(AsynchronousChannelGroup group)
+        throws IOException
+    {
+        AsynchronousChannelProvider provider = (group == null) ?
+            AsynchronousChannelProvider.provider() : group.provider();
+        return provider.openAsynchronousServerSocketChannel(group);
+    }
+
+    /**
+     * Opens an asynchronous server-socket channel.
+     *
+     * <p> This method returns an asynchronous server socket channel that is
+     * bound to the <em>default group</em>. This method is equivalent to evaluating
+     * the expression:
+     * <blockquote><pre>
+     * open((AsynchronousChannelGroup)null);
+     * </pre></blockquote>
+     *
+     * @return  A new asynchronous server socket channel
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousServerSocketChannel open()
+        throws IOException
+    {
+        return open(null);
+    }
+
+    /**
+     * Binds the channel's socket to a local address and configures the socket to
+     * listen for connections.
+     *
+     * <p> An invocation of this method is equivalent to the following:
+     * <blockquote><pre>
+     * bind(local, 0);
+     * </pre></blockquote>
+     *
+     * @param   local
+     *          The local address to bind the socket, or <tt>null</tt> to bind
+     *          to an automatically assigned socket address
+     *
+     * @return  This channel
+     *
+     * @throws  AlreadyBoundException               {@inheritDoc}
+     * @throws  UnsupportedAddressTypeException     {@inheritDoc}
+     * @throws  SecurityException                   {@inheritDoc}
+     * @throws  ClosedChannelException              {@inheritDoc}
+     * @throws  IOException                         {@inheritDoc}
+     */
+    public final AsynchronousServerSocketChannel bind(SocketAddress local)
+        throws IOException
+    {
+        return bind(local, 0);
+    }
+
+    /**
+     * Binds the channel's socket to a local address and configures the socket to
+     * listen for connections.
+     *
+     * <p> This method is used to establish an association between the socket and
+     * a local address. Once an association is established then the socket remains
+     * bound until the associated channel is closed.
+     *
+     * <p> The {@code backlog} parameter is the maximum number of pending
+     * connections on the socket. Its exact semantics are implementation specific.
+     * In particular, an implementation may impose a maximum length or may choose
+     * to ignore the parameter altogther. If the {@code backlog} parameter has
+     * the value {@code 0}, or a negative value, then an implementation specific
+     * default is used.
+     *
+     * @param   local
+     *          The local address to bind the socket, or {@code null} to bind
+     *          to an automatically assigned socket address
+     * @param   backlog
+     *          The maximum number of pending connections
+     *
+     * @return  This channel
+     *
+     * @throws  AlreadyBoundException
+     *          If the socket is already bound
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given address is not supported
+     * @throws  SecurityException
+     *          If a security manager has been installed and its {@link
+     *          SecurityManager#checkListen checkListen} method denies the operation
+     * @throws  ClosedChannelException
+     *          If the channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract AsynchronousServerSocketChannel bind(SocketAddress local, int backlog)
+        throws IOException;
+
+    /**
+     * @throws  IllegalArgumentException                {@inheritDoc}
+     * @throws  ClosedChannelException                  {@inheritDoc}
+     * @throws  IOException                             {@inheritDoc}
+     */
+    public abstract <T> AsynchronousServerSocketChannel setOption(SocketOption<T> name, T value)
+        throws IOException;
+
+    /**
+     * Accepts a connection.
+     *
+     * <p> This method initiates an asynchronous operation to accept a
+     * connection made to this channel's socket. The {@code handler} parameter is
+     * a completion handler that is invoked when a connection is accepted (or
+     * the operation fails). The result passed to the completion handler is
+     * the {@link AsynchronousSocketChannel} to the new connection.
+     *
+     * <p> When a new connection is accepted then the resulting {@code
+     * AsynchronousSocketChannel} will be bound to the same {@link
+     * AsynchronousChannelGroup} as this channel. If the group is {@link
+     * AsynchronousChannelGroup#isShutdown shutdown} and a connection is accepted,
+     * then the connection is closed, and the operation completes with an {@code
+     * IOException} and cause {@link ShutdownChannelGroupException}.
+     *
+     * <p> To allow for concurrent handling of new connections, the completion
+     * handler is not invoked directly by the initiating thread when a new
+     * connection is accepted immediately (see <a
+     * href="AsynchronousChannelGroup.html#threading">Threading</a>).
+     *
+     * <p> If a security manager has been installed then it verifies that the
+     * address and port number of the connection's remote endpoint are permitted
+     * by the security manager's {@link SecurityManager#checkAccept checkAccept}
+     * method. The permission check is performed with privileges that are restricted
+     * by the calling context of this method. If the permission check fails then
+     * the connection is closed and the operation completes with a {@link
+     * SecurityException}.
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result
+     *
+     * @throws  AcceptPendingException
+     *          If an accept operation is already in progress on this channel
+     * @throws  NotYetBoundException
+     *          If this channel's socket has not yet been bound
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group has terminated
+     */
+    public abstract <A> void accept(A attachment,
+                                    CompletionHandler<AsynchronousSocketChannel,? super A> handler);
+
+    /**
+     * Accepts a connection.
+     *
+     * <p> This method initiates an asynchronous operation to accept a
+     * connection made to this channel's socket. The method behaves in exactly
+     * the same manner as the {@link #accept(Object, CompletionHandler)} method
+     * except that instead of specifying a completion handler, this method
+     * returns a {@code Future} representing the pending result. The {@code
+     * Future}'s {@link Future#get() get} method returns the {@link
+     * AsynchronousSocketChannel} to the new connection on successful completion.
+     *
+     * @return  a {@code Future} object representing the pending result
+     *
+     * @throws  AcceptPendingException
+     *          If an accept operation is already in progress on this channel
+     * @throws  NotYetBoundException
+     *          If this channel's socket has not yet been bound
+     */
+    public abstract Future<AsynchronousSocketChannel> accept();
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * If there is a security manager set, its {@code checkConnect} method is
+     * called with the local address and {@code -1} as its arguments to see
+     * if the operation is allowed. If the operation is not allowed,
+     * a {@code SocketAddress} representing the
+     * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+     * local port of the channel's socket is returned.
+     *
+     * @return  The {@code SocketAddress} that the socket is bound to, or the
+     *          {@code SocketAddress} representing the loopback address if
+     *          denied by the security manager, or {@code null} if the
+     *          channel's socket is not bound
+     *
+     * @throws  ClosedChannelException     {@inheritDoc}
+     * @throws  IOException                {@inheritDoc}
+     */
+    @Override
+    public abstract SocketAddress getLocalAddress() throws IOException;
+}
diff --git a/java/nio/channels/AsynchronousSocketChannel.java b/java/nio/channels/AsynchronousSocketChannel.java
new file mode 100644
index 0000000..1ed1e86
--- /dev/null
+++ b/java/nio/channels/AsynchronousSocketChannel.java
@@ -0,0 +1,687 @@
+/*
+ * Copyright (c) 2007, 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.nio.channels;
+
+import java.nio.channels.spi.*;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.Future;
+import java.io.IOException;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+
+/**
+ * An asynchronous channel for stream-oriented connecting sockets.
+ *
+ * <p> Asynchronous socket channels are created in one of two ways. A newly-created
+ * {@code AsynchronousSocketChannel} is created by invoking one of the {@link
+ * #open open} methods defined by this class. A newly-created channel is open but
+ * not yet connected. A connected {@code AsynchronousSocketChannel} is created
+ * when a connection is made to the socket of an {@link AsynchronousServerSocketChannel}.
+ * It is not possible to create an asynchronous socket channel for an arbitrary,
+ * pre-existing {@link java.net.Socket socket}.
+ *
+ * <p> A newly-created channel is connected by invoking its {@link #connect connect}
+ * method; once connected, a channel remains connected until it is closed.  Whether
+ * or not a socket channel is connected may be determined by invoking its {@link
+ * #getRemoteAddress getRemoteAddress} method. An attempt to invoke an I/O
+ * operation upon an unconnected channel will cause a {@link NotYetConnectedException}
+ * to be thrown.
+ *
+ * <p> Channels of this type are safe for use by multiple concurrent threads.
+ * They support concurrent reading and writing, though at most one read operation
+ * and one write operation can be outstanding at any time.
+ * If a thread initiates a read operation before a previous read operation has
+ * completed then a {@link ReadPendingException} will be thrown. Similarly, an
+ * attempt to initiate a write operation before a previous write has completed
+ * will throw a {@link WritePendingException}.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. Asynchronous socket channels support the following options:
+ * <blockquote>
+ * <table border summary="Socket options">
+ *   <tr>
+ *     <th>Option Name</th>
+ *     <th>Description</th>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td>
+ *     <td> The size of the socket send buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> The size of the socket receive buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </td>
+ *     <td> Keep connection alive </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> Re-use address </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </td>
+ *     <td> Disable the Nagle algorithm </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <h2>Timeouts</h2>
+ *
+ * <p> The {@link #read(ByteBuffer,long,TimeUnit,Object,CompletionHandler) read}
+ * and {@link #write(ByteBuffer,long,TimeUnit,Object,CompletionHandler) write}
+ * methods defined by this class allow a timeout to be specified when initiating
+ * a read or write operation. If the timeout elapses before an operation completes
+ * then the operation completes with the exception {@link
+ * InterruptedByTimeoutException}. A timeout may leave the channel, or the
+ * underlying connection, in an inconsistent state. Where the implementation
+ * cannot guarantee that bytes have not been read from the channel then it puts
+ * the channel into an implementation specific <em>error state</em>. A subsequent
+ * attempt to initiate a {@code read} operation causes an unspecified runtime
+ * exception to be thrown. Similarly if a {@code write} operation times out and
+ * the implementation cannot guarantee bytes have not been written to the
+ * channel then further attempts to {@code write} to the channel cause an
+ * unspecified runtime exception to be thrown. When a timeout elapses then the
+ * state of the {@link ByteBuffer}, or the sequence of buffers, for the I/O
+ * operation is not defined. Buffers should be discarded or at least care must
+ * be taken to ensure that the buffers are not accessed while the channel remains
+ * open. All methods that accept timeout parameters treat values less than or
+ * equal to zero to mean that the I/O operation does not timeout.
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousSocketChannel
+    implements AsynchronousByteChannel, NetworkChannel
+{
+    private final AsynchronousChannelProvider provider;
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @param  provider
+     *         The provider that created this channel
+     */
+    protected AsynchronousSocketChannel(AsynchronousChannelProvider provider) {
+        this.provider = provider;
+    }
+
+    /**
+     * Returns the provider that created this channel.
+     *
+     * @return  The provider that created this channel
+     */
+    public final AsynchronousChannelProvider provider() {
+        return provider;
+    }
+
+    /**
+     * Opens an asynchronous socket channel.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * AsynchronousChannelProvider#openAsynchronousSocketChannel
+     * openAsynchronousSocketChannel} method on the {@link
+     * AsynchronousChannelProvider} that created the group. If the group parameter
+     * is {@code null} then the resulting channel is created by the system-wide
+     * default provider, and bound to the <em>default group</em>.
+     *
+     * @param   group
+     *          The group to which the newly constructed channel should be bound,
+     *          or {@code null} for the default group
+     *
+     * @return  A new asynchronous socket channel
+     *
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group is shutdown
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousSocketChannel open(AsynchronousChannelGroup group)
+        throws IOException
+    {
+        AsynchronousChannelProvider provider = (group == null) ?
+            AsynchronousChannelProvider.provider() : group.provider();
+        return provider.openAsynchronousSocketChannel(group);
+    }
+
+    /**
+     * Opens an asynchronous socket channel.
+     *
+     * <p> This method returns an asynchronous socket channel that is bound to
+     * the <em>default group</em>.This method is equivalent to evaluating the
+     * expression:
+     * <blockquote><pre>
+     * open((AsynchronousChannelGroup)null);
+     * </pre></blockquote>
+     *
+     * @return  A new asynchronous socket channel
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static AsynchronousSocketChannel open()
+        throws IOException
+    {
+        return open(null);
+    }
+
+
+    // -- socket options and related --
+
+    /**
+     * @throws  ConnectionPendingException
+     *          If a connection operation is already in progress on this channel
+     * @throws  AlreadyBoundException               {@inheritDoc}
+     * @throws  UnsupportedAddressTypeException     {@inheritDoc}
+     * @throws  ClosedChannelException              {@inheritDoc}
+     * @throws  IOException                         {@inheritDoc}
+     * @throws  SecurityException
+     *          If a security manager has been installed and its
+     *          {@link SecurityManager#checkListen checkListen} method denies
+     *          the operation
+     */
+    @Override
+    public abstract AsynchronousSocketChannel bind(SocketAddress local)
+        throws IOException;
+
+    /**
+     * @throws  IllegalArgumentException                {@inheritDoc}
+     * @throws  ClosedChannelException                  {@inheritDoc}
+     * @throws  IOException                             {@inheritDoc}
+     */
+    @Override
+    public abstract <T> AsynchronousSocketChannel setOption(SocketOption<T> name, T value)
+        throws IOException;
+
+    /**
+     * Shutdown the connection for reading without closing the channel.
+     *
+     * <p> Once shutdown for reading then further reads on the channel will
+     * return {@code -1}, the end-of-stream indication. If the input side of the
+     * connection is already shutdown then invoking this method has no effect.
+     * The effect on an outstanding read operation is system dependent and
+     * therefore not specified. The effect, if any, when there is data in the
+     * socket receive buffer that has not been read, or data arrives subsequently,
+     * is also system dependent.
+     *
+     * @return  The channel
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract AsynchronousSocketChannel shutdownInput() throws IOException;
+
+    /**
+     * Shutdown the connection for writing without closing the channel.
+     *
+     * <p> Once shutdown for writing then further attempts to write to the
+     * channel will throw {@link ClosedChannelException}. If the output side of
+     * the connection is already shutdown then invoking this method has no
+     * effect. The effect on an outstanding write operation is system dependent
+     * and therefore not specified.
+     *
+     * @return  The channel
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract AsynchronousSocketChannel shutdownOutput() throws IOException;
+
+    // -- state --
+
+    /**
+     * Returns the remote address to which this channel's socket is connected.
+     *
+     * <p> Where the channel is bound and connected to an Internet Protocol
+     * socket address then the return value from this method is of type {@link
+     * java.net.InetSocketAddress}.
+     *
+     * @return  The remote address; {@code null} if the channel's socket is not
+     *          connected
+     *
+     * @throws  ClosedChannelException
+     *          If the channel is closed
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract SocketAddress getRemoteAddress() throws IOException;
+
+    // -- asynchronous operations --
+
+    /**
+     * Connects this channel.
+     *
+     * <p> This method initiates an operation to connect this channel. The
+     * {@code handler} parameter is a completion handler that is invoked when
+     * the connection is successfully established or connection cannot be
+     * established. If the connection cannot be established then the channel is
+     * closed.
+     *
+     * <p> This method performs exactly the same security checks as the {@link
+     * java.net.Socket} class.  That is, if a security manager has been
+     * installed then this method verifies that its {@link
+     * java.lang.SecurityManager#checkConnect checkConnect} method permits
+     * connecting to the address and port number of the given remote endpoint.
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   remote
+     *          The remote address to which this channel is to be connected
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result
+     *
+     * @throws  UnresolvedAddressException
+     *          If the given remote address is not fully resolved
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given remote address is not supported
+     * @throws  AlreadyConnectedException
+     *          If this channel is already connected
+     * @throws  ConnectionPendingException
+     *          If a connection operation is already in progress on this channel
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group has terminated
+     * @throws  SecurityException
+     *          If a security manager has been installed
+     *          and it does not permit access to the given remote endpoint
+     *
+     * @see #getRemoteAddress
+     */
+    public abstract <A> void connect(SocketAddress remote,
+                                     A attachment,
+                                     CompletionHandler<Void,? super A> handler);
+
+    /**
+     * Connects this channel.
+     *
+     * <p> This method initiates an operation to connect this channel. This
+     * method behaves in exactly the same manner as the {@link
+     * #connect(SocketAddress, Object, CompletionHandler)} method except that
+     * instead of specifying a completion handler, this method returns a {@code
+     * Future} representing the pending result. The {@code Future}'s {@link
+     * Future#get() get} method returns {@code null} on successful completion.
+     *
+     * @param   remote
+     *          The remote address to which this channel is to be connected
+     *
+     * @return  A {@code Future} object representing the pending result
+     *
+     * @throws  UnresolvedAddressException
+     *          If the given remote address is not fully resolved
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given remote address is not supported
+     * @throws  AlreadyConnectedException
+     *          If this channel is already connected
+     * @throws  ConnectionPendingException
+     *          If a connection operation is already in progress on this channel
+     * @throws  SecurityException
+     *          If a security manager has been installed
+     *          and it does not permit access to the given remote endpoint
+     */
+    public abstract Future<Void> connect(SocketAddress remote);
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * <p> This method initiates an asynchronous read operation to read a
+     * sequence of bytes from this channel into the given buffer. The {@code
+     * handler} parameter is a completion handler that is invoked when the read
+     * operation completes (or fails). The result passed to the completion
+     * handler is the number of bytes read or {@code -1} if no bytes could be
+     * read because the channel has reached end-of-stream.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then the operation completes with the exception {@link
+     * InterruptedByTimeoutException}. Where a timeout occurs, and the
+     * implementation cannot guarantee that bytes have not been read, or will not
+     * be read from the channel into the given buffer, then further attempts to
+     * read from the channel will cause an unspecific runtime exception to be
+     * thrown.
+     *
+     * <p> Otherwise this method works in the same manner as the {@link
+     * AsynchronousByteChannel#read(ByteBuffer,Object,CompletionHandler)}
+     * method.
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   dst
+     *          The buffer into which bytes are to be transferred
+     * @param   timeout
+     *          The maximum time for the I/O operation to complete
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result
+     *
+     * @throws  IllegalArgumentException
+     *          If the buffer is read-only
+     * @throws  ReadPendingException
+     *          If a read operation is already in progress on this channel
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group has terminated
+     */
+    public abstract <A> void read(ByteBuffer dst,
+                                  long timeout,
+                                  TimeUnit unit,
+                                  A attachment,
+                                  CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * @throws  IllegalArgumentException        {@inheritDoc}
+     * @throws  ReadPendingException            {@inheritDoc}
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group has terminated
+     */
+    @Override
+    public final <A> void read(ByteBuffer dst,
+                               A attachment,
+                               CompletionHandler<Integer,? super A> handler)
+    {
+        read(dst, 0L, TimeUnit.MILLISECONDS, attachment, handler);
+    }
+
+    /**
+     * @throws  IllegalArgumentException        {@inheritDoc}
+     * @throws  ReadPendingException            {@inheritDoc}
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     */
+    @Override
+    public abstract Future<Integer> read(ByteBuffer dst);
+
+    /**
+     * Reads a sequence of bytes from this channel into a subsequence of the
+     * given buffers. This operation, sometimes called a <em>scattering read</em>,
+     * is often useful when implementing network protocols that group data into
+     * segments consisting of one or more fixed-length headers followed by a
+     * variable-length body. The {@code handler} parameter is a completion
+     * handler that is invoked when the read operation completes (or fails). The
+     * result passed to the completion handler is the number of bytes read or
+     * {@code -1} if no bytes could be read because the channel has reached
+     * end-of-stream.
+     *
+     * <p> This method initiates a read of up to <i>r</i> bytes from this channel,
+     * where <i>r</i> is the total number of bytes remaining in the specified
+     * subsequence of the given buffer array, that is,
+     *
+     * <blockquote><pre>
+     * dsts[offset].remaining()
+     *     + dsts[offset+1].remaining()
+     *     + ... + dsts[offset+length-1].remaining()</pre></blockquote>
+     *
+     * at the moment that the read is attempted.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is read, where
+     * <tt>0</tt>&nbsp;<tt>&lt;</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * Up to the first <tt>dsts[offset].remaining()</tt> bytes of this sequence
+     * are transferred into buffer <tt>dsts[offset]</tt>, up to the next
+     * <tt>dsts[offset+1].remaining()</tt> bytes are transferred into buffer
+     * <tt>dsts[offset+1]</tt>, and so forth, until the entire byte sequence
+     * is transferred into the given buffers.  As many bytes as possible are
+     * transferred into each buffer, hence the final position of each updated
+     * buffer, except the last updated buffer, is guaranteed to be equal to
+     * that buffer's limit. The underlying operating system may impose a limit
+     * on the number of buffers that may be used in an I/O operation. Where the
+     * number of buffers (with bytes remaining), exceeds this limit, then the
+     * I/O operation is performed with the maximum number of buffers allowed by
+     * the operating system.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then it completes with the exception {@link
+     * InterruptedByTimeoutException}. Where a timeout occurs, and the
+     * implementation cannot guarantee that bytes have not been read, or will not
+     * be read from the channel into the given buffers, then further attempts to
+     * read from the channel will cause an unspecific runtime exception to be
+     * thrown.
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   dsts
+     *          The buffers into which bytes are to be transferred
+     * @param   offset
+     *          The offset within the buffer array of the first buffer into which
+     *          bytes are to be transferred; must be non-negative and no larger than
+     *          {@code dsts.length}
+     * @param   length
+     *          The maximum number of buffers to be accessed; must be non-negative
+     *          and no larger than {@code dsts.length - offset}
+     * @param   timeout
+     *          The maximum time for the I/O operation to complete
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the pre-conditions for the {@code offset}  and {@code length}
+     *          parameter aren't met
+     * @throws  IllegalArgumentException
+     *          If the buffer is read-only
+     * @throws  ReadPendingException
+     *          If a read operation is already in progress on this channel
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group has terminated
+     */
+    public abstract <A> void read(ByteBuffer[] dsts,
+                                  int offset,
+                                  int length,
+                                  long timeout,
+                                  TimeUnit unit,
+                                  A attachment,
+                                  CompletionHandler<Long,? super A> handler);
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * <p> This method initiates an asynchronous write operation to write a
+     * sequence of bytes to this channel from the given buffer. The {@code
+     * handler} parameter is a completion handler that is invoked when the write
+     * operation completes (or fails). The result passed to the completion
+     * handler is the number of bytes written.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then it completes with the exception {@link
+     * InterruptedByTimeoutException}. Where a timeout occurs, and the
+     * implementation cannot guarantee that bytes have not been written, or will
+     * not be written to the channel from the given buffer, then further attempts
+     * to write to the channel will cause an unspecific runtime exception to be
+     * thrown.
+     *
+     * <p> Otherwise this method works in the same manner as the {@link
+     * AsynchronousByteChannel#write(ByteBuffer,Object,CompletionHandler)}
+     * method.
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   src
+     *          The buffer from which bytes are to be retrieved
+     * @param   timeout
+     *          The maximum time for the I/O operation to complete
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result
+     *
+     * @throws  WritePendingException
+     *          If a write operation is already in progress on this channel
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group has terminated
+     */
+    public abstract <A> void write(ByteBuffer src,
+                                   long timeout,
+                                   TimeUnit unit,
+                                   A attachment,
+                                   CompletionHandler<Integer,? super A> handler);
+
+    /**
+     * @throws  WritePendingException          {@inheritDoc}
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group has terminated
+     */
+    @Override
+    public final <A> void write(ByteBuffer src,
+                                A attachment,
+                                CompletionHandler<Integer,? super A> handler)
+
+    {
+        write(src, 0L, TimeUnit.MILLISECONDS, attachment, handler);
+    }
+
+    /**
+     * @throws  WritePendingException       {@inheritDoc}
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     */
+    @Override
+    public abstract Future<Integer> write(ByteBuffer src);
+
+    /**
+     * Writes a sequence of bytes to this channel from a subsequence of the given
+     * buffers. This operation, sometimes called a <em>gathering write</em>, is
+     * often useful when implementing network protocols that group data into
+     * segments consisting of one or more fixed-length headers followed by a
+     * variable-length body. The {@code handler} parameter is a completion
+     * handler that is invoked when the write operation completes (or fails).
+     * The result passed to the completion handler is the number of bytes written.
+     *
+     * <p> This method initiates a write of up to <i>r</i> bytes to this channel,
+     * where <i>r</i> is the total number of bytes remaining in the specified
+     * subsequence of the given buffer array, that is,
+     *
+     * <blockquote><pre>
+     * srcs[offset].remaining()
+     *     + srcs[offset+1].remaining()
+     *     + ... + srcs[offset+length-1].remaining()</pre></blockquote>
+     *
+     * at the moment that the write is attempted.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is written, where
+     * <tt>0</tt>&nbsp;<tt>&lt;</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * Up to the first <tt>srcs[offset].remaining()</tt> bytes of this sequence
+     * are written from buffer <tt>srcs[offset]</tt>, up to the next
+     * <tt>srcs[offset+1].remaining()</tt> bytes are written from buffer
+     * <tt>srcs[offset+1]</tt>, and so forth, until the entire byte sequence is
+     * written.  As many bytes as possible are written from each buffer, hence
+     * the final position of each updated buffer, except the last updated
+     * buffer, is guaranteed to be equal to that buffer's limit. The underlying
+     * operating system may impose a limit on the number of buffers that may be
+     * used in an I/O operation. Where the number of buffers (with bytes
+     * remaining), exceeds this limit, then the I/O operation is performed with
+     * the maximum number of buffers allowed by the operating system.
+     *
+     * <p> If a timeout is specified and the timeout elapses before the operation
+     * completes then it completes with the exception {@link
+     * InterruptedByTimeoutException}. Where a timeout occurs, and the
+     * implementation cannot guarantee that bytes have not been written, or will
+     * not be written to the channel from the given buffers, then further attempts
+     * to write to the channel will cause an unspecific runtime exception to be
+     * thrown.
+     *
+     * @param   <A>
+     *          The type of the attachment
+     * @param   srcs
+     *          The buffers from which bytes are to be retrieved
+     * @param   offset
+     *          The offset within the buffer array of the first buffer from which
+     *          bytes are to be retrieved; must be non-negative and no larger
+     *          than {@code srcs.length}
+     * @param   length
+     *          The maximum number of buffers to be accessed; must be non-negative
+     *          and no larger than {@code srcs.length - offset}
+     * @param   timeout
+     *          The maximum time for the I/O operation to complete
+     * @param   unit
+     *          The time unit of the {@code timeout} argument
+     * @param   attachment
+     *          The object to attach to the I/O operation; can be {@code null}
+     * @param   handler
+     *          The handler for consuming the result
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the pre-conditions for the {@code offset}  and {@code length}
+     *          parameter aren't met
+     * @throws  WritePendingException
+     *          If a write operation is already in progress on this channel
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ShutdownChannelGroupException
+     *          If the channel group has terminated
+     */
+    public abstract <A> void write(ByteBuffer[] srcs,
+                                   int offset,
+                                   int length,
+                                   long timeout,
+                                   TimeUnit unit,
+                                   A attachment,
+                                   CompletionHandler<Long,? super A> handler);
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * If there is a security manager set, its {@code checkConnect} method is
+     * called with the local address and {@code -1} as its arguments to see
+     * if the operation is allowed. If the operation is not allowed,
+     * a {@code SocketAddress} representing the
+     * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+     * local port of the channel's socket is returned.
+     *
+     * @return  The {@code SocketAddress} that the socket is bound to, or the
+     *          {@code SocketAddress} representing the loopback address if
+     *          denied by the security manager, or {@code null} if the
+     *          channel's socket is not bound
+     *
+     * @throws  ClosedChannelException     {@inheritDoc}
+     * @throws  IOException                {@inheritDoc}
+     */
+    public abstract SocketAddress getLocalAddress() throws IOException;
+}
diff --git a/java/nio/channels/ByteChannel.java b/java/nio/channels/ByteChannel.java
new file mode 100644
index 0000000..85d5275
--- /dev/null
+++ b/java/nio/channels/ByteChannel.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2000, 2001, 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.nio.channels;
+
+import java.io.IOException;
+
+
+/**
+ * A channel that can read and write bytes.  This interface simply unifies
+ * {@link ReadableByteChannel} and {@link WritableByteChannel}; it does not
+ * specify any new operations.
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface ByteChannel
+    extends ReadableByteChannel, WritableByteChannel
+{
+
+}
diff --git a/java/nio/channels/CancelledKeyException.java b/java/nio/channels/CancelledKeyException.java
new file mode 100644
index 0000000..b5306f0
--- /dev/null
+++ b/java/nio/channels/CancelledKeyException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to use
+ * a selection key that is no longer valid.
+ *
+ * @since 1.4
+ */
+
+public class CancelledKeyException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = -8438032138028814268L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public CancelledKeyException() { }
+
+}
diff --git a/java/nio/channels/Channel.java b/java/nio/channels/Channel.java
new file mode 100644
index 0000000..663d0e0
--- /dev/null
+++ b/java/nio/channels/Channel.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels;
+
+import java.io.IOException;
+import java.io.Closeable;
+
+
+/**
+ * A nexus for I/O operations.
+ *
+ * <p> A channel represents an open connection to an entity such as a hardware
+ * device, a file, a network socket, or a program component that is capable of
+ * performing one or more distinct I/O operations, for example reading or
+ * writing.
+ *
+ * <p> A channel is either open or closed.  A channel is open upon creation,
+ * and once closed it remains closed.  Once a channel is closed, any attempt to
+ * invoke an I/O operation upon it will cause a {@link ClosedChannelException}
+ * to be thrown.  Whether or not a channel is open may be tested by invoking
+ * its {@link #isOpen isOpen} method.
+ *
+ * <p> Channels are, in general, intended to be safe for multithreaded access
+ * as described in the specifications of the interfaces and classes that extend
+ * and implement this interface.
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface Channel extends Closeable {
+
+    /**
+     * Tells whether or not this channel is open.
+     *
+     * @return <tt>true</tt> if, and only if, this channel is open
+     */
+    public boolean isOpen();
+
+    /**
+     * Closes this channel.
+     *
+     * <p> After a channel is closed, any further attempt to invoke I/O
+     * operations upon it will cause a {@link ClosedChannelException} to be
+     * thrown.
+     *
+     * <p> If this channel is already closed then invoking this method has no
+     * effect.
+     *
+     * <p> This method may be invoked at any time.  If some other thread has
+     * already invoked it, however, then another invocation will block until
+     * the first invocation is complete, after which it will return without
+     * effect. </p>
+     *
+     * @throws  IOException  If an I/O error occurs
+     */
+    public void close() throws IOException;
+
+}
diff --git a/java/nio/channels/Channels.java b/java/nio/channels/Channels.java
new file mode 100644
index 0000000..1d11262
--- /dev/null
+++ b/java/nio/channels/Channels.java
@@ -0,0 +1,610 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.UnsupportedCharsetException;
+import java.nio.channels.spi.AbstractInterruptibleChannel;
+import java.util.concurrent.ExecutionException;
+import sun.nio.ch.ChannelInputStream;
+import sun.nio.cs.StreamDecoder;
+import sun.nio.cs.StreamEncoder;
+
+
+/**
+ * Utility methods for channels and streams.
+ *
+ * <p> This class defines static methods that support the interoperation of the
+ * stream classes of the <tt>{@link java.io}</tt> package with the channel
+ * classes of this package.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author Mike McCloskey
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public final class Channels {
+
+    private Channels() { }              // No instantiation
+
+    private static void checkNotNull(Object o, String name) {
+        if (o == null)
+            throw new NullPointerException("\"" + name + "\" is null!");
+    }
+
+    /**
+     * Write all remaining bytes in buffer to the given channel.
+     * If the channel is selectable then it must be configured blocking.
+     */
+    private static void writeFullyImpl(WritableByteChannel ch, ByteBuffer bb)
+        throws IOException
+    {
+        while (bb.remaining() > 0) {
+            int n = ch.write(bb);
+            if (n <= 0)
+                throw new RuntimeException("no bytes written");
+        }
+    }
+
+    /**
+     * Write all remaining bytes in buffer to the given channel.
+     *
+     * @throws  IllegalBlockingModeException
+     *          If the channel is selectable and configured non-blocking.
+     */
+    private static void writeFully(WritableByteChannel ch, ByteBuffer bb)
+        throws IOException
+    {
+        if (ch instanceof SelectableChannel) {
+            SelectableChannel sc = (SelectableChannel)ch;
+            synchronized (sc.blockingLock()) {
+                if (!sc.isBlocking())
+                    throw new IllegalBlockingModeException();
+                writeFullyImpl(ch, bb);
+            }
+        } else {
+            writeFullyImpl(ch, bb);
+        }
+    }
+
+    // -- Byte streams from channels --
+
+    /**
+     * Constructs a stream that reads bytes from the given channel.
+     *
+     * <p> The <tt>read</tt> methods of the resulting stream will throw an
+     * {@link IllegalBlockingModeException} if invoked while the underlying
+     * channel is in non-blocking mode.  The stream will not be buffered, and
+     * it will not support the {@link InputStream#mark mark} or {@link
+     * InputStream#reset reset} methods.  The stream will be safe for access by
+     * multiple concurrent threads.  Closing the stream will in turn cause the
+     * channel to be closed.  </p>
+     *
+     * @param  ch
+     *         The channel from which bytes will be read
+     *
+     * @return  A new input stream
+     */
+    public static InputStream newInputStream(ReadableByteChannel ch) {
+        checkNotNull(ch, "ch");
+        return new sun.nio.ch.ChannelInputStream(ch);
+    }
+
+    /**
+     * Constructs a stream that writes bytes to the given channel.
+     *
+     * <p> The <tt>write</tt> methods of the resulting stream will throw an
+     * {@link IllegalBlockingModeException} if invoked while the underlying
+     * channel is in non-blocking mode.  The stream will not be buffered.  The
+     * stream will be safe for access by multiple concurrent threads.  Closing
+     * the stream will in turn cause the channel to be closed.  </p>
+     *
+     * @param  ch
+     *         The channel to which bytes will be written
+     *
+     * @return  A new output stream
+     */
+    public static OutputStream newOutputStream(final WritableByteChannel ch) {
+        checkNotNull(ch, "ch");
+
+        return new OutputStream() {
+
+                private ByteBuffer bb = null;
+                private byte[] bs = null;       // Invoker's previous array
+                private byte[] b1 = null;
+
+                public synchronized void write(int b) throws IOException {
+                   if (b1 == null)
+                        b1 = new byte[1];
+                    b1[0] = (byte)b;
+                    this.write(b1);
+                }
+
+                public synchronized void write(byte[] bs, int off, int len)
+                    throws IOException
+                {
+                    if ((off < 0) || (off > bs.length) || (len < 0) ||
+                        ((off + len) > bs.length) || ((off + len) < 0)) {
+                        throw new IndexOutOfBoundsException();
+                    } else if (len == 0) {
+                        return;
+                    }
+                    ByteBuffer bb = ((this.bs == bs)
+                                     ? this.bb
+                                     : ByteBuffer.wrap(bs));
+                    bb.limit(Math.min(off + len, bb.capacity()));
+                    bb.position(off);
+                    this.bb = bb;
+                    this.bs = bs;
+                    Channels.writeFully(ch, bb);
+                }
+
+                public void close() throws IOException {
+                    ch.close();
+                }
+
+            };
+    }
+
+    /**
+     * Constructs a stream that reads bytes from the given channel.
+     *
+     * <p> The stream will not be buffered, and it will not support the {@link
+     * InputStream#mark mark} or {@link InputStream#reset reset} methods.  The
+     * stream will be safe for access by multiple concurrent threads.  Closing
+     * the stream will in turn cause the channel to be closed.  </p>
+     *
+     * @param  ch
+     *         The channel from which bytes will be read
+     *
+     * @return  A new input stream
+     *
+     * @since 1.7
+     */
+    public static InputStream newInputStream(final AsynchronousByteChannel ch) {
+        checkNotNull(ch, "ch");
+        return new InputStream() {
+
+            private ByteBuffer bb = null;
+            private byte[] bs = null;           // Invoker's previous array
+            private byte[] b1 = null;
+
+            @Override
+            public synchronized int read() throws IOException {
+                if (b1 == null)
+                    b1 = new byte[1];
+                int n = this.read(b1);
+                if (n == 1)
+                    return b1[0] & 0xff;
+                return -1;
+            }
+
+            @Override
+            public synchronized int read(byte[] bs, int off, int len)
+                throws IOException
+            {
+                if ((off < 0) || (off > bs.length) || (len < 0) ||
+                    ((off + len) > bs.length) || ((off + len) < 0)) {
+                    throw new IndexOutOfBoundsException();
+                } else if (len == 0)
+                    return 0;
+
+                ByteBuffer bb = ((this.bs == bs)
+                                 ? this.bb
+                                 : ByteBuffer.wrap(bs));
+                bb.position(off);
+                bb.limit(Math.min(off + len, bb.capacity()));
+                this.bb = bb;
+                this.bs = bs;
+
+                boolean interrupted = false;
+                try {
+                    for (;;) {
+                        try {
+                            return ch.read(bb).get();
+                        } catch (ExecutionException ee) {
+                            throw new IOException(ee.getCause());
+                        } catch (InterruptedException ie) {
+                            interrupted = true;
+                        }
+                    }
+                } finally {
+                    if (interrupted)
+                        Thread.currentThread().interrupt();
+                }
+            }
+
+            @Override
+            public void close() throws IOException {
+                ch.close();
+            }
+        };
+    }
+
+    /**
+     * Constructs a stream that writes bytes to the given channel.
+     *
+     * <p> The stream will not be buffered. The stream will be safe for access
+     * by multiple concurrent threads.  Closing the stream will in turn cause
+     * the channel to be closed.  </p>
+     *
+     * @param  ch
+     *         The channel to which bytes will be written
+     *
+     * @return  A new output stream
+     *
+     * @since 1.7
+     */
+    public static OutputStream newOutputStream(final AsynchronousByteChannel ch) {
+        checkNotNull(ch, "ch");
+        return new OutputStream() {
+
+            private ByteBuffer bb = null;
+            private byte[] bs = null;   // Invoker's previous array
+            private byte[] b1 = null;
+
+            @Override
+            public synchronized void write(int b) throws IOException {
+               if (b1 == null)
+                    b1 = new byte[1];
+                b1[0] = (byte)b;
+                this.write(b1);
+            }
+
+            @Override
+            public synchronized void write(byte[] bs, int off, int len)
+                throws IOException
+            {
+                if ((off < 0) || (off > bs.length) || (len < 0) ||
+                    ((off + len) > bs.length) || ((off + len) < 0)) {
+                    throw new IndexOutOfBoundsException();
+                } else if (len == 0) {
+                    return;
+                }
+                ByteBuffer bb = ((this.bs == bs)
+                                 ? this.bb
+                                 : ByteBuffer.wrap(bs));
+                bb.limit(Math.min(off + len, bb.capacity()));
+                bb.position(off);
+                this.bb = bb;
+                this.bs = bs;
+
+                boolean interrupted = false;
+                try {
+                    while (bb.remaining() > 0) {
+                        try {
+                            ch.write(bb).get();
+                        } catch (ExecutionException ee) {
+                            throw new IOException(ee.getCause());
+                        } catch (InterruptedException ie) {
+                            interrupted = true;
+                        }
+                    }
+                } finally {
+                    if (interrupted)
+                        Thread.currentThread().interrupt();
+                }
+            }
+
+            @Override
+            public void close() throws IOException {
+                ch.close();
+            }
+        };
+    }
+
+
+    // -- Channels from streams --
+
+    /**
+     * Constructs a channel that reads bytes from the given stream.
+     *
+     * <p> The resulting channel will not be buffered; it will simply redirect
+     * its I/O operations to the given stream.  Closing the channel will in
+     * turn cause the stream to be closed.  </p>
+     *
+     * @param  in
+     *         The stream from which bytes are to be read
+     *
+     * @return  A new readable byte channel
+     */
+    public static ReadableByteChannel newChannel(final InputStream in) {
+        checkNotNull(in, "in");
+
+        if (in instanceof FileInputStream &&
+            FileInputStream.class.equals(in.getClass())) {
+            return ((FileInputStream)in).getChannel();
+        }
+
+        return new ReadableByteChannelImpl(in);
+    }
+
+    private static class ReadableByteChannelImpl
+        extends AbstractInterruptibleChannel    // Not really interruptible
+        implements ReadableByteChannel
+    {
+        InputStream in;
+        private static final int TRANSFER_SIZE = 8192;
+        private byte buf[] = new byte[0];
+        private boolean open = true;
+        private Object readLock = new Object();
+
+        ReadableByteChannelImpl(InputStream in) {
+            this.in = in;
+        }
+
+        public int read(ByteBuffer dst) throws IOException {
+            int len = dst.remaining();
+            int totalRead = 0;
+            int bytesRead = 0;
+            synchronized (readLock) {
+                while (totalRead < len) {
+                    int bytesToRead = Math.min((len - totalRead),
+                                               TRANSFER_SIZE);
+                    if (buf.length < bytesToRead)
+                        buf = new byte[bytesToRead];
+                    if ((totalRead > 0) && !(in.available() > 0))
+                        break; // block at most once
+                    try {
+                        begin();
+                        bytesRead = in.read(buf, 0, bytesToRead);
+                    } finally {
+                        end(bytesRead > 0);
+                    }
+                    if (bytesRead < 0)
+                        break;
+                    else
+                        totalRead += bytesRead;
+                    dst.put(buf, 0, bytesRead);
+                }
+                if ((bytesRead < 0) && (totalRead == 0))
+                    return -1;
+
+                return totalRead;
+            }
+        }
+
+        protected void implCloseChannel() throws IOException {
+            in.close();
+            open = false;
+        }
+    }
+
+
+    /**
+     * Constructs a channel that writes bytes to the given stream.
+     *
+     * <p> The resulting channel will not be buffered; it will simply redirect
+     * its I/O operations to the given stream.  Closing the channel will in
+     * turn cause the stream to be closed.  </p>
+     *
+     * @param  out
+     *         The stream to which bytes are to be written
+     *
+     * @return  A new writable byte channel
+     */
+    public static WritableByteChannel newChannel(final OutputStream out) {
+        checkNotNull(out, "out");
+        return new WritableByteChannelImpl(out);
+    }
+
+    private static class WritableByteChannelImpl
+        extends AbstractInterruptibleChannel    // Not really interruptible
+        implements WritableByteChannel
+    {
+        OutputStream out;
+        private static final int TRANSFER_SIZE = 8192;
+        private byte buf[] = new byte[0];
+        private boolean open = true;
+        private Object writeLock = new Object();
+
+        WritableByteChannelImpl(OutputStream out) {
+            this.out = out;
+        }
+
+        public int write(ByteBuffer src) throws IOException {
+            int len = src.remaining();
+            int totalWritten = 0;
+            synchronized (writeLock) {
+                while (totalWritten < len) {
+                    int bytesToWrite = Math.min((len - totalWritten),
+                                                TRANSFER_SIZE);
+                    if (buf.length < bytesToWrite)
+                        buf = new byte[bytesToWrite];
+                    src.get(buf, 0, bytesToWrite);
+                    try {
+                        begin();
+                        out.write(buf, 0, bytesToWrite);
+                    } finally {
+                        end(bytesToWrite > 0);
+                    }
+                    totalWritten += bytesToWrite;
+                }
+                return totalWritten;
+            }
+        }
+
+        protected void implCloseChannel() throws IOException {
+            out.close();
+            open = false;
+        }
+    }
+
+
+    // -- Character streams from channels --
+
+    /**
+     * Constructs a reader that decodes bytes from the given channel using the
+     * given decoder.
+     *
+     * <p> The resulting stream will contain an internal input buffer of at
+     * least <tt>minBufferCap</tt> bytes.  The stream's <tt>read</tt> methods
+     * will, as needed, fill the buffer by reading bytes from the underlying
+     * channel; if the channel is in non-blocking mode when bytes are to be
+     * read then an {@link IllegalBlockingModeException} will be thrown.  The
+     * resulting stream will not otherwise be buffered, and it will not support
+     * the {@link Reader#mark mark} or {@link Reader#reset reset} methods.
+     * Closing the stream will in turn cause the channel to be closed.  </p>
+     *
+     * @param  ch
+     *         The channel from which bytes will be read
+     *
+     * @param  dec
+     *         The charset decoder to be used
+     *
+     * @param  minBufferCap
+     *         The minimum capacity of the internal byte buffer,
+     *         or <tt>-1</tt> if an implementation-dependent
+     *         default capacity is to be used
+     *
+     * @return  A new reader
+     */
+    public static Reader newReader(ReadableByteChannel ch,
+                                   CharsetDecoder dec,
+                                   int minBufferCap)
+    {
+        checkNotNull(ch, "ch");
+        return StreamDecoder.forDecoder(ch, dec.reset(), minBufferCap);
+    }
+
+    /**
+     * Constructs a reader that decodes bytes from the given channel according
+     * to the named charset.
+     *
+     * <p> An invocation of this method of the form
+     *
+     * <blockquote><pre>
+     * Channels.newReader(ch, csname)</pre></blockquote>
+     *
+     * behaves in exactly the same way as the expression
+     *
+     * <blockquote><pre>
+     * Channels.newReader(ch,
+     *                    Charset.forName(csName)
+     *                        .newDecoder(),
+     *                    -1);</pre></blockquote>
+     *
+     * @param  ch
+     *         The channel from which bytes will be read
+     *
+     * @param  csName
+     *         The name of the charset to be used
+     *
+     * @return  A new reader
+     *
+     * @throws  UnsupportedCharsetException
+     *          If no support for the named charset is available
+     *          in this instance of the Java virtual machine
+     */
+    public static Reader newReader(ReadableByteChannel ch,
+                                   String csName)
+    {
+        checkNotNull(csName, "csName");
+        return newReader(ch, Charset.forName(csName).newDecoder(), -1);
+    }
+
+    /**
+     * Constructs a writer that encodes characters using the given encoder and
+     * writes the resulting bytes to the given channel.
+     *
+     * <p> The resulting stream will contain an internal output buffer of at
+     * least <tt>minBufferCap</tt> bytes.  The stream's <tt>write</tt> methods
+     * will, as needed, flush the buffer by writing bytes to the underlying
+     * channel; if the channel is in non-blocking mode when bytes are to be
+     * written then an {@link IllegalBlockingModeException} will be thrown.
+     * The resulting stream will not otherwise be buffered.  Closing the stream
+     * will in turn cause the channel to be closed.  </p>
+     *
+     * @param  ch
+     *         The channel to which bytes will be written
+     *
+     * @param  enc
+     *         The charset encoder to be used
+     *
+     * @param  minBufferCap
+     *         The minimum capacity of the internal byte buffer,
+     *         or <tt>-1</tt> if an implementation-dependent
+     *         default capacity is to be used
+     *
+     * @return  A new writer
+     */
+    public static Writer newWriter(final WritableByteChannel ch,
+                                   final CharsetEncoder enc,
+                                   final int minBufferCap)
+    {
+        checkNotNull(ch, "ch");
+        return StreamEncoder.forEncoder(ch, enc.reset(), minBufferCap);
+    }
+
+    /**
+     * Constructs a writer that encodes characters according to the named
+     * charset and writes the resulting bytes to the given channel.
+     *
+     * <p> An invocation of this method of the form
+     *
+     * <blockquote><pre>
+     * Channels.newWriter(ch, csname)</pre></blockquote>
+     *
+     * behaves in exactly the same way as the expression
+     *
+     * <blockquote><pre>
+     * Channels.newWriter(ch,
+     *                    Charset.forName(csName)
+     *                        .newEncoder(),
+     *                    -1);</pre></blockquote>
+     *
+     * @param  ch
+     *         The channel to which bytes will be written
+     *
+     * @param  csName
+     *         The name of the charset to be used
+     *
+     * @return  A new writer
+     *
+     * @throws  UnsupportedCharsetException
+     *          If no support for the named charset is available
+     *          in this instance of the Java virtual machine
+     */
+    public static Writer newWriter(WritableByteChannel ch,
+                                   String csName)
+    {
+        checkNotNull(csName, "csName");
+        return newWriter(ch, Charset.forName(csName).newEncoder(), -1);
+    }
+}
diff --git a/java/nio/channels/ClosedByInterruptException.java b/java/nio/channels/ClosedByInterruptException.java
new file mode 100644
index 0000000..848ee61
--- /dev/null
+++ b/java/nio/channels/ClosedByInterruptException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Checked exception received by a thread when another thread interrupts it
+ * while it is blocked in an I/O operation upon a channel.  Before this
+ * exception is thrown the channel will have been closed and the interrupt
+ * status of the previously-blocked thread will have been set.
+ *
+ * @since 1.4
+ */
+
+public class ClosedByInterruptException
+    extends AsynchronousCloseException
+{
+
+    private static final long serialVersionUID = -4488191543534286750L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ClosedByInterruptException() { }
+
+}
diff --git a/java/nio/channels/ClosedChannelException.java b/java/nio/channels/ClosedChannelException.java
new file mode 100644
index 0000000..a9a2277
--- /dev/null
+++ b/java/nio/channels/ClosedChannelException.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Checked exception thrown when an attempt is made to invoke or complete an
+ * I/O operation upon channel that is closed, or at least closed to that
+ * operation.  That this exception is thrown does not necessarily imply that
+ * the channel is completely closed.  A socket channel whose write half has
+ * been shut down, for example, may still be open for reading.
+ *
+ * @since 1.4
+ */
+
+public class ClosedChannelException
+    extends java.io.IOException
+{
+
+    private static final long serialVersionUID = 882777185433553857L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ClosedChannelException() { }
+
+}
diff --git a/java/nio/channels/ClosedSelectorException.java b/java/nio/channels/ClosedSelectorException.java
new file mode 100644
index 0000000..f3168c2
--- /dev/null
+++ b/java/nio/channels/ClosedSelectorException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an I/O
+ * operation upon a closed selector.
+ *
+ * @since 1.4
+ */
+
+public class ClosedSelectorException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = 6466297122317847835L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ClosedSelectorException() { }
+
+}
diff --git a/java/nio/channels/CompletionHandler.java b/java/nio/channels/CompletionHandler.java
new file mode 100644
index 0000000..2574dbf
--- /dev/null
+++ b/java/nio/channels/CompletionHandler.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.channels;
+
+/**
+ * A handler for consuming the result of an asynchronous I/O operation.
+ *
+ * <p> The asynchronous channels defined in this package allow a completion
+ * handler to be specified to consume the result of an asynchronous operation.
+ * The {@link #completed completed} method is invoked when the I/O operation
+ * completes successfully. The {@link #failed failed} method is invoked if the
+ * I/O operations fails. The implementations of these methods should complete
+ * in a timely manner so as to avoid keeping the invoking thread from dispatching
+ * to other completion handlers.
+ *
+ * @param   <V>     The result type of the I/O operation
+ * @param   <A>     The type of the object attached to the I/O operation
+ *
+ * @since 1.7
+ */
+
+public interface CompletionHandler<V,A> {
+
+    /**
+     * Invoked when an operation has completed.
+     *
+     * @param   result
+     *          The result of the I/O operation.
+     * @param   attachment
+     *          The object attached to the I/O operation when it was initiated.
+     */
+    void completed(V result, A attachment);
+
+    /**
+     * Invoked when an operation fails.
+     *
+     * @param   exc
+     *          The exception to indicate why the I/O operation failed
+     * @param   attachment
+     *          The object attached to the I/O operation when it was initiated.
+     */
+    void failed(Throwable exc, A attachment);
+}
diff --git a/java/nio/channels/ConnectionPendingException.java b/java/nio/channels/ConnectionPendingException.java
new file mode 100644
index 0000000..c43927e
--- /dev/null
+++ b/java/nio/channels/ConnectionPendingException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to connect a {@link
+ * SocketChannel} for which a non-blocking connection operation is already in
+ * progress.
+ *
+ * @since 1.4
+ */
+
+public class ConnectionPendingException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = 2008393366501760879L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ConnectionPendingException() { }
+
+}
diff --git a/java/nio/channels/DatagramChannel.java b/java/nio/channels/DatagramChannel.java
new file mode 100644
index 0000000..b85c98c
--- /dev/null
+++ b/java/nio/channels/DatagramChannel.java
@@ -0,0 +1,592 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels;
+
+import java.io.IOException;
+import java.net.ProtocolFamily;
+import java.net.DatagramSocket;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * A selectable channel for datagram-oriented sockets.
+ *
+ * <p> A datagram channel is created by invoking one of the {@link #open open} methods
+ * of this class. It is not possible to create a channel for an arbitrary,
+ * pre-existing datagram socket. A newly-created datagram channel is open but not
+ * connected. A datagram channel need not be connected in order for the {@link #send
+ * send} and {@link #receive receive} methods to be used.  A datagram channel may be
+ * connected, by invoking its {@link #connect connect} method, in order to
+ * avoid the overhead of the security checks are otherwise performed as part of
+ * every send and receive operation.  A datagram channel must be connected in
+ * order to use the {@link #read(java.nio.ByteBuffer) read} and {@link
+ * #write(java.nio.ByteBuffer) write} methods, since those methods do not
+ * accept or return socket addresses.
+ *
+ * <p> Once connected, a datagram channel remains connected until it is
+ * disconnected or closed.  Whether or not a datagram channel is connected may
+ * be determined by invoking its {@link #isConnected isConnected} method.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. A datagram channel to an Internet Protocol socket supports
+ * the following options:
+ * <blockquote>
+ * <table border summary="Socket options">
+ *   <tr>
+ *     <th>Option Name</th>
+ *     <th>Description</th>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td>
+ *     <td> The size of the socket send buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> The size of the socket receive buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> Re-use address </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_BROADCAST SO_BROADCAST} </td>
+ *     <td> Allow transmission of broadcast datagrams </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#IP_TOS IP_TOS} </td>
+ *     <td> The Type of Service (ToS) octet in the Internet Protocol (IP) header </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_IF IP_MULTICAST_IF} </td>
+ *     <td> The network interface for Internet Protocol (IP) multicast datagrams </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_TTL
+ *       IP_MULTICAST_TTL} </td>
+ *     <td> The <em>time-to-live</em> for Internet Protocol (IP) multicast
+ *       datagrams </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#IP_MULTICAST_LOOP
+ *       IP_MULTICAST_LOOP} </td>
+ *     <td> Loopback for Internet Protocol (IP) multicast datagrams </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <p> Datagram channels are safe for use by multiple concurrent threads.  They
+ * support concurrent reading and writing, though at most one thread may be
+ * reading and at most one thread may be writing at any given time.  </p>
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class DatagramChannel
+    extends AbstractSelectableChannel
+    implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, MulticastChannel
+{
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @param  provider
+     *         The provider that created this channel
+     */
+    protected DatagramChannel(SelectorProvider provider) {
+        super(provider);
+    }
+
+    /**
+     * Opens a datagram channel.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * java.nio.channels.spi.SelectorProvider#openDatagramChannel()
+     * openDatagramChannel} method of the system-wide default {@link
+     * java.nio.channels.spi.SelectorProvider} object.  The channel will not be
+     * connected.
+     *
+     * <p> The {@link ProtocolFamily ProtocolFamily} of the channel's socket
+     * is platform (and possibly configuration) dependent and therefore unspecified.
+     * The {@link #open(ProtocolFamily) open} allows the protocol family to be
+     * selected when opening a datagram channel, and should be used to open
+     * datagram channels that are intended for Internet Protocol multicasting.
+     *
+     * @return  A new datagram channel
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static DatagramChannel open() throws IOException {
+        return SelectorProvider.provider().openDatagramChannel();
+    }
+
+    /**
+     * Opens a datagram channel.
+     *
+     * <p> The {@code family} parameter is used to specify the {@link
+     * ProtocolFamily}. If the datagram channel is to be used for IP multicasting
+     * then this should correspond to the address type of the multicast groups
+     * that this channel will join.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * java.nio.channels.spi.SelectorProvider#openDatagramChannel(ProtocolFamily)
+     * openDatagramChannel} method of the system-wide default {@link
+     * java.nio.channels.spi.SelectorProvider} object.  The channel will not be
+     * connected.
+     *
+     * @param   family
+     *          The protocol family
+     *
+     * @return  A new datagram channel
+     *
+     * @throws  UnsupportedOperationException
+     *          If the specified protocol family is not supported. For example,
+     *          suppose the parameter is specified as {@link
+     *          java.net.StandardProtocolFamily#INET6 StandardProtocolFamily.INET6}
+     *          but IPv6 is not enabled on the platform.
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @since   1.7
+     */
+    public static DatagramChannel open(ProtocolFamily family) throws IOException {
+        return SelectorProvider.provider().openDatagramChannel(family);
+    }
+
+    /**
+     * Returns an operation set identifying this channel's supported
+     * operations.
+     *
+     * <p> Datagram channels support reading and writing, so this method
+     * returns <tt>(</tt>{@link SelectionKey#OP_READ} <tt>|</tt>&nbsp;{@link
+     * SelectionKey#OP_WRITE}<tt>)</tt>.  </p>
+     *
+     * @return  The valid-operation set
+     */
+    public final int validOps() {
+        return (SelectionKey.OP_READ
+                | SelectionKey.OP_WRITE);
+    }
+
+
+    // -- Socket-specific operations --
+
+    /**
+     * @throws  AlreadyBoundException               {@inheritDoc}
+     * @throws  UnsupportedAddressTypeException     {@inheritDoc}
+     * @throws  ClosedChannelException              {@inheritDoc}
+     * @throws  IOException                         {@inheritDoc}
+     * @throws  SecurityException
+     *          If a security manager has been installed and its {@link
+     *          SecurityManager#checkListen checkListen} method denies the
+     *          operation
+     *
+     * @since 1.7
+     */
+    public abstract DatagramChannel bind(SocketAddress local)
+        throws IOException;
+
+    /**
+     * @throws  UnsupportedOperationException           {@inheritDoc}
+     * @throws  IllegalArgumentException                {@inheritDoc}
+     * @throws  ClosedChannelException                  {@inheritDoc}
+     * @throws  IOException                             {@inheritDoc}
+     *
+     * @since 1.7
+     */
+    public abstract <T> DatagramChannel setOption(SocketOption<T> name, T value)
+        throws IOException;
+
+    /**
+     * Retrieves a datagram socket associated with this channel.
+     *
+     * <p> The returned object will not declare any public methods that are not
+     * declared in the {@link java.net.DatagramSocket} class.  </p>
+     *
+     * @return  A datagram socket associated with this channel
+     */
+    public abstract DatagramSocket socket();
+
+    /**
+     * Tells whether or not this channel's socket is connected.
+     *
+     * @return  {@code true} if, and only if, this channel's socket
+     *          is {@link #isOpen open} and connected
+     */
+    public abstract boolean isConnected();
+
+    /**
+     * Connects this channel's socket.
+     *
+     * <p> The channel's socket is configured so that it only receives
+     * datagrams from, and sends datagrams to, the given remote <i>peer</i>
+     * address.  Once connected, datagrams may not be received from or sent to
+     * any other address.  A datagram socket remains connected until it is
+     * explicitly disconnected or until it is closed.
+     *
+     * <p> This method performs exactly the same security checks as the {@link
+     * java.net.DatagramSocket#connect connect} method of the {@link
+     * java.net.DatagramSocket} class.  That is, if a security manager has been
+     * installed then this method verifies that its {@link
+     * java.lang.SecurityManager#checkAccept checkAccept} and {@link
+     * java.lang.SecurityManager#checkConnect checkConnect} methods permit
+     * datagrams to be received from and sent to, respectively, the given
+     * remote address.
+     *
+     * <p> This method may be invoked at any time.  It will not have any effect
+     * on read or write operations that are already in progress at the moment
+     * that it is invoked. If this channel's socket is not bound then this method
+     * will first cause the socket to be bound to an address that is assigned
+     * automatically, as if invoking the {@link #bind bind} method with a
+     * parameter of {@code null}. </p>
+     *
+     * @param  remote
+     *         The remote address to which this channel is to be connected
+     *
+     * @return  This datagram channel
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the connect operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the connect operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed
+     *          and it does not permit access to the given remote address
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract DatagramChannel connect(SocketAddress remote)
+        throws IOException;
+
+    /**
+     * Disconnects this channel's socket.
+     *
+     * <p> The channel's socket is configured so that it can receive datagrams
+     * from, and sends datagrams to, any remote address so long as the security
+     * manager, if installed, permits it.
+     *
+     * <p> This method may be invoked at any time.  It will not have any effect
+     * on read or write operations that are already in progress at the moment
+     * that it is invoked.
+     *
+     * <p> If this channel's socket is not connected, or if the channel is
+     * closed, then invoking this method has no effect.  </p>
+     *
+     * @return  This datagram channel
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract DatagramChannel disconnect() throws IOException;
+
+    /**
+     * Returns the remote address to which this channel's socket is connected.
+     *
+     * @return  The remote address; {@code null} if the channel's socket is not
+     *          connected
+     *
+     * @throws  ClosedChannelException
+     *          If the channel is closed
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @since 1.7
+     */
+    public abstract SocketAddress getRemoteAddress() throws IOException;
+
+    /**
+     * Receives a datagram via this channel.
+     *
+     * <p> If a datagram is immediately available, or if this channel is in
+     * blocking mode and one eventually becomes available, then the datagram is
+     * copied into the given byte buffer and its source address is returned.
+     * If this channel is in non-blocking mode and a datagram is not
+     * immediately available then this method immediately returns
+     * <tt>null</tt>.
+     *
+     * <p> The datagram is transferred into the given byte buffer starting at
+     * its current position, as if by a regular {@link
+     * ReadableByteChannel#read(java.nio.ByteBuffer) read} operation.  If there
+     * are fewer bytes remaining in the buffer than are required to hold the
+     * datagram then the remainder of the datagram is silently discarded.
+     *
+     * <p> This method performs exactly the same security checks as the {@link
+     * java.net.DatagramSocket#receive receive} method of the {@link
+     * java.net.DatagramSocket} class.  That is, if the socket is not connected
+     * to a specific remote address and a security manager has been installed
+     * then for each datagram received this method verifies that the source's
+     * address and port number are permitted by the security manager's {@link
+     * java.lang.SecurityManager#checkAccept checkAccept} method.  The overhead
+     * of this security check can be avoided by first connecting the socket via
+     * the {@link #connect connect} method.
+     *
+     * <p> This method may be invoked at any time.  If another thread has
+     * already initiated a read operation upon this channel, however, then an
+     * invocation of this method will block until the first operation is
+     * complete. If this channel's socket is not bound then this method will
+     * first cause the socket to be bound to an address that is assigned
+     * automatically, as if invoking the {@link #bind bind} method with a
+     * parameter of {@code null}. </p>
+     *
+     * @param  dst
+     *         The buffer into which the datagram is to be transferred
+     *
+     * @return  The datagram's source address,
+     *          or <tt>null</tt> if this channel is in non-blocking mode
+     *          and no datagram was immediately available
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the read operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the read operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed
+     *          and it does not permit datagrams to be accepted
+     *          from the datagram's sender
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract SocketAddress receive(ByteBuffer dst) throws IOException;
+
+    /**
+     * Sends a datagram via this channel.
+     *
+     * <p> If this channel is in non-blocking mode and there is sufficient room
+     * in the underlying output buffer, or if this channel is in blocking mode
+     * and sufficient room becomes available, then the remaining bytes in the
+     * given buffer are transmitted as a single datagram to the given target
+     * address.
+     *
+     * <p> The datagram is transferred from the byte buffer as if by a regular
+     * {@link WritableByteChannel#write(java.nio.ByteBuffer) write} operation.
+     *
+     * <p> This method performs exactly the same security checks as the {@link
+     * java.net.DatagramSocket#send send} method of the {@link
+     * java.net.DatagramSocket} class.  That is, if the socket is not connected
+     * to a specific remote address and a security manager has been installed
+     * then for each datagram sent this method verifies that the target address
+     * and port number are permitted by the security manager's {@link
+     * java.lang.SecurityManager#checkConnect checkConnect} method.  The
+     * overhead of this security check can be avoided by first connecting the
+     * socket via the {@link #connect connect} method.
+     *
+     * <p> This method may be invoked at any time.  If another thread has
+     * already initiated a write operation upon this channel, however, then an
+     * invocation of this method will block until the first operation is
+     * complete. If this channel's socket is not bound then this method will
+     * first cause the socket to be bound to an address that is assigned
+     * automatically, as if by invoking the {@link #bind bind} method with a
+     * parameter of {@code null}. </p>
+     *
+     * @param  src
+     *         The buffer containing the datagram to be sent
+     *
+     * @param  target
+     *         The address to which the datagram is to be sent
+     *
+     * @return   The number of bytes sent, which will be either the number
+     *           of bytes that were remaining in the source buffer when this
+     *           method was invoked or, if this channel is non-blocking, may be
+     *           zero if there was insufficient room for the datagram in the
+     *           underlying output buffer
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the read operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the read operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed
+     *          and it does not permit datagrams to be sent
+     *          to the given address
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract int send(ByteBuffer src, SocketAddress target)
+        throws IOException;
+
+
+    // -- ByteChannel operations --
+
+    /**
+     * Reads a datagram from this channel.
+     *
+     * <p> This method may only be invoked if this channel's socket is
+     * connected, and it only accepts datagrams from the socket's peer.  If
+     * there are more bytes in the datagram than remain in the given buffer
+     * then the remainder of the datagram is silently discarded.  Otherwise
+     * this method behaves exactly as specified in the {@link
+     * ReadableByteChannel} interface.  </p>
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel's socket is not connected
+     */
+    public abstract int read(ByteBuffer dst) throws IOException;
+
+    /**
+     * Reads a datagram from this channel.
+     *
+     * <p> This method may only be invoked if this channel's socket is
+     * connected, and it only accepts datagrams from the socket's peer.  If
+     * there are more bytes in the datagram than remain in the given buffers
+     * then the remainder of the datagram is silently discarded.  Otherwise
+     * this method behaves exactly as specified in the {@link
+     * ScatteringByteChannel} interface.  </p>
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel's socket is not connected
+     */
+    public abstract long read(ByteBuffer[] dsts, int offset, int length)
+        throws IOException;
+
+    /**
+     * Reads a datagram from this channel.
+     *
+     * <p> This method may only be invoked if this channel's socket is
+     * connected, and it only accepts datagrams from the socket's peer.  If
+     * there are more bytes in the datagram than remain in the given buffers
+     * then the remainder of the datagram is silently discarded.  Otherwise
+     * this method behaves exactly as specified in the {@link
+     * ScatteringByteChannel} interface.  </p>
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel's socket is not connected
+     */
+    public final long read(ByteBuffer[] dsts) throws IOException {
+        return read(dsts, 0, dsts.length);
+    }
+
+    /**
+     * Writes a datagram to this channel.
+     *
+     * <p> This method may only be invoked if this channel's socket is
+     * connected, in which case it sends datagrams directly to the socket's
+     * peer.  Otherwise it behaves exactly as specified in the {@link
+     * WritableByteChannel} interface.  </p>
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel's socket is not connected
+     */
+    public abstract int write(ByteBuffer src) throws IOException;
+
+    /**
+     * Writes a datagram to this channel.
+     *
+     * <p> This method may only be invoked if this channel's socket is
+     * connected, in which case it sends datagrams directly to the socket's
+     * peer.  Otherwise it behaves exactly as specified in the {@link
+     * GatheringByteChannel} interface.  </p>
+     *
+     * @return   The number of bytes sent, which will be either the number
+     *           of bytes that were remaining in the source buffer when this
+     *           method was invoked or, if this channel is non-blocking, may be
+     *           zero if there was insufficient room for the datagram in the
+     *           underlying output buffer
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel's socket is not connected
+     */
+    public abstract long write(ByteBuffer[] srcs, int offset, int length)
+        throws IOException;
+
+    /**
+     * Writes a datagram to this channel.
+     *
+     * <p> This method may only be invoked if this channel's socket is
+     * connected, in which case it sends datagrams directly to the socket's
+     * peer.  Otherwise it behaves exactly as specified in the {@link
+     * GatheringByteChannel} interface.  </p>
+     *
+     * @return   The number of bytes sent, which will be either the number
+     *           of bytes that were remaining in the source buffer when this
+     *           method was invoked or, if this channel is non-blocking, may be
+     *           zero if there was insufficient room for the datagram in the
+     *           underlying output buffer
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel's socket is not connected
+     */
+    public final long write(ByteBuffer[] srcs) throws IOException {
+        return write(srcs, 0, srcs.length);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * If there is a security manager set, its {@code checkConnect} method is
+     * called with the local address and {@code -1} as its arguments to see
+     * if the operation is allowed. If the operation is not allowed,
+     * a {@code SocketAddress} representing the
+     * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+     * local port of the channel's socket is returned.
+     *
+     * @return  The {@code SocketAddress} that the socket is bound to, or the
+     *          {@code SocketAddress} representing the loopback address if
+     *          denied by the security manager, or {@code null} if the
+     *          channel's socket is not bound
+     *
+     * @throws  ClosedChannelException     {@inheritDoc}
+     * @throws  IOException                {@inheritDoc}
+     */
+    @Override
+    public abstract SocketAddress getLocalAddress() throws IOException;
+
+}
diff --git a/java/nio/channels/FileChannel.java b/java/nio/channels/FileChannel.java
new file mode 100644
index 0000000..a23f1c3
--- /dev/null
+++ b/java/nio/channels/FileChannel.java
@@ -0,0 +1,1158 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.spi.AbstractInterruptibleChannel;
+import java.nio.file.*;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.spi.*;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+
+/**
+ * A channel for reading, writing, mapping, and manipulating a file.
+ *
+ * <p> A file channel is a {@link SeekableByteChannel} that is connected to
+ * a file. It has a current <i>position</i> within its file which can
+ * be both {@link #position() <i>queried</i>} and {@link #position(long)
+ * <i>modified</i>}.  The file itself contains a variable-length sequence
+ * of bytes that can be read and written and whose current {@link #size
+ * <i>size</i>} can be queried.  The size of the file increases
+ * when bytes are written beyond its current size; the size of the file
+ * decreases when it is {@link #truncate <i>truncated</i>}.  The
+ * file may also have some associated <i>metadata</i> such as access
+ * permissions, content type, and last-modification time; this class does not
+ * define methods for metadata access.
+ *
+ * <p> In addition to the familiar read, write, and close operations of byte
+ * channels, this class defines the following file-specific operations: </p>
+ *
+ * <ul>
+ *
+ *   <li><p> Bytes may be {@link #read(ByteBuffer, long) read} or
+ *   {@link #write(ByteBuffer, long) <i>written</i>} at an absolute
+ *   position in a file in a way that does not affect the channel's current
+ *   position.  </p></li>
+ *
+ *   <li><p> A region of a file may be {@link #map <i>mapped</i>}
+ *   directly into memory; for large files this is often much more efficient
+ *   than invoking the usual <tt>read</tt> or <tt>write</tt> methods.
+ *   </p></li>
+ *
+ *   <li><p> Updates made to a file may be {@link #force <i>forced
+ *   out</i>} to the underlying storage device, ensuring that data are not
+ *   lost in the event of a system crash.  </p></li>
+ *
+ *   <li><p> Bytes can be transferred from a file {@link #transferTo <i>to
+ *   some other channel</i>}, and {@link #transferFrom <i>vice
+ *   versa</i>}, in a way that can be optimized by many operating systems
+ *   into a very fast transfer directly to or from the filesystem cache.
+ *   </p></li>
+ *
+ *   <li><p> A region of a file may be {@link FileLock <i>locked</i>}
+ *   against access by other programs.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> File channels are safe for use by multiple concurrent threads.  The
+ * {@link Channel#close close} method may be invoked at any time, as specified
+ * by the {@link Channel} interface.  Only one operation that involves the
+ * channel's position or can change its file's size may be in progress at any
+ * given time; attempts to initiate a second such operation while the first is
+ * still in progress will block until the first operation completes.  Other
+ * operations, in particular those that take an explicit position, may proceed
+ * concurrently; whether they in fact do so is dependent upon the underlying
+ * implementation and is therefore unspecified.
+ *
+ * <p> The view of a file provided by an instance of this class is guaranteed
+ * to be consistent with other views of the same file provided by other
+ * instances in the same program.  The view provided by an instance of this
+ * class may or may not, however, be consistent with the views seen by other
+ * concurrently-running programs due to caching performed by the underlying
+ * operating system and delays induced by network-filesystem protocols.  This
+ * is true regardless of the language in which these other programs are
+ * written, and whether they are running on the same machine or on some other
+ * machine.  The exact nature of any such inconsistencies are system-dependent
+ * and are therefore unspecified.
+ *
+ * <p> A file channel is created by invoking one of the {@link #open open}
+ * methods defined by this class. A file channel can also be obtained from an
+ * existing {@link java.io.FileInputStream#getChannel FileInputStream}, {@link
+ * java.io.FileOutputStream#getChannel FileOutputStream}, or {@link
+ * java.io.RandomAccessFile#getChannel RandomAccessFile} object by invoking
+ * that object's <tt>getChannel</tt> method, which returns a file channel that
+ * is connected to the same underlying file. Where the file channel is obtained
+ * from an existing stream or random access file then the state of the file
+ * channel is intimately connected to that of the object whose <tt>getChannel</tt>
+ * method returned the channel.  Changing the channel's position, whether
+ * explicitly or by reading or writing bytes, will change the file position of
+ * the originating object, and vice versa. Changing the file's length via the
+ * file channel will change the length seen via the originating object, and vice
+ * versa.  Changing the file's content by writing bytes will change the content
+ * seen by the originating object, and vice versa.
+ *
+ * <a name="open-mode"></a> <p> At various points this class specifies that an
+ * instance that is "open for reading," "open for writing," or "open for
+ * reading and writing" is required.  A channel obtained via the {@link
+ * java.io.FileInputStream#getChannel getChannel} method of a {@link
+ * java.io.FileInputStream} instance will be open for reading.  A channel
+ * obtained via the {@link java.io.FileOutputStream#getChannel getChannel}
+ * method of a {@link java.io.FileOutputStream} instance will be open for
+ * writing.  Finally, a channel obtained via the {@link
+ * java.io.RandomAccessFile#getChannel getChannel} method of a {@link
+ * java.io.RandomAccessFile} instance will be open for reading if the instance
+ * was created with mode <tt>"r"</tt> and will be open for reading and writing
+ * if the instance was created with mode <tt>"rw"</tt>.
+ *
+ * <a name="append-mode"></a><p> A file channel that is open for writing may be in
+ * <i>append mode</i>, for example if it was obtained from a file-output stream
+ * that was created by invoking the {@link
+ * java.io.FileOutputStream#FileOutputStream(java.io.File,boolean)
+ * FileOutputStream(File,boolean)} constructor and passing <tt>true</tt> for
+ * the second parameter.  In this mode each invocation of a relative write
+ * operation first advances the position to the end of the file and then writes
+ * the requested data.  Whether the advancement of the position and the writing
+ * of the data are done in a single atomic operation is system-dependent and
+ * therefore unspecified.
+ *
+ * @see java.io.FileInputStream#getChannel()
+ * @see java.io.FileOutputStream#getChannel()
+ * @see java.io.RandomAccessFile#getChannel()
+ *
+ * @author Mark Reinhold
+ * @author Mike McCloskey
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class FileChannel
+    extends AbstractInterruptibleChannel
+    implements SeekableByteChannel, GatheringByteChannel, ScatteringByteChannel
+{
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected FileChannel() { }
+
+    /**
+     * Opens or creates a file, returning a file channel to access the file.
+     *
+     * <p> The {@code options} parameter determines how the file is opened.
+     * The {@link StandardOpenOption#READ READ} and {@link StandardOpenOption#WRITE
+     * WRITE} options determine if the file should be opened for reading and/or
+     * writing. If neither option (or the {@link StandardOpenOption#APPEND APPEND}
+     * option) is contained in the array then the file is opened for reading.
+     * By default reading or writing commences at the beginning of the file.
+     *
+     * <p> In the addition to {@code READ} and {@code WRITE}, the following
+     * options may be present:
+     *
+     * <table border=1 cellpadding=5 summary="">
+     * <tr> <th>Option</th> <th>Description</th> </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#APPEND APPEND} </td>
+     *   <td> If this option is present then the file is opened for writing and
+     *     each invocation of the channel's {@code write} method first advances
+     *     the position to the end of the file and then writes the requested
+     *     data. Whether the advancement of the position and the writing of the
+     *     data are done in a single atomic operation is system-dependent and
+     *     therefore unspecified. This option may not be used in conjunction
+     *     with the {@code READ} or {@code TRUNCATE_EXISTING} options. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
+     *   <td> If this option is present then the existing file is truncated to
+     *   a size of 0 bytes. This option is ignored when the file is opened only
+     *   for reading. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
+     *   <td> If this option is present then a new file is created, failing if
+     *   the file already exists. When creating a file the check for the
+     *   existence of the file and the creation of the file if it does not exist
+     *   is atomic with respect to other file system operations. This option is
+     *   ignored when the file is opened only for reading. </td>
+     * </tr>
+     * <tr>
+     *   <td > {@link StandardOpenOption#CREATE CREATE} </td>
+     *   <td> If this option is present then an existing file is opened if it
+     *   exists, otherwise a new file is created. When creating a file the check
+     *   for the existence of the file and the creation of the file if it does
+     *   not exist is atomic with respect to other file system operations. This
+     *   option is ignored if the {@code CREATE_NEW} option is also present or
+     *   the file is opened only for reading. </td>
+     * </tr>
+     * <tr>
+     *   <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
+     *   <td> When this option is present then the implementation makes a
+     *   <em>best effort</em> attempt to delete the file when closed by the
+     *   the {@link #close close} method. If the {@code close} method is not
+     *   invoked then a <em>best effort</em> attempt is made to delete the file
+     *   when the Java virtual machine terminates. </td>
+     * </tr>
+     * <tr>
+     *   <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
+     *   <td> When creating a new file this option is a <em>hint</em> that the
+     *   new file will be sparse. This option is ignored when not creating
+     *   a new file. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#SYNC SYNC} </td>
+     *   <td> Requires that every update to the file's content or metadata be
+     *   written synchronously to the underlying storage device. (see <a
+     *   href="../file/package-summary.html#integrity"> Synchronized I/O file
+     *   integrity</a>). </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
+     *   <td> Requires that every update to the file's content be written
+     *   synchronously to the underlying storage device. (see <a
+     *   href="../file/package-summary.html#integrity"> Synchronized I/O file
+     *   integrity</a>). </td>
+     * </tr>
+     * </table>
+     *
+     * <p> An implementation may also support additional options.
+     *
+     * <p> The {@code attrs} parameter is an optional array of file {@link
+     * FileAttribute file-attributes} to set atomically when creating the file.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * FileSystemProvider#newFileChannel newFileChannel} method on the
+     * provider that created the {@code Path}.
+     *
+     * @param   path
+     *          The path of the file to open or create
+     * @param   options
+     *          Options specifying how the file is opened
+     * @param   attrs
+     *          An optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  A new file channel
+     *
+     * @throws  IllegalArgumentException
+     *          If the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          If the {@code path} is associated with a provider that does not
+     *          support creating file channels, or an unsupported open option is
+     *          specified, or the array contains an attribute that cannot be set
+     *          atomically when creating the file
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an
+     *          unspecified permission required by the implementation.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     *
+     * @since   1.7
+     */
+    public static FileChannel open(Path path,
+                                   Set<? extends OpenOption> options,
+                                   FileAttribute<?>... attrs)
+        throws IOException
+    {
+        FileSystemProvider provider = path.getFileSystem().provider();
+        return provider.newFileChannel(path, options, attrs);
+    }
+
+    @SuppressWarnings({"unchecked", "rawtypes"}) // generic array construction
+    private static final FileAttribute<?>[] NO_ATTRIBUTES = new FileAttribute[0];
+
+    /**
+     * Opens or creates a file, returning a file channel to access the file.
+     *
+     * <p> An invocation of this method behaves in exactly the same way as the
+     * invocation
+     * <pre>
+     *     fc.{@link #open(Path,Set,FileAttribute[]) open}(file, opts, new FileAttribute&lt;?&gt;[0]);
+     * </pre>
+     * where {@code opts} is a set of the options specified in the {@code
+     * options} array.
+     *
+     * @param   path
+     *          The path of the file to open or create
+     * @param   options
+     *          Options specifying how the file is opened
+     *
+     * @return  A new file channel
+     *
+     * @throws  IllegalArgumentException
+     *          If the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          If the {@code path} is associated with a provider that does not
+     *          support creating file channels, or an unsupported open option is
+     *          specified
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an
+     *          unspecified permission required by the implementation.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     *
+     * @since   1.7
+     */
+    public static FileChannel open(Path path, OpenOption... options)
+        throws IOException
+    {
+        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+        Collections.addAll(set, options);
+        return open(path, set, NO_ATTRIBUTES);
+    }
+
+    // -- Channel operations --
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * <p> Bytes are read starting at this channel's current file position, and
+     * then the file position is updated with the number of bytes actually
+     * read.  Otherwise this method behaves exactly as specified in the {@link
+     * ReadableByteChannel} interface. </p>
+     */
+    public abstract int read(ByteBuffer dst) throws IOException;
+
+    /**
+     * Reads a sequence of bytes from this channel into a subsequence of the
+     * given buffers.
+     *
+     * <p> Bytes are read starting at this channel's current file position, and
+     * then the file position is updated with the number of bytes actually
+     * read.  Otherwise this method behaves exactly as specified in the {@link
+     * ScatteringByteChannel} interface.  </p>
+     */
+    public abstract long read(ByteBuffer[] dsts, int offset, int length)
+        throws IOException;
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffers.
+     *
+     * <p> Bytes are read starting at this channel's current file position, and
+     * then the file position is updated with the number of bytes actually
+     * read.  Otherwise this method behaves exactly as specified in the {@link
+     * ScatteringByteChannel} interface.  </p>
+     */
+    public final long read(ByteBuffer[] dsts) throws IOException {
+        return read(dsts, 0, dsts.length);
+    }
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * <p> Bytes are written starting at this channel's current file position
+     * unless the channel is in append mode, in which case the position is
+     * first advanced to the end of the file.  The file is grown, if necessary,
+     * to accommodate the written bytes, and then the file position is updated
+     * with the number of bytes actually written.  Otherwise this method
+     * behaves exactly as specified by the {@link WritableByteChannel}
+     * interface. </p>
+     */
+    public abstract int write(ByteBuffer src) throws IOException;
+
+    /**
+     * Writes a sequence of bytes to this channel from a subsequence of the
+     * given buffers.
+     *
+     * <p> Bytes are written starting at this channel's current file position
+     * unless the channel is in append mode, in which case the position is
+     * first advanced to the end of the file.  The file is grown, if necessary,
+     * to accommodate the written bytes, and then the file position is updated
+     * with the number of bytes actually written.  Otherwise this method
+     * behaves exactly as specified in the {@link GatheringByteChannel}
+     * interface.  </p>
+     */
+    public abstract long write(ByteBuffer[] srcs, int offset, int length)
+        throws IOException;
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffers.
+     *
+     * <p> Bytes are written starting at this channel's current file position
+     * unless the channel is in append mode, in which case the position is
+     * first advanced to the end of the file.  The file is grown, if necessary,
+     * to accommodate the written bytes, and then the file position is updated
+     * with the number of bytes actually written.  Otherwise this method
+     * behaves exactly as specified in the {@link GatheringByteChannel}
+     * interface.  </p>
+     */
+    public final long write(ByteBuffer[] srcs) throws IOException {
+        return write(srcs, 0, srcs.length);
+    }
+
+
+    // -- Other operations --
+
+    /**
+     * Returns this channel's file position.
+     *
+     * @return  This channel's file position,
+     *          a non-negative integer counting the number of bytes
+     *          from the beginning of the file to the current position
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract long position() throws IOException;
+
+    /**
+     * Sets this channel's file position.
+     *
+     * <p> Setting the position to a value that is greater than the file's
+     * current size is legal but does not change the size of the file.  A later
+     * attempt to read bytes at such a position will immediately return an
+     * end-of-file indication.  A later attempt to write bytes at such a
+     * position will cause the file to be grown to accommodate the new bytes;
+     * the values of any bytes between the previous end-of-file and the
+     * newly-written bytes are unspecified.  </p>
+     *
+     * @param  newPosition
+     *         The new position, a non-negative integer counting
+     *         the number of bytes from the beginning of the file
+     *
+     * @return  This file channel
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  IllegalArgumentException
+     *          If the new position is negative
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract FileChannel position(long newPosition) throws IOException;
+
+    /**
+     * Returns the current size of this channel's file.
+     *
+     * @return  The current size of this channel's file,
+     *          measured in bytes
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract long size() throws IOException;
+
+    /**
+     * Truncates this channel's file to the given size.
+     *
+     * <p> If the given size is less than the file's current size then the file
+     * is truncated, discarding any bytes beyond the new end of the file.  If
+     * the given size is greater than or equal to the file's current size then
+     * the file is not modified.  In either case, if this channel's file
+     * position is greater than the given size then it is set to that size.
+     * </p>
+     *
+     * @param  size
+     *         The new size, a non-negative byte count
+     *
+     * @return  This file channel
+     *
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  IllegalArgumentException
+     *          If the new size is negative
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract FileChannel truncate(long size) throws IOException;
+
+    /**
+     * Forces any updates to this channel's file to be written to the storage
+     * device that contains it.
+     *
+     * <p> If this channel's file resides on a local storage device then when
+     * this method returns it is guaranteed that all changes made to the file
+     * since this channel was created, or since this method was last invoked,
+     * will have been written to that device.  This is useful for ensuring that
+     * critical information is not lost in the event of a system crash.
+     *
+     * <p> If the file does not reside on a local device then no such guarantee
+     * is made.
+     *
+     * <p> The <tt>metaData</tt> parameter can be used to limit the number of
+     * I/O operations that this method is required to perform.  Passing
+     * <tt>false</tt> for this parameter indicates that only updates to the
+     * file's content need be written to storage; passing <tt>true</tt>
+     * indicates that updates to both the file's content and metadata must be
+     * written, which generally requires at least one more I/O operation.
+     * Whether this parameter actually has any effect is dependent upon the
+     * underlying operating system and is therefore unspecified.
+     *
+     * <p> Invoking this method may cause an I/O operation to occur even if the
+     * channel was only opened for reading.  Some operating systems, for
+     * example, maintain a last-access time as part of a file's metadata, and
+     * this time is updated whenever the file is read.  Whether or not this is
+     * actually done is system-dependent and is therefore unspecified.
+     *
+     * <p> This method is only guaranteed to force changes that were made to
+     * this channel's file via the methods defined in this class.  It may or
+     * may not force changes that were made by modifying the content of a
+     * {@link MappedByteBuffer <i>mapped byte buffer</i>} obtained by
+     * invoking the {@link #map map} method.  Invoking the {@link
+     * MappedByteBuffer#force force} method of the mapped byte buffer will
+     * force changes made to the buffer's content to be written.  </p>
+     *
+     * @param   metaData
+     *          If <tt>true</tt> then this method is required to force changes
+     *          to both the file's content and metadata to be written to
+     *          storage; otherwise, it need only force content changes to be
+     *          written
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract void force(boolean metaData) throws IOException;
+
+    /**
+     * Transfers bytes from this channel's file to the given writable byte
+     * channel.
+     *
+     * <p> An attempt is made to read up to <tt>count</tt> bytes starting at
+     * the given <tt>position</tt> in this channel's file and write them to the
+     * target channel.  An invocation of this method may or may not transfer
+     * all of the requested bytes; whether or not it does so depends upon the
+     * natures and states of the channels.  Fewer than the requested number of
+     * bytes are transferred if this channel's file contains fewer than
+     * <tt>count</tt> bytes starting at the given <tt>position</tt>, or if the
+     * target channel is non-blocking and it has fewer than <tt>count</tt>
+     * bytes free in its output buffer.
+     *
+     * <p> This method does not modify this channel's position.  If the given
+     * position is greater than the file's current size then no bytes are
+     * transferred.  If the target channel has a position then bytes are
+     * written starting at that position and then the position is incremented
+     * by the number of bytes written.
+     *
+     * <p> This method is potentially much more efficient than a simple loop
+     * that reads from this channel and writes to the target channel.  Many
+     * operating systems can transfer bytes directly from the filesystem cache
+     * to the target channel without actually copying them.  </p>
+     *
+     * @param  position
+     *         The position within the file at which the transfer is to begin;
+     *         must be non-negative
+     *
+     * @param  count
+     *         The maximum number of bytes to be transferred; must be
+     *         non-negative
+     *
+     * @param  target
+     *         The target channel
+     *
+     * @return  The number of bytes, possibly zero,
+     *          that were actually transferred
+     *
+     * @throws IllegalArgumentException
+     *         If the preconditions on the parameters do not hold
+     *
+     * @throws  NonReadableChannelException
+     *          If this channel was not opened for reading
+     *
+     * @throws  NonWritableChannelException
+     *          If the target channel was not opened for writing
+     *
+     * @throws  ClosedChannelException
+     *          If either this channel or the target channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes either channel
+     *          while the transfer is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread while the
+     *          transfer is in progress, thereby closing both channels and
+     *          setting the current thread's interrupt status
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract long transferTo(long position, long count,
+                                    WritableByteChannel target)
+        throws IOException;
+
+    /**
+     * Transfers bytes into this channel's file from the given readable byte
+     * channel.
+     *
+     * <p> An attempt is made to read up to <tt>count</tt> bytes from the
+     * source channel and write them to this channel's file starting at the
+     * given <tt>position</tt>.  An invocation of this method may or may not
+     * transfer all of the requested bytes; whether or not it does so depends
+     * upon the natures and states of the channels.  Fewer than the requested
+     * number of bytes will be transferred if the source channel has fewer than
+     * <tt>count</tt> bytes remaining, or if the source channel is non-blocking
+     * and has fewer than <tt>count</tt> bytes immediately available in its
+     * input buffer.
+     *
+     * <p> This method does not modify this channel's position.  If the given
+     * position is greater than the file's current size then no bytes are
+     * transferred.  If the source channel has a position then bytes are read
+     * starting at that position and then the position is incremented by the
+     * number of bytes read.
+     *
+     * <p> This method is potentially much more efficient than a simple loop
+     * that reads from the source channel and writes to this channel.  Many
+     * operating systems can transfer bytes directly from the source channel
+     * into the filesystem cache without actually copying them.  </p>
+     *
+     * @param  src
+     *         The source channel
+     *
+     * @param  position
+     *         The position within the file at which the transfer is to begin;
+     *         must be non-negative
+     *
+     * @param  count
+     *         The maximum number of bytes to be transferred; must be
+     *         non-negative
+     *
+     * @return  The number of bytes, possibly zero,
+     *          that were actually transferred
+     *
+     * @throws IllegalArgumentException
+     *         If the preconditions on the parameters do not hold
+     *
+     * @throws  NonReadableChannelException
+     *          If the source channel was not opened for reading
+     *
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     *
+     * @throws  ClosedChannelException
+     *          If either this channel or the source channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes either channel
+     *          while the transfer is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread while the
+     *          transfer is in progress, thereby closing both channels and
+     *          setting the current thread's interrupt status
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract long transferFrom(ReadableByteChannel src,
+                                      long position, long count)
+        throws IOException;
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer,
+     * starting at the given file position.
+     *
+     * <p> This method works in the same manner as the {@link
+     * #read(ByteBuffer)} method, except that bytes are read starting at the
+     * given file position rather than at the channel's current position.  This
+     * method does not modify this channel's position.  If the given position
+     * is greater than the file's current size then no bytes are read.  </p>
+     *
+     * @param  dst
+     *         The buffer into which bytes are to be transferred
+     *
+     * @param  position
+     *         The file position at which the transfer is to begin;
+     *         must be non-negative
+     *
+     * @return  The number of bytes read, possibly zero, or <tt>-1</tt> if the
+     *          given position is greater than or equal to the file's current
+     *          size
+     *
+     * @throws  IllegalArgumentException
+     *          If the position is negative
+     *
+     * @throws  NonReadableChannelException
+     *          If this channel was not opened for reading
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the read operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the read operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract int read(ByteBuffer dst, long position) throws IOException;
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer,
+     * starting at the given file position.
+     *
+     * <p> This method works in the same manner as the {@link
+     * #write(ByteBuffer)} method, except that bytes are written starting at
+     * the given file position rather than at the channel's current position.
+     * This method does not modify this channel's position.  If the given
+     * position is greater than the file's current size then the file will be
+     * grown to accommodate the new bytes; the values of any bytes between the
+     * previous end-of-file and the newly-written bytes are unspecified.  </p>
+     *
+     * @param  src
+     *         The buffer from which bytes are to be transferred
+     *
+     * @param  position
+     *         The file position at which the transfer is to begin;
+     *         must be non-negative
+     *
+     * @return  The number of bytes written, possibly zero
+     *
+     * @throws  IllegalArgumentException
+     *          If the position is negative
+     *
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the write operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the write operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract int write(ByteBuffer src, long position) throws IOException;
+
+
+    // -- Memory-mapped buffers --
+
+    /**
+     * A typesafe enumeration for file-mapping modes.
+     *
+     * @since 1.4
+     *
+     * @see java.nio.channels.FileChannel#map
+     */
+    public static class MapMode {
+
+        /**
+         * Mode for a read-only mapping.
+         */
+        public static final MapMode READ_ONLY
+            = new MapMode("READ_ONLY");
+
+        /**
+         * Mode for a read/write mapping.
+         */
+        public static final MapMode READ_WRITE
+            = new MapMode("READ_WRITE");
+
+        /**
+         * Mode for a private (copy-on-write) mapping.
+         */
+        public static final MapMode PRIVATE
+            = new MapMode("PRIVATE");
+
+        private final String name;
+
+        private MapMode(String name) {
+            this.name = name;
+        }
+
+        /**
+         * Returns a string describing this file-mapping mode.
+         *
+         * @return  A descriptive string
+         */
+        public String toString() {
+            return name;
+        }
+
+    }
+
+    /**
+     * Maps a region of this channel's file directly into memory.
+     *
+     * <p> A region of a file may be mapped into memory in one of three modes:
+     * </p>
+     *
+     * <ul>
+     *
+     *   <li><p> <i>Read-only:</i> Any attempt to modify the resulting buffer
+     *   will cause a {@link java.nio.ReadOnlyBufferException} to be thrown.
+     *   ({@link MapMode#READ_ONLY MapMode.READ_ONLY}) </p></li>
+     *
+     *   <li><p> <i>Read/write:</i> Changes made to the resulting buffer will
+     *   eventually be propagated to the file; they may or may not be made
+     *   visible to other programs that have mapped the same file.  ({@link
+     *   MapMode#READ_WRITE MapMode.READ_WRITE}) </p></li>
+     *
+     *   <li><p> <i>Private:</i> Changes made to the resulting buffer will not
+     *   be propagated to the file and will not be visible to other programs
+     *   that have mapped the same file; instead, they will cause private
+     *   copies of the modified portions of the buffer to be created.  ({@link
+     *   MapMode#PRIVATE MapMode.PRIVATE}) </p></li>
+     *
+     * </ul>
+     *
+     * <p> For a read-only mapping, this channel must have been opened for
+     * reading; for a read/write or private mapping, this channel must have
+     * been opened for both reading and writing.
+     *
+     * <p> The {@link MappedByteBuffer <i>mapped byte buffer</i>}
+     * returned by this method will have a position of zero and a limit and
+     * capacity of <tt>size</tt>; its mark will be undefined.  The buffer and
+     * the mapping that it represents will remain valid until the buffer itself
+     * is garbage-collected.
+     *
+     * <p> A mapping, once established, is not dependent upon the file channel
+     * that was used to create it.  Closing the channel, in particular, has no
+     * effect upon the validity of the mapping.
+     *
+     * <p> Many of the details of memory-mapped files are inherently dependent
+     * upon the underlying operating system and are therefore unspecified.  The
+     * behavior of this method when the requested region is not completely
+     * contained within this channel's file is unspecified.  Whether changes
+     * made to the content or size of the underlying file, by this program or
+     * another, are propagated to the buffer is unspecified.  The rate at which
+     * changes to the buffer are propagated to the file is unspecified.
+     *
+     * <p> For most operating systems, mapping a file into memory is more
+     * expensive than reading or writing a few tens of kilobytes of data via
+     * the usual {@link #read read} and {@link #write write} methods.  From the
+     * standpoint of performance it is generally only worth mapping relatively
+     * large files into memory.  </p>
+     *
+     * @param  mode
+     *         One of the constants {@link MapMode#READ_ONLY READ_ONLY}, {@link
+     *         MapMode#READ_WRITE READ_WRITE}, or {@link MapMode#PRIVATE
+     *         PRIVATE} defined in the {@link MapMode} class, according to
+     *         whether the file is to be mapped read-only, read/write, or
+     *         privately (copy-on-write), respectively
+     *
+     * @param  position
+     *         The position within the file at which the mapped region
+     *         is to start; must be non-negative
+     *
+     * @param  size
+     *         The size of the region to be mapped; must be non-negative and
+     *         no greater than {@link java.lang.Integer#MAX_VALUE}
+     *
+     * @return  The mapped byte buffer
+     *
+     * @throws NonReadableChannelException
+     *         If the <tt>mode</tt> is {@link MapMode#READ_ONLY READ_ONLY} but
+     *         this channel was not opened for reading
+     *
+     * @throws NonWritableChannelException
+     *         If the <tt>mode</tt> is {@link MapMode#READ_WRITE READ_WRITE} or
+     *         {@link MapMode#PRIVATE PRIVATE} but this channel was not opened
+     *         for both reading and writing
+     *
+     * @throws IllegalArgumentException
+     *         If the preconditions on the parameters do not hold
+     *
+     * @throws IOException
+     *         If some other I/O error occurs
+     *
+     * @see java.nio.channels.FileChannel.MapMode
+     * @see java.nio.MappedByteBuffer
+     */
+    public abstract MappedByteBuffer map(MapMode mode,
+                                         long position, long size)
+        throws IOException;
+
+
+    // -- Locks --
+
+    /**
+     * Acquires a lock on the given region of this channel's file.
+     *
+     * <p> An invocation of this method will block until the region can be
+     * locked, this channel is closed, or the invoking thread is interrupted,
+     * whichever comes first.
+     *
+     * <p> If this channel is closed by another thread during an invocation of
+     * this method then an {@link AsynchronousCloseException} will be thrown.
+     *
+     * <p> If the invoking thread is interrupted while waiting to acquire the
+     * lock then its interrupt status will be set and a {@link
+     * FileLockInterruptionException} will be thrown.  If the invoker's
+     * interrupt status is set when this method is invoked then that exception
+     * will be thrown immediately; the thread's interrupt status will not be
+     * changed.
+     *
+     * <p> The region specified by the <tt>position</tt> and <tt>size</tt>
+     * parameters need not be contained within, or even overlap, the actual
+     * underlying file.  Lock regions are fixed in size; if a locked region
+     * initially contains the end of the file and the file grows beyond the
+     * region then the new portion of the file will not be covered by the lock.
+     * If a file is expected to grow in size and a lock on the entire file is
+     * required then a region starting at zero, and no smaller than the
+     * expected maximum size of the file, should be locked.  The zero-argument
+     * {@link #lock()} method simply locks a region of size {@link
+     * Long#MAX_VALUE}.
+     *
+     * <p> Some operating systems do not support shared locks, in which case a
+     * request for a shared lock is automatically converted into a request for
+     * an exclusive lock.  Whether the newly-acquired lock is shared or
+     * exclusive may be tested by invoking the resulting lock object's {@link
+     * FileLock#isShared() isShared} method.
+     *
+     * <p> File locks are held on behalf of the entire Java virtual machine.
+     * They are not suitable for controlling access to a file by multiple
+     * threads within the same virtual machine.  </p>
+     *
+     * @param  position
+     *         The position at which the locked region is to start; must be
+     *         non-negative
+     *
+     * @param  size
+     *         The size of the locked region; must be non-negative, and the sum
+     *         <tt>position</tt>&nbsp;+&nbsp;<tt>size</tt> must be non-negative
+     *
+     * @param  shared
+     *         <tt>true</tt> to request a shared lock, in which case this
+     *         channel must be open for reading (and possibly writing);
+     *         <tt>false</tt> to request an exclusive lock, in which case this
+     *         channel must be open for writing (and possibly reading)
+     *
+     * @return  A lock object representing the newly-acquired lock
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameters do not hold
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel while the invoking
+     *          thread is blocked in this method
+     *
+     * @throws  FileLockInterruptionException
+     *          If the invoking thread is interrupted while blocked in this
+     *          method
+     *
+     * @throws  OverlappingFileLockException
+     *          If a lock that overlaps the requested region is already held by
+     *          this Java virtual machine, or if another thread is already
+     *          blocked in this method and is attempting to lock an overlapping
+     *          region
+     *
+     * @throws  NonReadableChannelException
+     *          If <tt>shared</tt> is <tt>true</tt> this channel was not
+     *          opened for reading
+     *
+     * @throws  NonWritableChannelException
+     *          If <tt>shared</tt> is <tt>false</tt> but this channel was not
+     *          opened for writing
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     *
+     * @see     #lock()
+     * @see     #tryLock()
+     * @see     #tryLock(long,long,boolean)
+     */
+    public abstract FileLock lock(long position, long size, boolean shared)
+        throws IOException;
+
+    /**
+     * Acquires an exclusive lock on this channel's file.
+     *
+     * <p> An invocation of this method of the form <tt>fc.lock()</tt> behaves
+     * in exactly the same way as the invocation
+     *
+     * <pre>
+     *     fc.{@link #lock(long,long,boolean) lock}(0L, Long.MAX_VALUE, false) </pre>
+     *
+     * @return  A lock object representing the newly-acquired lock
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel while the invoking
+     *          thread is blocked in this method
+     *
+     * @throws  FileLockInterruptionException
+     *          If the invoking thread is interrupted while blocked in this
+     *          method
+     *
+     * @throws  OverlappingFileLockException
+     *          If a lock that overlaps the requested region is already held by
+     *          this Java virtual machine, or if another thread is already
+     *          blocked in this method and is attempting to lock an overlapping
+     *          region of the same file
+     *
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     *
+     * @see     #lock(long,long,boolean)
+     * @see     #tryLock()
+     * @see     #tryLock(long,long,boolean)
+     */
+    public final FileLock lock() throws IOException {
+        return lock(0L, Long.MAX_VALUE, false);
+    }
+
+    /**
+     * Attempts to acquire a lock on the given region of this channel's file.
+     *
+     * <p> This method does not block.  An invocation always returns
+     * immediately, either having acquired a lock on the requested region or
+     * having failed to do so.  If it fails to acquire a lock because an
+     * overlapping lock is held by another program then it returns
+     * <tt>null</tt>.  If it fails to acquire a lock for any other reason then
+     * an appropriate exception is thrown.
+     *
+     * <p> The region specified by the <tt>position</tt> and <tt>size</tt>
+     * parameters need not be contained within, or even overlap, the actual
+     * underlying file.  Lock regions are fixed in size; if a locked region
+     * initially contains the end of the file and the file grows beyond the
+     * region then the new portion of the file will not be covered by the lock.
+     * If a file is expected to grow in size and a lock on the entire file is
+     * required then a region starting at zero, and no smaller than the
+     * expected maximum size of the file, should be locked.  The zero-argument
+     * {@link #tryLock()} method simply locks a region of size {@link
+     * Long#MAX_VALUE}.
+     *
+     * <p> Some operating systems do not support shared locks, in which case a
+     * request for a shared lock is automatically converted into a request for
+     * an exclusive lock.  Whether the newly-acquired lock is shared or
+     * exclusive may be tested by invoking the resulting lock object's {@link
+     * FileLock#isShared() isShared} method.
+     *
+     * <p> File locks are held on behalf of the entire Java virtual machine.
+     * They are not suitable for controlling access to a file by multiple
+     * threads within the same virtual machine.  </p>
+     *
+     * @param  position
+     *         The position at which the locked region is to start; must be
+     *         non-negative
+     *
+     * @param  size
+     *         The size of the locked region; must be non-negative, and the sum
+     *         <tt>position</tt>&nbsp;+&nbsp;<tt>size</tt> must be non-negative
+     *
+     * @param  shared
+     *         <tt>true</tt> to request a shared lock,
+     *         <tt>false</tt> to request an exclusive lock
+     *
+     * @return  A lock object representing the newly-acquired lock,
+     *          or <tt>null</tt> if the lock could not be acquired
+     *          because another program holds an overlapping lock
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameters do not hold
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  OverlappingFileLockException
+     *          If a lock that overlaps the requested region is already held by
+     *          this Java virtual machine, or if another thread is already
+     *          blocked in this method and is attempting to lock an overlapping
+     *          region of the same file
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     *
+     * @see     #lock()
+     * @see     #lock(long,long,boolean)
+     * @see     #tryLock()
+     */
+    public abstract FileLock tryLock(long position, long size, boolean shared)
+        throws IOException;
+
+    /**
+     * Attempts to acquire an exclusive lock on this channel's file.
+     *
+     * <p> An invocation of this method of the form <tt>fc.tryLock()</tt>
+     * behaves in exactly the same way as the invocation
+     *
+     * <pre>
+     *     fc.{@link #tryLock(long,long,boolean) tryLock}(0L, Long.MAX_VALUE, false) </pre>
+     *
+     * @return  A lock object representing the newly-acquired lock,
+     *          or <tt>null</tt> if the lock could not be acquired
+     *          because another program holds an overlapping lock
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  OverlappingFileLockException
+     *          If a lock that overlaps the requested region is already held by
+     *          this Java virtual machine, or if another thread is already
+     *          blocked in this method and is attempting to lock an overlapping
+     *          region
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     *
+     * @see     #lock()
+     * @see     #lock(long,long,boolean)
+     * @see     #tryLock(long,long,boolean)
+     */
+    public final FileLock tryLock() throws IOException {
+        return tryLock(0L, Long.MAX_VALUE, false);
+    }
+
+}
diff --git a/java/nio/channels/FileLock.java b/java/nio/channels/FileLock.java
new file mode 100644
index 0000000..156071c
--- /dev/null
+++ b/java/nio/channels/FileLock.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2001, 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.nio.channels;
+
+import java.io.IOException;
+
+/**
+ * A token representing a lock on a region of a file.
+ *
+ * <p> A file-lock object is created each time a lock is acquired on a file via
+ * one of the {@link FileChannel#lock(long,long,boolean) lock} or {@link
+ * FileChannel#tryLock(long,long,boolean) tryLock} methods of the
+ * {@link FileChannel} class, or the {@link
+ * AsynchronousFileChannel#lock(long,long,boolean,Object,CompletionHandler) lock}
+ * or {@link AsynchronousFileChannel#tryLock(long,long,boolean) tryLock}
+ * methods of the {@link AsynchronousFileChannel} class.
+ *
+ * <p> A file-lock object is initially valid.  It remains valid until the lock
+ * is released by invoking the {@link #release release} method, by closing the
+ * channel that was used to acquire it, or by the termination of the Java
+ * virtual machine, whichever comes first.  The validity of a lock may be
+ * tested by invoking its {@link #isValid isValid} method.
+ *
+ * <p> A file lock is either <i>exclusive</i> or <i>shared</i>.  A shared lock
+ * prevents other concurrently-running programs from acquiring an overlapping
+ * exclusive lock, but does allow them to acquire overlapping shared locks.  An
+ * exclusive lock prevents other programs from acquiring an overlapping lock of
+ * either type.  Once it is released, a lock has no further effect on the locks
+ * that may be acquired by other programs.
+ *
+ * <p> Whether a lock is exclusive or shared may be determined by invoking its
+ * {@link #isShared isShared} method.  Some platforms do not support shared
+ * locks, in which case a request for a shared lock is automatically converted
+ * into a request for an exclusive lock.
+ *
+ * <p> The locks held on a particular file by a single Java virtual machine do
+ * not overlap.  The {@link #overlaps overlaps} method may be used to test
+ * whether a candidate lock range overlaps an existing lock.
+ *
+ * <p> A file-lock object records the file channel upon whose file the lock is
+ * held, the type and validity of the lock, and the position and size of the
+ * locked region.  Only the validity of a lock is subject to change over time;
+ * all other aspects of a lock's state are immutable.
+ *
+ * <p> File locks are held on behalf of the entire Java virtual machine.
+ * They are not suitable for controlling access to a file by multiple
+ * threads within the same virtual machine.
+ *
+ * <p> File-lock objects are safe for use by multiple concurrent threads.
+ *
+ *
+ * <a name="pdep"></a><h2> Platform dependencies </h2>
+ *
+ * <p> This file-locking API is intended to map directly to the native locking
+ * facility of the underlying operating system.  Thus the locks held on a file
+ * should be visible to all programs that have access to the file, regardless
+ * of the language in which those programs are written.
+ *
+ * <p> Whether or not a lock actually prevents another program from accessing
+ * the content of the locked region is system-dependent and therefore
+ * unspecified.  The native file-locking facilities of some systems are merely
+ * <i>advisory</i>, meaning that programs must cooperatively observe a known
+ * locking protocol in order to guarantee data integrity.  On other systems
+ * native file locks are <i>mandatory</i>, meaning that if one program locks a
+ * region of a file then other programs are actually prevented from accessing
+ * that region in a way that would violate the lock.  On yet other systems,
+ * whether native file locks are advisory or mandatory is configurable on a
+ * per-file basis.  To ensure consistent and correct behavior across platforms,
+ * it is strongly recommended that the locks provided by this API be used as if
+ * they were advisory locks.
+ *
+ * <p> On some systems, acquiring a mandatory lock on a region of a file
+ * prevents that region from being {@link java.nio.channels.FileChannel#map
+ * <i>mapped into memory</i>}, and vice versa.  Programs that combine
+ * locking and mapping should be prepared for this combination to fail.
+ *
+ * <p> On some systems, closing a channel releases all locks held by the Java
+ * virtual machine on the underlying file regardless of whether the locks were
+ * acquired via that channel or via another channel open on the same file.  It
+ * is strongly recommended that, within a program, a unique channel be used to
+ * acquire all locks on any given file.
+ *
+ * <p> Some network filesystems permit file locking to be used with
+ * memory-mapped files only when the locked regions are page-aligned and a
+ * whole multiple of the underlying hardware's page size.  Some network
+ * filesystems do not implement file locks on regions that extend past a
+ * certain position, often 2<sup>30</sup> or 2<sup>31</sup>.  In general, great
+ * care should be taken when locking files that reside on network filesystems.
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class FileLock implements AutoCloseable {
+
+    private final Channel channel;
+    private final long position;
+    private final long size;
+    private final boolean shared;
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @param  channel
+     *         The file channel upon whose file this lock is held
+     *
+     * @param  position
+     *         The position within the file at which the locked region starts;
+     *         must be non-negative
+     *
+     * @param  size
+     *         The size of the locked region; must be non-negative, and the sum
+     *         <tt>position</tt>&nbsp;+&nbsp;<tt>size</tt> must be non-negative
+     *
+     * @param  shared
+     *         <tt>true</tt> if this lock is shared,
+     *         <tt>false</tt> if it is exclusive
+     *
+     * @throws IllegalArgumentException
+     *         If the preconditions on the parameters do not hold
+     */
+    protected FileLock(FileChannel channel,
+                       long position, long size, boolean shared)
+    {
+        if (position < 0)
+            throw new IllegalArgumentException("Negative position");
+        if (size < 0)
+            throw new IllegalArgumentException("Negative size");
+        if (position + size < 0)
+            throw new IllegalArgumentException("Negative position + size");
+        this.channel = channel;
+        this.position = position;
+        this.size = size;
+        this.shared = shared;
+    }
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @param  channel
+     *         The channel upon whose file this lock is held
+     *
+     * @param  position
+     *         The position within the file at which the locked region starts;
+     *         must be non-negative
+     *
+     * @param  size
+     *         The size of the locked region; must be non-negative, and the sum
+     *         <tt>position</tt>&nbsp;+&nbsp;<tt>size</tt> must be non-negative
+     *
+     * @param  shared
+     *         <tt>true</tt> if this lock is shared,
+     *         <tt>false</tt> if it is exclusive
+     *
+     * @throws IllegalArgumentException
+     *         If the preconditions on the parameters do not hold
+     *
+     * @since 1.7
+     */
+    protected FileLock(AsynchronousFileChannel channel,
+                       long position, long size, boolean shared)
+    {
+        if (position < 0)
+            throw new IllegalArgumentException("Negative position");
+        if (size < 0)
+            throw new IllegalArgumentException("Negative size");
+        if (position + size < 0)
+            throw new IllegalArgumentException("Negative position + size");
+        this.channel = channel;
+        this.position = position;
+        this.size = size;
+        this.shared = shared;
+    }
+
+    /**
+     * Returns the file channel upon whose file this lock was acquired.
+     *
+     * <p> This method has been superseded by the {@link #acquiredBy acquiredBy}
+     * method.
+     *
+     * @return  The file channel, or {@code null} if the file lock was not
+     *          acquired by a file channel.
+     */
+    public final FileChannel channel() {
+        return (channel instanceof FileChannel) ? (FileChannel)channel : null;
+    }
+
+    /**
+     * Returns the channel upon whose file this lock was acquired.
+     *
+     * @return  The channel upon whose file this lock was acquired.
+     *
+     * @since 1.7
+     */
+    public Channel acquiredBy() {
+        return channel;
+    }
+
+    /**
+     * Returns the position within the file of the first byte of the locked
+     * region.
+     *
+     * <p> A locked region need not be contained within, or even overlap, the
+     * actual underlying file, so the value returned by this method may exceed
+     * the file's current size.  </p>
+     *
+     * @return  The position
+     */
+    public final long position() {
+        return position;
+    }
+
+    /**
+     * Returns the size of the locked region in bytes.
+     *
+     * <p> A locked region need not be contained within, or even overlap, the
+     * actual underlying file, so the value returned by this method may exceed
+     * the file's current size.  </p>
+     *
+     * @return  The size of the locked region
+     */
+    public final long size() {
+        return size;
+    }
+
+    /**
+     * Tells whether this lock is shared.
+     *
+     * @return <tt>true</tt> if lock is shared,
+     *         <tt>false</tt> if it is exclusive
+     */
+    public final boolean isShared() {
+        return shared;
+    }
+
+    /**
+     * Tells whether or not this lock overlaps the given lock range.
+     *
+     * @param   position
+     *          The starting position of the lock range
+     * @param   size
+     *          The size of the lock range
+     *
+     * @return  <tt>true</tt> if, and only if, this lock and the given lock
+     *          range overlap by at least one byte
+     */
+    public final boolean overlaps(long position, long size) {
+        if (position + size <= this.position)
+            return false;               // That is below this
+        if (this.position + this.size <= position)
+            return false;               // This is below that
+        return true;
+    }
+
+    /**
+     * Tells whether or not this lock is valid.
+     *
+     * <p> A lock object remains valid until it is released or the associated
+     * file channel is closed, whichever comes first.  </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this lock is valid
+     */
+    public abstract boolean isValid();
+
+    /**
+     * Releases this lock.
+     *
+     * <p> If this lock object is valid then invoking this method releases the
+     * lock and renders the object invalid.  If this lock object is invalid
+     * then invoking this method has no effect.  </p>
+     *
+     * @throws  ClosedChannelException
+     *          If the channel that was used to acquire this lock
+     *          is no longer open
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract void release() throws IOException;
+
+    /**
+     * This method invokes the {@link #release} method. It was added
+     * to the class so that it could be used in conjunction with the
+     * automatic resource management block construct.
+     *
+     * @since 1.7
+     */
+    public final void close() throws IOException {
+        release();
+    }
+
+    /**
+     * Returns a string describing the range, type, and validity of this lock.
+     *
+     * @return  A descriptive string
+     */
+    public final String toString() {
+        return (this.getClass().getName()
+                + "[" + position
+                + ":" + size
+                + " " + (shared ? "shared" : "exclusive")
+                + " " + (isValid() ? "valid" : "invalid")
+                + "]");
+    }
+
+}
diff --git a/java/nio/channels/FileLockInterruptionException.java b/java/nio/channels/FileLockInterruptionException.java
new file mode 100644
index 0000000..a9b1bd6
--- /dev/null
+++ b/java/nio/channels/FileLockInterruptionException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Checked exception received by a thread when another thread interrupts it
+ * while it is waiting to acquire a file lock.  Before this exception is thrown
+ * the interrupt status of the previously-blocked thread will have been set.
+ *
+ * @since 1.4
+ */
+
+public class FileLockInterruptionException
+    extends java.io.IOException
+{
+
+    private static final long serialVersionUID = 7104080643653532383L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public FileLockInterruptionException() { }
+
+}
diff --git a/java/nio/channels/GatheringByteChannel.java b/java/nio/channels/GatheringByteChannel.java
new file mode 100644
index 0000000..9c50d93
--- /dev/null
+++ b/java/nio/channels/GatheringByteChannel.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2000, 2001, 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.nio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+
+/**
+ * A channel that can write bytes from a sequence of buffers.
+ *
+ * <p> A <i>gathering</i> write operation writes, in a single invocation, a
+ * sequence of bytes from one or more of a given sequence of buffers.
+ * Gathering writes are often useful when implementing network protocols or
+ * file formats that, for example, group data into segments consisting of one
+ * or more fixed-length headers followed by a variable-length body.  Similar
+ * <i>scattering</i> read operations are defined in the {@link
+ * ScatteringByteChannel} interface.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface GatheringByteChannel
+    extends WritableByteChannel
+{
+
+    /**
+     * Writes a sequence of bytes to this channel from a subsequence of the
+     * given buffers.
+     *
+     * <p> An attempt is made to write up to <i>r</i> bytes to this channel,
+     * where <i>r</i> is the total number of bytes remaining in the specified
+     * subsequence of the given buffer array, that is,
+     *
+     * <blockquote><pre>
+     * srcs[offset].remaining()
+     *     + srcs[offset+1].remaining()
+     *     + ... + srcs[offset+length-1].remaining()</pre></blockquote>
+     *
+     * at the moment that this method is invoked.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is written, where
+     * <tt>0</tt>&nbsp;<tt>&lt;=</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * Up to the first <tt>srcs[offset].remaining()</tt> bytes of this sequence
+     * are written from buffer <tt>srcs[offset]</tt>, up to the next
+     * <tt>srcs[offset+1].remaining()</tt> bytes are written from buffer
+     * <tt>srcs[offset+1]</tt>, and so forth, until the entire byte sequence is
+     * written.  As many bytes as possible are written from each buffer, hence
+     * the final position of each updated buffer, except the last updated
+     * buffer, is guaranteed to be equal to that buffer's limit.
+     *
+     * <p> Unless otherwise specified, a write operation will return only after
+     * writing all of the <i>r</i> requested bytes.  Some types of channels,
+     * depending upon their state, may write only some of the bytes or possibly
+     * none at all.  A socket channel in non-blocking mode, for example, cannot
+     * write any more bytes than are free in the socket's output buffer.
+     *
+     * <p> This method may be invoked at any time.  If another thread has
+     * already initiated a write operation upon this channel, however, then an
+     * invocation of this method will block until the first operation is
+     * complete. </p>
+     *
+     * @param  srcs
+     *         The buffers from which bytes are to be retrieved
+     *
+     * @param  offset
+     *         The offset within the buffer array of the first buffer from
+     *         which bytes are to be retrieved; must be non-negative and no
+     *         larger than <tt>srcs.length</tt>
+     *
+     * @param  length
+     *         The maximum number of buffers to be accessed; must be
+     *         non-negative and no larger than
+     *         <tt>srcs.length</tt>&nbsp;-&nbsp;<tt>offset</tt>
+     *
+     * @return  The number of bytes written, possibly zero
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     *
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the write operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the write operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public long write(ByteBuffer[] srcs, int offset, int length)
+        throws IOException;
+
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffers.
+     *
+     * <p> An invocation of this method of the form <tt>c.write(srcs)</tt>
+     * behaves in exactly the same manner as the invocation
+     *
+     * <blockquote><pre>
+     * c.write(srcs, 0, srcs.length);</pre></blockquote>
+     *
+     * @param  srcs
+     *         The buffers from which bytes are to be retrieved
+     *
+     * @return  The number of bytes written, possibly zero
+     *
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the write operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the write operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public long write(ByteBuffer[] srcs) throws IOException;
+
+}
diff --git a/java/nio/channels/IllegalBlockingModeException.java b/java/nio/channels/IllegalBlockingModeException.java
new file mode 100644
index 0000000..19d0300
--- /dev/null
+++ b/java/nio/channels/IllegalBlockingModeException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when a blocking-mode-specific operation
+ * is invoked upon a channel in the incorrect blocking mode.
+ *
+ * @since 1.4
+ */
+
+public class IllegalBlockingModeException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = -3335774961855590474L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public IllegalBlockingModeException() { }
+
+}
diff --git a/java/nio/channels/IllegalChannelGroupException.java b/java/nio/channels/IllegalChannelGroupException.java
new file mode 100644
index 0000000..dd47105
--- /dev/null
+++ b/java/nio/channels/IllegalChannelGroupException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to open a channel
+ * in a group that was not created by the same provider. 
+ *
+ * @since 1.7
+ */
+
+public class IllegalChannelGroupException
+    extends IllegalArgumentException
+{
+
+    private static final long serialVersionUID = -2495041211157744253L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public IllegalChannelGroupException() { }
+
+}
diff --git a/java/nio/channels/IllegalSelectorException.java b/java/nio/channels/IllegalSelectorException.java
new file mode 100644
index 0000000..b10f071
--- /dev/null
+++ b/java/nio/channels/IllegalSelectorException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to register a channel
+ * with a selector that was not created by the provider that created the
+ * channel.
+ *
+ * @since 1.4
+ */
+
+public class IllegalSelectorException
+    extends IllegalArgumentException
+{
+
+    private static final long serialVersionUID = -8406323347253320987L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public IllegalSelectorException() { }
+
+}
diff --git a/java/nio/channels/InterruptedByTimeoutException.java b/java/nio/channels/InterruptedByTimeoutException.java
new file mode 100644
index 0000000..ae2018d
--- /dev/null
+++ b/java/nio/channels/InterruptedByTimeoutException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Checked exception received by a thread when a timeout elapses before an
+ * asynchronous operation completes.
+ *
+ * @since 1.7
+ */
+
+public class InterruptedByTimeoutException
+    extends java.io.IOException
+{
+
+    private static final long serialVersionUID = -4268008601014042947L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public InterruptedByTimeoutException() { }
+
+}
diff --git a/java/nio/channels/InterruptibleChannel.java b/java/nio/channels/InterruptibleChannel.java
new file mode 100644
index 0000000..0e49aa6
--- /dev/null
+++ b/java/nio/channels/InterruptibleChannel.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2001, 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.nio.channels;
+
+import java.io.IOException;
+
+
+/**
+ * A channel that can be asynchronously closed and interrupted.
+ *
+ * <p> A channel that implements this interface is <i>asynchronously
+ * closeable:</i> If a thread is blocked in an I/O operation on an
+ * interruptible channel then another thread may invoke the channel's {@link
+ * #close close} method.  This will cause the blocked thread to receive an
+ * {@link AsynchronousCloseException}.
+ *
+ * <p> A channel that implements this interface is also <i>interruptible:</i>
+ * If a thread is blocked in an I/O operation on an interruptible channel then
+ * another thread may invoke the blocked thread's {@link Thread#interrupt()
+ * interrupt} method.  This will cause the channel to be closed, the blocked
+ * thread to receive a {@link ClosedByInterruptException}, and the blocked
+ * thread's interrupt status to be set.
+ *
+ * <p> If a thread's interrupt status is already set and it invokes a blocking
+ * I/O operation upon a channel then the channel will be closed and the thread
+ * will immediately receive a {@link ClosedByInterruptException}; its interrupt
+ * status will remain set.
+ *
+ * <p> A channel supports asynchronous closing and interruption if, and only
+ * if, it implements this interface.  This can be tested at runtime, if
+ * necessary, via the <tt>instanceof</tt> operator.
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface InterruptibleChannel
+    extends Channel
+{
+
+    /**
+     * Closes this channel.
+     *
+     * <p> Any thread currently blocked in an I/O operation upon this channel
+     * will receive an {@link AsynchronousCloseException}.
+     *
+     * <p> This method otherwise behaves exactly as specified by the {@link
+     * Channel#close Channel} interface.  </p>
+     *
+     * @throws  IOException  If an I/O error occurs
+     */
+    public void close() throws IOException;
+
+}
diff --git a/java/nio/channels/MembershipKey.java b/java/nio/channels/MembershipKey.java
new file mode 100644
index 0000000..91c2632
--- /dev/null
+++ b/java/nio/channels/MembershipKey.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2007, 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.nio.channels;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.io.IOException;
+
+/**
+ * A token representing the membership of an Internet Protocol (IP) multicast
+ * group.
+ *
+ * <p> A membership key may represent a membership to receive all datagrams sent
+ * to the group, or it may be <em>source-specific</em>, meaning that it
+ * represents a membership that receives only datagrams from a specific source
+ * address. Whether or not a membership key is source-specific may be determined
+ * by invoking its {@link #sourceAddress() sourceAddress} method.
+ *
+ * <p> A membership key is valid upon creation and remains valid until the
+ * membership is dropped by invoking the {@link #drop() drop} method, or
+ * the channel is closed. The validity of the membership key may be tested
+ * by invoking its {@link #isValid() isValid} method.
+ *
+ * <p> Where a membership key is not source-specific and the underlying operation
+ * system supports source filtering, then the {@link #block block} and {@link
+ * #unblock unblock} methods can be used to block or unblock multicast datagrams
+ * from particular source addresses.
+ *
+ * @see MulticastChannel
+ *
+ * @since 1.7
+ */
+public abstract class MembershipKey {
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected MembershipKey() {
+    }
+
+    /**
+     * Tells whether or not this membership is valid.
+     *
+     * <p> A multicast group membership is valid upon creation and remains
+     * valid until the membership is dropped by invoking the {@link #drop() drop}
+     * method, or the channel is closed.
+     *
+     * @return  {@code true} if this membership key is valid, {@code false}
+     *          otherwise
+     */
+    public abstract boolean isValid();
+
+    /**
+     * Drop membership.
+     *
+     * <p> If the membership key represents a membership to receive all datagrams
+     * then the membership is dropped and the channel will no longer receive any
+     * datagrams sent to the group. If the membership key is source-specific
+     * then the channel will no longer receive datagrams sent to the group from
+     * that source address.
+     *
+     * <p> After membership is dropped it may still be possible to receive
+     * datagrams sent to the group. This can arise when datagrams are waiting to
+     * be received in the socket's receive buffer. After membership is dropped
+     * then the channel may {@link MulticastChannel#join join} the group again
+     * in which case a new membership key is returned.
+     *
+     * <p> Upon return, this membership object will be {@link #isValid() invalid}.
+     * If the multicast group membership is already invalid then invoking this
+     * method has no effect. Once a multicast group membership is invalid,
+     * it remains invalid forever.
+     */
+    public abstract void drop();
+
+    /**
+     * Block multicast datagrams from the given source address.
+     *
+     * <p> If this membership key is not source-specific, and the underlying
+     * operating system supports source filtering, then this method blocks
+     * multicast datagrams from the given source address. If the given source
+     * address is already blocked then this method has no effect.
+     * After a source address is blocked it may still be possible to receive
+     * datagrams from that source. This can arise when datagrams are waiting to
+     * be received in the socket's receive buffer.
+     *
+     * @param   source
+     *          The source address to block
+     *
+     * @return  This membership key
+     *
+     * @throws  IllegalArgumentException
+     *          If the {@code source} parameter is not a unicast address or
+     *          is not the same address type as the multicast group
+     * @throws  IllegalStateException
+     *          If this membership key is source-specific or is no longer valid
+     * @throws  UnsupportedOperationException
+     *          If the underlying operating system does not support source
+     *          filtering
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract MembershipKey block(InetAddress source) throws IOException;
+
+    /**
+     * Unblock multicast datagrams from the given source address that was
+     * previously blocked using the {@link #block(InetAddress) block} method.
+     *
+     * @param   source
+     *          The source address to unblock
+     *
+     * @return  This membership key
+     *
+     * @throws  IllegalStateException
+     *          If the given source address is not currently blocked or the
+     *          membership key is no longer valid
+     */
+    public abstract MembershipKey unblock(InetAddress source);
+
+    /**
+     * Returns the channel for which this membership key was created. This
+     * method will continue to return the channel even after the membership
+     * becomes {@link #isValid invalid}.
+     *
+     * @return  the channel
+     */
+    public abstract MulticastChannel channel();
+
+    /**
+     * Returns the multicast group for which this membership key was created.
+     * This method will continue to return the group even after the membership
+     * becomes {@link #isValid invalid}.
+     *
+     * @return  the multicast group
+     */
+    public abstract InetAddress group();
+
+    /**
+     * Returns the network interface for which this membership key was created.
+     * This method will continue to return the network interface even after the
+     * membership becomes {@link #isValid invalid}.
+     *
+     * @return  the network interface
+     */
+    public abstract NetworkInterface networkInterface();
+
+    /**
+     * Returns the source address if this membership key is source-specific,
+     * or {@code null} if this membership is not source-specific.
+     *
+     * @return  The source address if this membership key is source-specific,
+     *          otherwise {@code null}
+     */
+    public abstract InetAddress sourceAddress();
+}
diff --git a/java/nio/channels/MulticastChannel.java b/java/nio/channels/MulticastChannel.java
new file mode 100644
index 0000000..d1d13eb
--- /dev/null
+++ b/java/nio/channels/MulticastChannel.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2007, 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.nio.channels;
+
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.io.IOException;
+import java.net.ProtocolFamily;             // javadoc
+import java.net.StandardProtocolFamily;     // javadoc
+import java.net.StandardSocketOptions;      // javadoc
+
+/**
+ * A network channel that supports Internet Protocol (IP) multicasting.
+ *
+ * <p> IP multicasting is the transmission of IP datagrams to members of
+ * a <em>group</em> that is zero or more hosts identified by a single destination
+ * address.
+ *
+ * <p> In the case of a channel to an {@link StandardProtocolFamily#INET IPv4} socket,
+ * the underlying operating system supports <a href="http://www.ietf.org/rfc/rfc2236.txt">
+ * <i>RFC&nbsp;2236: Internet Group Management Protocol, Version 2 (IGMPv2)</i></a>.
+ * It may optionally support source filtering as specified by <a
+ * href="http://www.ietf.org/rfc/rfc3376.txt"> <i>RFC&nbsp;3376: Internet Group
+ * Management Protocol, Version 3 (IGMPv3)</i></a>.
+ * For channels to an {@link StandardProtocolFamily#INET6 IPv6} socket, the equivalent
+ * standards are <a href="http://www.ietf.org/rfc/rfc2710.txt"> <i>RFC&nbsp;2710:
+ * Multicast Listener Discovery (MLD) for IPv6</i></a> and <a
+ * href="http://www.ietf.org/rfc/rfc3810.txt"> <i>RFC&nbsp;3810: Multicast Listener
+ * Discovery Version 2 (MLDv2) for IPv6</i></a>.
+ *
+ * <p> The {@link #join(InetAddress,NetworkInterface)} method is used to
+ * join a group and receive all multicast datagrams sent to the group. A channel
+ * may join several multicast groups and may join the same group on several
+ * {@link NetworkInterface interfaces}. Membership is dropped by invoking the {@link
+ * MembershipKey#drop drop} method on the returned {@link MembershipKey}. If the
+ * underlying platform supports source filtering then the {@link MembershipKey#block
+ * block} and {@link MembershipKey#unblock unblock} methods can be used to block or
+ * unblock multicast datagrams from particular source addresses.
+ *
+ * <p> The {@link #join(InetAddress,NetworkInterface,InetAddress)} method
+ * is used to begin receiving datagrams sent to a group whose source address matches
+ * a given source address. This method throws {@link UnsupportedOperationException}
+ * if the underlying platform does not support source filtering.  Membership is
+ * <em>cumulative</em> and this method may be invoked again with the same group
+ * and interface to allow receiving datagrams from other source addresses. The
+ * method returns a {@link MembershipKey} that represents membership to receive
+ * datagrams from the given source address. Invoking the key's {@link
+ * MembershipKey#drop drop} method drops membership so that datagrams from the
+ * source address can no longer be received.
+ *
+ * <h2>Platform dependencies</h2>
+ *
+ * The multicast implementation is intended to map directly to the native
+ * multicasting facility. Consequently, the following items should be considered
+ * when developing an application that receives IP multicast datagrams:
+ *
+ * <ol>
+ *
+ * <li><p> The creation of the channel should specify the {@link ProtocolFamily}
+ * that corresponds to the address type of the multicast groups that the channel
+ * will join. There is no guarantee that a channel to a socket in one protocol
+ * family can join and receive multicast datagrams when the address of the
+ * multicast group corresponds to another protocol family. For example, it is
+ * implementation specific if a channel to an {@link StandardProtocolFamily#INET6 IPv6}
+ * socket can join an {@link StandardProtocolFamily#INET IPv4} multicast group and receive
+ * multicast datagrams sent to the group. </p></li>
+ *
+ * <li><p> The channel's socket should be bound to the {@link
+ * InetAddress#isAnyLocalAddress wildcard} address. If the socket is bound to
+ * a specific address, rather than the wildcard address then it is implementation
+ * specific if multicast datagrams are received by the socket. </p></li>
+ *
+ * <li><p> The {@link StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} option should be
+ * enabled prior to {@link NetworkChannel#bind binding} the socket. This is
+ * required to allow multiple members of the group to bind to the same
+ * address. </p></li>
+ *
+ * </ol>
+ *
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ *     // join multicast group on this interface, and also use this
+ *     // interface for outgoing multicast datagrams
+ *     NetworkInterface ni = NetworkInterface.getByName("hme0");
+ *
+ *     DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)
+ *         .setOption(StandardSocketOptions.SO_REUSEADDR, true)
+ *         .bind(new InetSocketAddress(5000))
+ *         .setOption(StandardSocketOptions.IP_MULTICAST_IF, ni);
+ *
+ *     InetAddress group = InetAddress.getByName("225.4.5.6");
+ *
+ *     MembershipKey key = dc.join(group, ni);
+ * </pre>
+ *
+ * @since 1.7
+ */
+
+public interface MulticastChannel
+    extends NetworkChannel
+{
+    /**
+     * Closes this channel.
+     *
+     * <p> If the channel is a member of a multicast group then the membership
+     * is {@link MembershipKey#drop dropped}. Upon return, the {@link
+     * MembershipKey membership-key} will be {@link MembershipKey#isValid
+     * invalid}.
+     *
+     * <p> This method otherwise behaves exactly as specified by the {@link
+     * Channel} interface.
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    @Override void close() throws IOException;
+
+    /**
+     * Joins a multicast group to begin receiving all datagrams sent to the group,
+     * returning a membership key.
+     *
+     * <p> If this channel is currently a member of the group on the given
+     * interface to receive all datagrams then the membership key, representing
+     * that membership, is returned. Otherwise this channel joins the group and
+     * the resulting new membership key is returned. The resulting membership key
+     * is not {@link MembershipKey#sourceAddress source-specific}.
+     *
+     * <p> A multicast channel may join several multicast groups, including
+     * the same group on more than one interface. An implementation may impose a
+     * limit on the number of groups that may be joined at the same time.
+     *
+     * @param   group
+     *          The multicast address to join
+     * @param   interf
+     *          The network interface on which to join the group
+     *
+     * @return  The membership key
+     *
+     * @throws  IllegalArgumentException
+     *          If the group parameter is not a {@link InetAddress#isMulticastAddress
+     *          multicast} address, or the group parameter is an address type
+     *          that is not supported by this channel
+     * @throws  IllegalStateException
+     *          If the channel already has source-specific membership of the
+     *          group on the interface
+     * @throws  UnsupportedOperationException
+     *          If the channel's socket is not an Internet Protocol socket
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is set, and its
+     *          {@link SecurityManager#checkMulticast(InetAddress) checkMulticast}
+     *          method denies access to the multiast group
+     */
+    MembershipKey join(InetAddress group, NetworkInterface interf)
+        throws IOException;
+
+    /**
+     * Joins a multicast group to begin receiving datagrams sent to the group
+     * from a given source address.
+     *
+     * <p> If this channel is currently a member of the group on the given
+     * interface to receive datagrams from the given source address then the
+     * membership key, representing that membership, is returned. Otherwise this
+     * channel joins the group and the resulting new membership key is returned.
+     * The resulting membership key is {@link MembershipKey#sourceAddress
+     * source-specific}.
+     *
+     * <p> Membership is <em>cumulative</em> and this method may be invoked
+     * again with the same group and interface to allow receiving datagrams sent
+     * by other source addresses to the group.
+     *
+     * @param   group
+     *          The multicast address to join
+     * @param   interf
+     *          The network interface on which to join the group
+     * @param   source
+     *          The source address
+     *
+     * @return  The membership key
+     *
+     * @throws  IllegalArgumentException
+     *          If the group parameter is not a {@link
+     *          InetAddress#isMulticastAddress multicast} address, the
+     *          source parameter is not a unicast address, the group
+     *          parameter is an address type that is not supported by this channel,
+     *          or the source parameter is not the same address type as the group
+     * @throws  IllegalStateException
+     *          If the channel is currently a member of the group on the given
+     *          interface to receive all datagrams
+     * @throws  UnsupportedOperationException
+     *          If the channel's socket is not an Internet Protocol socket or
+     *          source filtering is not supported
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is set, and its
+     *          {@link SecurityManager#checkMulticast(InetAddress) checkMulticast}
+     *          method denies access to the multiast group
+     */
+    MembershipKey join(InetAddress group, NetworkInterface interf, InetAddress source)
+        throws IOException;
+}
diff --git a/java/nio/channels/NetworkChannel.java b/java/nio/channels/NetworkChannel.java
new file mode 100644
index 0000000..65a7c22
--- /dev/null
+++ b/java/nio/channels/NetworkChannel.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2007, 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.nio.channels;
+
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.util.Set;
+import java.io.IOException;
+
+/**
+ * A channel to a network socket.
+ *
+ * <p> A channel that implements this interface is a channel to a network
+ * socket. The {@link #bind(SocketAddress) bind} method is used to bind the
+ * socket to a local {@link SocketAddress address}, the {@link #getLocalAddress()
+ * getLocalAddress} method returns the address that the socket is bound to, and
+ * the {@link #setOption(SocketOption,Object) setOption} and {@link
+ * #getOption(SocketOption) getOption} methods are used to set and query socket
+ * options.  An implementation of this interface should specify the socket options
+ * that it supports.
+ *
+ * <p> The {@link #bind bind} and {@link #setOption setOption} methods that do
+ * not otherwise have a value to return are specified to return the network
+ * channel upon which they are invoked. This allows method invocations to be
+ * chained. Implementations of this interface should specialize the return type
+ * so that method invocations on the implementation class can be chained.
+ *
+ * @since 1.7
+ */
+
+public interface NetworkChannel
+    extends Channel
+{
+    /**
+     * Binds the channel's socket to a local address.
+     *
+     * <p> This method is used to establish an association between the socket and
+     * a local address. Once an association is established then the socket remains
+     * bound until the channel is closed. If the {@code local} parameter has the
+     * value {@code null} then the socket will be bound to an address that is
+     * assigned automatically.
+     *
+     * @param   local
+     *          The address to bind the socket, or {@code null} to bind the socket
+     *          to an automatically assigned socket address
+     *
+     * @return  This channel
+     *
+     * @throws  AlreadyBoundException
+     *          If the socket is already bound
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given address is not supported
+     * @throws  ClosedChannelException
+     *          If the channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an unspecified
+     *          permission. An implementation of this interface should specify
+     *          any required permissions.
+     *
+     * @see #getLocalAddress
+     */
+    NetworkChannel bind(SocketAddress local) throws IOException;
+
+    /**
+     * Returns the socket address that this channel's socket is bound to.
+     *
+     * <p> Where the channel is {@link #bind bound} to an Internet Protocol
+     * socket address then the return value from this method is of type {@link
+     * java.net.InetSocketAddress}.
+     *
+     * @return  The socket address that the socket is bound to, or {@code null}
+     *          if the channel's socket is not bound
+     *
+     * @throws  ClosedChannelException
+     *          If the channel is closed
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    SocketAddress getLocalAddress() throws IOException;
+
+    /**
+     * Sets the value of a socket option.
+     *
+     * @param   <T>
+     *          The type of the socket option value
+     * @param   name
+     *          The socket option
+     * @param   value
+     *          The value of the socket option. A value of {@code null} may be
+     *          a valid value for some socket options.
+     *
+     * @return  This channel
+     *
+     * @throws  UnsupportedOperationException
+     *          If the socket option is not supported by this channel
+     * @throws  IllegalArgumentException
+     *          If the value is not a valid value for this socket option
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @see java.net.StandardSocketOptions
+     */
+    <T> NetworkChannel setOption(SocketOption<T> name, T value) throws IOException;
+
+    /**
+     * Returns the value of a socket option.
+     *
+     * @param   <T>
+     *          The type of the socket option value
+     * @param   name
+     *          The socket option
+     *
+     * @return  The value of the socket option. A value of {@code null} may be
+     *          a valid value for some socket options.
+     *
+     * @throws  UnsupportedOperationException
+     *          If the socket option is not supported by this channel
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @see java.net.StandardSocketOptions
+     */
+    <T> T getOption(SocketOption<T> name) throws IOException;
+
+    /**
+     * Returns a set of the socket options supported by this channel.
+     *
+     * <p> This method will continue to return the set of options even after the
+     * channel has been closed.
+     *
+     * @return  A set of the socket options supported by this channel
+     */
+    Set<SocketOption<?>> supportedOptions();
+}
diff --git a/java/nio/channels/NoConnectionPendingException.java b/java/nio/channels/NoConnectionPendingException.java
new file mode 100644
index 0000000..cea5ad1
--- /dev/null
+++ b/java/nio/channels/NoConnectionPendingException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when the {@link SocketChannel#finishConnect
+ * finishConnect} method of a {@link SocketChannel} is invoked without first
+ * successfully invoking its {@link SocketChannel#connect connect} method.
+ *
+ * @since 1.4
+ */
+
+public class NoConnectionPendingException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = -8296561183633134743L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public NoConnectionPendingException() { }
+
+}
diff --git a/java/nio/channels/NonReadableChannelException.java b/java/nio/channels/NonReadableChannelException.java
new file mode 100644
index 0000000..ddfa7fa
--- /dev/null
+++ b/java/nio/channels/NonReadableChannelException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to read
+ * from a channel that was not originally opened for reading.
+ *
+ * @since 1.4
+ */
+
+public class NonReadableChannelException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = -3200915679294993514L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public NonReadableChannelException() { }
+
+}
diff --git a/java/nio/channels/NonWritableChannelException.java b/java/nio/channels/NonWritableChannelException.java
new file mode 100644
index 0000000..17c90f3
--- /dev/null
+++ b/java/nio/channels/NonWritableChannelException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to write
+ * to a channel that was not originally opened for writing.
+ *
+ * @since 1.4
+ */
+
+public class NonWritableChannelException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = -7071230488279011621L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public NonWritableChannelException() { }
+
+}
diff --git a/java/nio/channels/NotYetBoundException.java b/java/nio/channels/NotYetBoundException.java
new file mode 100644
index 0000000..b6c6af3
--- /dev/null
+++ b/java/nio/channels/NotYetBoundException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an I/O
+ * operation upon a server socket channel that is not yet bound.
+ *
+ * @since 1.4
+ */
+
+public class NotYetBoundException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = 4640999303950202242L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public NotYetBoundException() { }
+
+}
diff --git a/java/nio/channels/NotYetConnectedException.java b/java/nio/channels/NotYetConnectedException.java
new file mode 100644
index 0000000..9e56d07
--- /dev/null
+++ b/java/nio/channels/NotYetConnectedException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an I/O
+ * operation upon a socket channel that is not yet connected.
+ *
+ * @since 1.4
+ */
+
+public class NotYetConnectedException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = 4697316551909513464L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public NotYetConnectedException() { }
+
+}
diff --git a/java/nio/channels/OverlappingFileLockException.java b/java/nio/channels/OverlappingFileLockException.java
new file mode 100644
index 0000000..7dd8f24
--- /dev/null
+++ b/java/nio/channels/OverlappingFileLockException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to acquire a lock on a
+ * region of a file that overlaps a region already locked by the same Java
+ * virtual machine, or when another thread is already waiting to lock an
+ * overlapping region of the same file.
+ *
+ * @since 1.4
+ */
+
+public class OverlappingFileLockException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = 2047812138163068433L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public OverlappingFileLockException() { }
+
+}
diff --git a/java/nio/channels/Pipe.java b/java/nio/channels/Pipe.java
new file mode 100644
index 0000000..d704680
--- /dev/null
+++ b/java/nio/channels/Pipe.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels;
+
+import java.io.IOException;
+import java.nio.channels.spi.*;
+
+
+/**
+ * A pair of channels that implements a unidirectional pipe.
+ *
+ * <p> A pipe consists of a pair of channels: A writable {@link
+ * Pipe.SinkChannel sink} channel and a readable {@link Pipe.SourceChannel source}
+ * channel.  Once some bytes are written to the sink channel they can be read
+ * from source channel in exactlyAthe order in which they were written.
+ *
+ * <p> Whether or not a thread writing bytes to a pipe will block until another
+ * thread reads those bytes, or some previously-written bytes, from the pipe is
+ * system-dependent and therefore unspecified.  Many pipe implementations will
+ * buffer up to a certain number of bytes between the sink and source channels,
+ * but such buffering should not be assumed.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class Pipe {
+
+    /**
+     * A channel representing the readable end of a {@link Pipe}.
+     *
+     * @since 1.4
+     */
+    public static abstract class SourceChannel
+        extends AbstractSelectableChannel
+        implements ReadableByteChannel, ScatteringByteChannel
+    {
+        /**
+         * Constructs a new instance of this class.
+         *
+         * @param  provider
+         *         The selector provider
+         */
+        protected SourceChannel(SelectorProvider provider) {
+            super(provider);
+        }
+
+        /**
+         * Returns an operation set identifying this channel's supported
+         * operations.
+         *
+         * <p> Pipe-source channels only support reading, so this method
+         * returns {@link SelectionKey#OP_READ}.  </p>
+         *
+         * @return  The valid-operation set
+         */
+        public final int validOps() {
+            return SelectionKey.OP_READ;
+        }
+
+    }
+
+    /**
+     * A channel representing the writable end of a {@link Pipe}.
+     *
+     * @since 1.4
+     */
+    public static abstract class SinkChannel
+        extends AbstractSelectableChannel
+        implements WritableByteChannel, GatheringByteChannel
+    {
+        /**
+         * Initializes a new instance of this class.
+         *
+         * @param  provider
+         *         The selector provider
+         */
+        protected SinkChannel(SelectorProvider provider) {
+            super(provider);
+        }
+
+        /**
+         * Returns an operation set identifying this channel's supported
+         * operations.
+         *
+         * <p> Pipe-sink channels only support writing, so this method returns
+         * {@link SelectionKey#OP_WRITE}.  </p>
+         *
+         * @return  The valid-operation set
+         */
+        public final int validOps() {
+            return SelectionKey.OP_WRITE;
+        }
+
+    }
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected Pipe() { }
+
+    /**
+     * Returns this pipe's source channel.
+     *
+     * @return  This pipe's source channel
+     */
+    public abstract SourceChannel source();
+
+    /**
+     * Returns this pipe's sink channel.
+     *
+     * @return  This pipe's sink channel
+     */
+    public abstract SinkChannel sink();
+
+    /**
+     * Opens a pipe.
+     *
+     * <p> The new pipe is created by invoking the {@link
+     * java.nio.channels.spi.SelectorProvider#openPipe openPipe} method of the
+     * system-wide default {@link java.nio.channels.spi.SelectorProvider}
+     * object.  </p>
+     *
+     * @return  A new pipe
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static Pipe open() throws IOException {
+        return SelectorProvider.provider().openPipe();
+    }
+
+}
diff --git a/java/nio/channels/ReadPendingException.java b/java/nio/channels/ReadPendingException.java
new file mode 100644
index 0000000..770c9de
--- /dev/null
+++ b/java/nio/channels/ReadPendingException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to read from an
+ * asynchronous socket channel and a previous read has not completed.
+ *
+ * @since 1.7
+ */
+
+public class ReadPendingException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = 1986315242191227217L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ReadPendingException() { }
+
+}
diff --git a/java/nio/channels/ReadableByteChannel.java b/java/nio/channels/ReadableByteChannel.java
new file mode 100644
index 0000000..4cd99c0
--- /dev/null
+++ b/java/nio/channels/ReadableByteChannel.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2000, 2001, 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.nio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+
+/**
+ * A channel that can read bytes.
+ *
+ * <p> Only one read operation upon a readable channel may be in progress at
+ * any given time.  If one thread initiates a read operation upon a channel
+ * then any other thread that attempts to initiate another read operation will
+ * block until the first operation is complete.  Whether or not other kinds of
+ * I/O operations may proceed concurrently with a read operation depends upon
+ * the type of the channel. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface ReadableByteChannel extends Channel {
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * <p> An attempt is made to read up to <i>r</i> bytes from the channel,
+     * where <i>r</i> is the number of bytes remaining in the buffer, that is,
+     * <tt>dst.remaining()</tt>, at the moment this method is invoked.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is read, where
+     * <tt>0</tt>&nbsp;<tt>&lt;=</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * This byte sequence will be transferred into the buffer so that the first
+     * byte in the sequence is at index <i>p</i> and the last byte is at index
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>&nbsp;<tt>-</tt>&nbsp;<tt>1</tt>,
+     * where <i>p</i> is the buffer's position at the moment this method is
+     * invoked.  Upon return the buffer's position will be equal to
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>; its limit will not have changed.
+     *
+     * <p> A read operation might not fill the buffer, and in fact it might not
+     * read any bytes at all.  Whether or not it does so depends upon the
+     * nature and state of the channel.  A socket channel in non-blocking mode,
+     * for example, cannot read any more bytes than are immediately available
+     * from the socket's input buffer; similarly, a file channel cannot read
+     * any more bytes than remain in the file.  It is guaranteed, however, that
+     * if a channel is in blocking mode and there is at least one byte
+     * remaining in the buffer then this method will block until at least one
+     * byte is read.
+     *
+     * <p> This method may be invoked at any time.  If another thread has
+     * already initiated a read operation upon this channel, however, then an
+     * invocation of this method will block until the first operation is
+     * complete. </p>
+     *
+     * @param  dst
+     *         The buffer into which bytes are to be transferred
+     *
+     * @return  The number of bytes read, possibly zero, or <tt>-1</tt> if the
+     *          channel has reached end-of-stream
+     *
+     * @throws  NonReadableChannelException
+     *          If this channel was not opened for reading
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the read operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the read operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public int read(ByteBuffer dst) throws IOException;
+
+}
diff --git a/java/nio/channels/ScatteringByteChannel.java b/java/nio/channels/ScatteringByteChannel.java
new file mode 100644
index 0000000..7922909
--- /dev/null
+++ b/java/nio/channels/ScatteringByteChannel.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2000, 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.nio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+
+/**
+ * A channel that can read bytes into a sequence of buffers.
+ *
+ * <p> A <i>scattering</i> read operation reads, in a single invocation, a
+ * sequence of bytes into one or more of a given sequence of buffers.
+ * Scattering reads are often useful when implementing network protocols or
+ * file formats that, for example, group data into segments consisting of one
+ * or more fixed-length headers followed by a variable-length body.  Similar
+ * <i>gathering</i> write operations are defined in the {@link
+ * GatheringByteChannel} interface.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface ScatteringByteChannel
+    extends ReadableByteChannel
+{
+
+    /**
+     * Reads a sequence of bytes from this channel into a subsequence of the
+     * given buffers.
+     *
+     * <p> An invocation of this method attempts to read up to <i>r</i> bytes
+     * from this channel, where <i>r</i> is the total number of bytes remaining
+     * the specified subsequence of the given buffer array, that is,
+     *
+     * <blockquote><pre>
+     * dsts[offset].remaining()
+     *     + dsts[offset+1].remaining()
+     *     + ... + dsts[offset+length-1].remaining()</pre></blockquote>
+     *
+     * at the moment that this method is invoked.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is read, where
+     * <tt>0</tt>&nbsp;<tt>&lt;=</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * Up to the first <tt>dsts[offset].remaining()</tt> bytes of this sequence
+     * are transferred into buffer <tt>dsts[offset]</tt>, up to the next
+     * <tt>dsts[offset+1].remaining()</tt> bytes are transferred into buffer
+     * <tt>dsts[offset+1]</tt>, and so forth, until the entire byte sequence
+     * is transferred into the given buffers.  As many bytes as possible are
+     * transferred into each buffer, hence the final position of each updated
+     * buffer, except the last updated buffer, is guaranteed to be equal to
+     * that buffer's limit.
+     *
+     * <p> This method may be invoked at any time.  If another thread has
+     * already initiated a read operation upon this channel, however, then an
+     * invocation of this method will block until the first operation is
+     * complete. </p>
+     *
+     * @param  dsts
+     *         The buffers into which bytes are to be transferred
+     *
+     * @param  offset
+     *         The offset within the buffer array of the first buffer into
+     *         which bytes are to be transferred; must be non-negative and no
+     *         larger than <tt>dsts.length</tt>
+     *
+     * @param  length
+     *         The maximum number of buffers to be accessed; must be
+     *         non-negative and no larger than
+     *         <tt>dsts.length</tt>&nbsp;-&nbsp;<tt>offset</tt>
+     *
+     * @return The number of bytes read, possibly zero,
+     *         or <tt>-1</tt> if the channel has reached end-of-stream
+     *
+     * @throws  IndexOutOfBoundsException
+     *          If the preconditions on the <tt>offset</tt> and <tt>length</tt>
+     *          parameters do not hold
+     *
+     * @throws  NonReadableChannelException
+     *          If this channel was not opened for reading
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the read operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the read operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public long read(ByteBuffer[] dsts, int offset, int length)
+        throws IOException;
+
+    /**
+     * Reads a sequence of bytes from this channel into the given buffers.
+     *
+     * <p> An invocation of this method of the form <tt>c.read(dsts)</tt>
+     * behaves in exactly the same manner as the invocation
+     *
+     * <blockquote><pre>
+     * c.read(dsts, 0, dsts.length);</pre></blockquote>
+     *
+     * @param  dsts
+     *         The buffers into which bytes are to be transferred
+     *
+     * @return The number of bytes read, possibly zero,
+     *         or <tt>-1</tt> if the channel has reached end-of-stream
+     *
+     * @throws  NonReadableChannelException
+     *          If this channel was not opened for reading
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the read operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the read operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public long read(ByteBuffer[] dsts) throws IOException;
+
+}
diff --git a/java/nio/channels/SeekableByteChannel.java b/java/nio/channels/SeekableByteChannel.java
new file mode 100644
index 0000000..3f5be1c
--- /dev/null
+++ b/java/nio/channels/SeekableByteChannel.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels;
+
+import java.nio.ByteBuffer;
+import java.io.IOException;
+
+/**
+ * A byte channel that maintains a current <i>position</i> and allows the
+ * position to be changed.
+ *
+ * <p> A seekable byte channel is connected to an entity, typically a file,
+ * that contains a variable-length sequence of bytes that can be read and
+ * written. The current position can be {@link #position() <i>queried</i>} and
+ * {@link #position(long) <i>modified</i>}. The channel also provides access to
+ * the current <i>size</i> of the entity to which the channel is connected. The
+ * size increases when bytes are written beyond its current size; the size
+ * decreases when it is {@link #truncate <i>truncated</i>}.
+ *
+ * <p> The {@link #position(long) position} and {@link #truncate truncate} methods
+ * which do not otherwise have a value to return are specified to return the
+ * channel upon which they are invoked. This allows method invocations to be
+ * chained. Implementations of this interface should specialize the return type
+ * so that method invocations on the implementation class can be chained.
+ *
+ * @since 1.7
+ * @see java.nio.file.Files#newByteChannel
+ */
+
+public interface SeekableByteChannel
+    extends ByteChannel
+{
+    /**
+     * Reads a sequence of bytes from this channel into the given buffer.
+     *
+     * <p> Bytes are read starting at this channel's current position, and
+     * then the position is updated with the number of bytes actually read.
+     * Otherwise this method behaves exactly as specified in the {@link
+     * ReadableByteChannel} interface.
+     */
+    @Override
+    int read(ByteBuffer dst) throws IOException;
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * <p> Bytes are written starting at this channel's current position, unless
+     * the channel is connected to an entity such as a file that is opened with
+     * the {@link java.nio.file.StandardOpenOption#APPEND APPEND} option, in
+     * which case the position is first advanced to the end. The entity to which
+     * the channel is connected is grown, if necessary, to accommodate the
+     * written bytes, and then the position is updated with the number of bytes
+     * actually written. Otherwise this method behaves exactly as specified by
+     * the {@link WritableByteChannel} interface.
+     */
+    @Override
+    int write(ByteBuffer src) throws IOException;
+
+    /**
+     * Returns this channel's position.
+     *
+     * @return  This channel's position,
+     *          a non-negative integer counting the number of bytes
+     *          from the beginning of the entity to the current position
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    long position() throws IOException;
+
+    /**
+     * Sets this channel's position.
+     *
+     * <p> Setting the position to a value that is greater than the current size
+     * is legal but does not change the size of the entity.  A later attempt to
+     * read bytes at such a position will immediately return an end-of-file
+     * indication.  A later attempt to write bytes at such a position will cause
+     * the entity to grow to accommodate the new bytes; the values of any bytes
+     * between the previous end-of-file and the newly-written bytes are
+     * unspecified.
+     *
+     * <p> Setting the channel's position is not recommended when connected to
+     * an entity, typically a file, that is opened with the {@link
+     * java.nio.file.StandardOpenOption#APPEND APPEND} option. When opened for
+     * append, the position is first advanced to the end before writing.
+     *
+     * @param  newPosition
+     *         The new position, a non-negative integer counting
+     *         the number of bytes from the beginning of the entity
+     *
+     * @return  This channel
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IllegalArgumentException
+     *          If the new position is negative
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    SeekableByteChannel position(long newPosition) throws IOException;
+
+    /**
+     * Returns the current size of entity to which this channel is connected.
+     *
+     * @return  The current size, measured in bytes
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    long size() throws IOException;
+
+    /**
+     * Truncates the entity, to which this channel is connected, to the given
+     * size.
+     *
+     * <p> If the given size is less than the current size then the entity is
+     * truncated, discarding any bytes beyond the new end. If the given size is
+     * greater than or equal to the current size then the entity is not modified.
+     * In either case, if the current position is greater than the given size
+     * then it is set to that size.
+     *
+     * <p> An implementation of this interface may prohibit truncation when
+     * connected to an entity, typically a file, opened with the {@link
+     * java.nio.file.StandardOpenOption#APPEND APPEND} option.
+     *
+     * @param  size
+     *         The new size, a non-negative byte count
+     *
+     * @return  This channel
+     *
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IllegalArgumentException
+     *          If the new size is negative
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    SeekableByteChannel truncate(long size) throws IOException;
+}
diff --git a/java/nio/channels/SelectableChannel.java b/java/nio/channels/SelectableChannel.java
new file mode 100644
index 0000000..997d5c5
--- /dev/null
+++ b/java/nio/channels/SelectableChannel.java
@@ -0,0 +1,344 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels;
+
+import java.io.IOException;
+import java.nio.channels.spi.AbstractInterruptibleChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+
+/**
+ * A channel that can be multiplexed via a {@link Selector}.
+ *
+ * <p> In order to be used with a selector, an instance of this class must
+ * first be <i>registered</i> via the {@link #register(Selector,int,Object)
+ * register} method.  This method returns a new {@link SelectionKey} object
+ * that represents the channel's registration with the selector.
+ *
+ * <p> Once registered with a selector, a channel remains registered until it
+ * is <i>deregistered</i>.  This involves deallocating whatever resources were
+ * allocated to the channel by the selector.
+ *
+ * <p> A channel cannot be deregistered directly; instead, the key representing
+ * its registration must be <i>cancelled</i>.  Cancelling a key requests that
+ * the channel be deregistered during the selector's next selection operation.
+ * A key may be cancelled explicitly by invoking its {@link
+ * SelectionKey#cancel() cancel} method.  All of a channel's keys are cancelled
+ * implicitly when the channel is closed, whether by invoking its {@link
+ * Channel#close close} method or by interrupting a thread blocked in an I/O
+ * operation upon the channel.
+ *
+ * <p> If the selector itself is closed then the channel will be deregistered,
+ * and the key representing its registration will be invalidated, without
+ * further delay.
+ *
+ * <p> A channel may be registered at most once with any particular selector.
+ *
+ * <p> Whether or not a channel is registered with one or more selectors may be
+ * determined by invoking the {@link #isRegistered isRegistered} method.
+ *
+ * <p> Selectable channels are safe for use by multiple concurrent
+ * threads. </p>
+ *
+ *
+ * <a name="bm"></a>
+ * <h2>Blocking mode</h2>
+ *
+ * A selectable channel is either in <i>blocking</i> mode or in
+ * <i>non-blocking</i> mode.  In blocking mode, every I/O operation invoked
+ * upon the channel will block until it completes.  In non-blocking mode an I/O
+ * operation will never block and may transfer fewer bytes than were requested
+ * or possibly no bytes at all.  The blocking mode of a selectable channel may
+ * be determined by invoking its {@link #isBlocking isBlocking} method.
+ *
+ * <p> Newly-created selectable channels are always in blocking mode.
+ * Non-blocking mode is most useful in conjunction with selector-based
+ * multiplexing.  A channel must be placed into non-blocking mode before being
+ * registered with a selector, and may not be returned to blocking mode until
+ * it has been deregistered.
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see SelectionKey
+ * @see Selector
+ */
+
+public abstract class SelectableChannel
+    extends AbstractInterruptibleChannel
+    implements Channel
+{
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected SelectableChannel() { }
+
+    /**
+     * Returns the provider that created this channel.
+     *
+     * @return  The provider that created this channel
+     */
+    public abstract SelectorProvider provider();
+
+    /**
+     * Returns an <a href="SelectionKey.html#opsets">operation set</a>
+     * identifying this channel's supported operations.  The bits that are set
+     * in this integer value denote exactly the operations that are valid for
+     * this channel.  This method always returns the same value for a given
+     * concrete channel class.
+     *
+     * @return  The valid-operation set
+     */
+    public abstract int validOps();
+
+    // Internal state:
+    //   keySet, may be empty but is never null, typ. a tiny array
+    //   boolean isRegistered, protected by key set
+    //   regLock, lock object to prevent duplicate registrations
+    //   boolean isBlocking, protected by regLock
+
+    /**
+     * Tells whether or not this channel is currently registered with any
+     * selectors.  A newly-created channel is not registered.
+     *
+     * <p> Due to the inherent delay between key cancellation and channel
+     * deregistration, a channel may remain registered for some time after all
+     * of its keys have been cancelled.  A channel may also remain registered
+     * for some time after it is closed.  </p>
+     *
+     * @return <tt>true</tt> if, and only if, this channel is registered
+     */
+    public abstract boolean isRegistered();
+    //
+    // sync(keySet) { return isRegistered; }
+
+    /**
+     * Retrieves the key representing the channel's registration with the given
+     * selector.
+     *
+     * @param   sel
+     *          The selector
+     *
+     * @return  The key returned when this channel was last registered with the
+     *          given selector, or <tt>null</tt> if this channel is not
+     *          currently registered with that selector
+     */
+    public abstract SelectionKey keyFor(Selector sel);
+    //
+    // sync(keySet) { return findKey(sel); }
+
+    /**
+     * Registers this channel with the given selector, returning a selection
+     * key.
+     *
+     * <p> If this channel is currently registered with the given selector then
+     * the selection key representing that registration is returned.  The key's
+     * interest set will have been changed to <tt>ops</tt>, as if by invoking
+     * the {@link SelectionKey#interestOps(int) interestOps(int)} method.  If
+     * the <tt>att</tt> argument is not <tt>null</tt> then the key's attachment
+     * will have been set to that value.  A {@link CancelledKeyException} will
+     * be thrown if the key has already been cancelled.
+     *
+     * <p> Otherwise this channel has not yet been registered with the given
+     * selector, so it is registered and the resulting new key is returned.
+     * The key's initial interest set will be <tt>ops</tt> and its attachment
+     * will be <tt>att</tt>.
+     *
+     * <p> This method may be invoked at any time.  If this method is invoked
+     * while another invocation of this method or of the {@link
+     * #configureBlocking(boolean) configureBlocking} method is in progress
+     * then it will first block until the other operation is complete.  This
+     * method will then synchronize on the selector's key set and therefore may
+     * block if invoked concurrently with another registration or selection
+     * operation involving the same selector. </p>
+     *
+     * <p> If this channel is closed while this operation is in progress then
+     * the key returned by this method will have been cancelled and will
+     * therefore be invalid. </p>
+     *
+     * @param  sel
+     *         The selector with which this channel is to be registered
+     *
+     * @param  ops
+     *         The interest set for the resulting key
+     *
+     * @param  att
+     *         The attachment for the resulting key; may be <tt>null</tt>
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  ClosedSelectorException
+     *          If the selector is closed
+     *
+     * @throws  IllegalBlockingModeException
+     *          If this channel is in blocking mode
+     *
+     * @throws  IllegalSelectorException
+     *          If this channel was not created by the same provider
+     *          as the given selector
+     *
+     * @throws  CancelledKeyException
+     *          If this channel is currently registered with the given selector
+     *          but the corresponding key has already been cancelled
+     *
+     * @throws  IllegalArgumentException
+     *          If a bit in the <tt>ops</tt> set does not correspond to an
+     *          operation that is supported by this channel, that is, if
+     *          {@code set & ~validOps() != 0}
+     *
+     * @return  A key representing the registration of this channel with
+     *          the given selector
+     */
+    public abstract SelectionKey register(Selector sel, int ops, Object att)
+        throws ClosedChannelException;
+    //
+    // sync(regLock) {
+    //   sync(keySet) { look for selector }
+    //   if (channel found) { set interest ops -- may block in selector;
+    //                        return key; }
+    //   create new key -- may block somewhere in selector;
+    //   sync(keySet) { add key; }
+    //   attach(attachment);
+    //   return key;
+    // }
+
+    /**
+     * Registers this channel with the given selector, returning a selection
+     * key.
+     *
+     * <p> An invocation of this convenience method of the form
+     *
+     * <blockquote><tt>sc.register(sel, ops)</tt></blockquote>
+     *
+     * behaves in exactly the same way as the invocation
+     *
+     * <blockquote><tt>sc.{@link
+     * #register(java.nio.channels.Selector,int,java.lang.Object)
+     * register}(sel, ops, null)</tt></blockquote>
+     *
+     * @param  sel
+     *         The selector with which this channel is to be registered
+     *
+     * @param  ops
+     *         The interest set for the resulting key
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  ClosedSelectorException
+     *          If the selector is closed
+     *
+     * @throws  IllegalBlockingModeException
+     *          If this channel is in blocking mode
+     *
+     * @throws  IllegalSelectorException
+     *          If this channel was not created by the same provider
+     *          as the given selector
+     *
+     * @throws  CancelledKeyException
+     *          If this channel is currently registered with the given selector
+     *          but the corresponding key has already been cancelled
+     *
+     * @throws  IllegalArgumentException
+     *          If a bit in <tt>ops</tt> does not correspond to an operation
+     *          that is supported by this channel, that is, if {@code set &
+     *          ~validOps() != 0}
+     *
+     * @return  A key representing the registration of this channel with
+     *          the given selector
+     */
+    public final SelectionKey register(Selector sel, int ops)
+        throws ClosedChannelException
+    {
+        return register(sel, ops, null);
+    }
+
+    /**
+     * Adjusts this channel's blocking mode.
+     *
+     * <p> If this channel is registered with one or more selectors then an
+     * attempt to place it into blocking mode will cause an {@link
+     * IllegalBlockingModeException} to be thrown.
+     *
+     * <p> This method may be invoked at any time.  The new blocking mode will
+     * only affect I/O operations that are initiated after this method returns.
+     * For some implementations this may require blocking until all pending I/O
+     * operations are complete.
+     *
+     * <p> If this method is invoked while another invocation of this method or
+     * of the {@link #register(Selector, int) register} method is in progress
+     * then it will first block until the other operation is complete. </p>
+     *
+     * @param  block  If <tt>true</tt> then this channel will be placed in
+     *                blocking mode; if <tt>false</tt> then it will be placed
+     *                non-blocking mode
+     *
+     * @return  This selectable channel
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  IllegalBlockingModeException
+     *          If <tt>block</tt> is <tt>true</tt> and this channel is
+     *          registered with one or more selectors
+     *
+     * @throws IOException
+     *         If an I/O error occurs
+     */
+    public abstract SelectableChannel configureBlocking(boolean block)
+        throws IOException;
+    //
+    // sync(regLock) {
+    //   sync(keySet) { throw IBME if block && isRegistered; }
+    //   change mode;
+    // }
+
+    /**
+     * Tells whether or not every I/O operation on this channel will block
+     * until it completes.  A newly-created channel is always in blocking mode.
+     *
+     * <p> If this channel is closed then the value returned by this method is
+     * not specified. </p>
+     *
+     * @return <tt>true</tt> if, and only if, this channel is in blocking mode
+     */
+    public abstract boolean isBlocking();
+
+    /**
+     * Retrieves the object upon which the {@link #configureBlocking
+     * configureBlocking} and {@link #register register} methods synchronize.
+     * This is often useful in the implementation of adaptors that require a
+     * specific blocking mode to be maintained for a short period of time.
+     *
+     * @return  The blocking-mode lock object
+     */
+    public abstract Object blockingLock();
+
+}
diff --git a/java/nio/channels/SelectionKey.java b/java/nio/channels/SelectionKey.java
new file mode 100644
index 0000000..00ea670
--- /dev/null
+++ b/java/nio/channels/SelectionKey.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels;
+
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import java.io.IOException;
+
+
+/**
+ * A token representing the registration of a {@link SelectableChannel} with a
+ * {@link Selector}.
+ *
+ * <p> A selection key is created each time a channel is registered with a
+ * selector.  A key remains valid until it is <i>cancelled</i> by invoking its
+ * {@link #cancel cancel} method, by closing its channel, or by closing its
+ * selector.  Cancelling a key does not immediately remove it from its
+ * selector; it is instead added to the selector's <a
+ * href="Selector.html#ks"><i>cancelled-key set</i></a> for removal during the
+ * next selection operation.  The validity of a key may be tested by invoking
+ * its {@link #isValid isValid} method.
+ *
+ * <a name="opsets"></a>
+ *
+ * <p> A selection key contains two <i>operation sets</i> represented as
+ * integer values.  Each bit of an operation set denotes a category of
+ * selectable operations that are supported by the key's channel.
+ *
+ * <ul>
+ *
+ *   <li><p> The <i>interest set</i> determines which operation categories will
+ *   be tested for readiness the next time one of the selector's selection
+ *   methods is invoked.  The interest set is initialized with the value given
+ *   when the key is created; it may later be changed via the {@link
+ *   #interestOps(int)} method. </p></li>
+ *
+ *   <li><p> The <i>ready set</i> identifies the operation categories for which
+ *   the key's channel has been detected to be ready by the key's selector.
+ *   The ready set is initialized to zero when the key is created; it may later
+ *   be updated by the selector during a selection operation, but it cannot be
+ *   updated directly. </p></li>
+ *
+ * </ul>
+ *
+ * <p> That a selection key's ready set indicates that its channel is ready for
+ * some operation category is a hint, but not a guarantee, that an operation in
+ * such a category may be performed by a thread without causing the thread to
+ * block.  A ready set is most likely to be accurate immediately after the
+ * completion of a selection operation.  It is likely to be made inaccurate by
+ * external events and by I/O operations that are invoked upon the
+ * corresponding channel.
+ *
+ * <p> This class defines all known operation-set bits, but precisely which
+ * bits are supported by a given channel depends upon the type of the channel.
+ * Each subclass of {@link SelectableChannel} defines an {@link
+ * SelectableChannel#validOps() validOps()} method which returns a set
+ * identifying just those operations that are supported by the channel.  An
+ * attempt to set or test an operation-set bit that is not supported by a key's
+ * channel will result in an appropriate run-time exception.
+ *
+ * <p> It is often necessary to associate some application-specific data with a
+ * selection key, for example an object that represents the state of a
+ * higher-level protocol and handles readiness notifications in order to
+ * implement that protocol.  Selection keys therefore support the
+ * <i>attachment</i> of a single arbitrary object to a key.  An object can be
+ * attached via the {@link #attach attach} method and then later retrieved via
+ * the {@link #attachment() attachment} method.
+ *
+ * <p> Selection keys are safe for use by multiple concurrent threads.  The
+ * operations of reading and writing the interest set will, in general, be
+ * synchronized with certain operations of the selector.  Exactly how this
+ * synchronization is performed is implementation-dependent: In a naive
+ * implementation, reading or writing the interest set may block indefinitely
+ * if a selection operation is already in progress; in a high-performance
+ * implementation, reading or writing the interest set may block briefly, if at
+ * all.  In any case, a selection operation will always use the interest-set
+ * value that was current at the moment that the operation began.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see SelectableChannel
+ * @see Selector
+ */
+
+public abstract class SelectionKey {
+
+    /**
+     * Constructs an instance of this class.
+     */
+    protected SelectionKey() { }
+
+
+    // -- Channel and selector operations --
+
+    /**
+     * Returns the channel for which this key was created.  This method will
+     * continue to return the channel even after the key is cancelled.
+     *
+     * @return  This key's channel
+     */
+    public abstract SelectableChannel channel();
+
+    /**
+     * Returns the selector for which this key was created.  This method will
+     * continue to return the selector even after the key is cancelled.
+     *
+     * @return  This key's selector
+     */
+    public abstract Selector selector();
+
+    /**
+     * Tells whether or not this key is valid.
+     *
+     * <p> A key is valid upon creation and remains so until it is cancelled,
+     * its channel is closed, or its selector is closed.  </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this key is valid
+     */
+    public abstract boolean isValid();
+
+    /**
+     * Requests that the registration of this key's channel with its selector
+     * be cancelled.  Upon return the key will be invalid and will have been
+     * added to its selector's cancelled-key set.  The key will be removed from
+     * all of the selector's key sets during the next selection operation.
+     *
+     * <p> If this key has already been cancelled then invoking this method has
+     * no effect.  Once cancelled, a key remains forever invalid. </p>
+     *
+     * <p> This method may be invoked at any time.  It synchronizes on the
+     * selector's cancelled-key set, and therefore may block briefly if invoked
+     * concurrently with a cancellation or selection operation involving the
+     * same selector.  </p>
+     */
+    public abstract void cancel();
+
+
+    // -- Operation-set accessors --
+
+    /**
+     * Retrieves this key's interest set.
+     *
+     * <p> It is guaranteed that the returned set will only contain operation
+     * bits that are valid for this key's channel.
+     *
+     * <p> This method may be invoked at any time.  Whether or not it blocks,
+     * and for how long, is implementation-dependent.  </p>
+     *
+     * @return  This key's interest set
+     *
+     * @throws  CancelledKeyException
+     *          If this key has been cancelled
+     */
+    public abstract int interestOps();
+
+    /**
+     * Sets this key's interest set to the given value.
+     *
+     * <p> This method may be invoked at any time.  Whether or not it blocks,
+     * and for how long, is implementation-dependent.  </p>
+     *
+     * @param  ops  The new interest set
+     *
+     * @return  This selection key
+     *
+     * @throws  IllegalArgumentException
+     *          If a bit in the set does not correspond to an operation that
+     *          is supported by this key's channel, that is, if
+     *          {@code (ops & ~channel().validOps()) != 0}
+     *
+     * @throws  CancelledKeyException
+     *          If this key has been cancelled
+     */
+    public abstract SelectionKey interestOps(int ops);
+
+    /**
+     * Retrieves this key's ready-operation set.
+     *
+     * <p> It is guaranteed that the returned set will only contain operation
+     * bits that are valid for this key's channel.  </p>
+     *
+     * @return  This key's ready-operation set
+     *
+     * @throws  CancelledKeyException
+     *          If this key has been cancelled
+     */
+    public abstract int readyOps();
+
+
+    // -- Operation bits and bit-testing convenience methods --
+
+    /**
+     * Operation-set bit for read operations.
+     *
+     * <p> Suppose that a selection key's interest set contains
+     * <tt>OP_READ</tt> at the start of a <a
+     * href="Selector.html#selop">selection operation</a>.  If the selector
+     * detects that the corresponding channel is ready for reading, has reached
+     * end-of-stream, has been remotely shut down for further reading, or has
+     * an error pending, then it will add <tt>OP_READ</tt> to the key's
+     * ready-operation set and add the key to its selected-key&nbsp;set.  </p>
+     */
+    public static final int OP_READ = 1 << 0;
+
+    /**
+     * Operation-set bit for write operations.
+     *
+     * <p> Suppose that a selection key's interest set contains
+     * <tt>OP_WRITE</tt> at the start of a <a
+     * href="Selector.html#selop">selection operation</a>.  If the selector
+     * detects that the corresponding channel is ready for writing, has been
+     * remotely shut down for further writing, or has an error pending, then it
+     * will add <tt>OP_WRITE</tt> to the key's ready set and add the key to its
+     * selected-key&nbsp;set.  </p>
+     */
+    public static final int OP_WRITE = 1 << 2;
+
+    /**
+     * Operation-set bit for socket-connect operations.
+     *
+     * <p> Suppose that a selection key's interest set contains
+     * <tt>OP_CONNECT</tt> at the start of a <a
+     * href="Selector.html#selop">selection operation</a>.  If the selector
+     * detects that the corresponding socket channel is ready to complete its
+     * connection sequence, or has an error pending, then it will add
+     * <tt>OP_CONNECT</tt> to the key's ready set and add the key to its
+     * selected-key&nbsp;set.  </p>
+     */
+    public static final int OP_CONNECT = 1 << 3;
+
+    /**
+     * Operation-set bit for socket-accept operations.
+     *
+     * <p> Suppose that a selection key's interest set contains
+     * <tt>OP_ACCEPT</tt> at the start of a <a
+     * href="Selector.html#selop">selection operation</a>.  If the selector
+     * detects that the corresponding server-socket channel is ready to accept
+     * another connection, or has an error pending, then it will add
+     * <tt>OP_ACCEPT</tt> to the key's ready set and add the key to its
+     * selected-key&nbsp;set.  </p>
+     */
+    public static final int OP_ACCEPT = 1 << 4;
+
+    /**
+     * Tests whether this key's channel is ready for reading.
+     *
+     * <p> An invocation of this method of the form <tt>k.isReadable()</tt>
+     * behaves in exactly the same way as the expression
+     *
+     * <blockquote><pre>{@code
+     * k.readyOps() & OP_READ != 0
+     * }</pre></blockquote>
+     *
+     * <p> If this key's channel does not support read operations then this
+     * method always returns <tt>false</tt>.  </p>
+     *
+     * @return  <tt>true</tt> if, and only if,
+                {@code readyOps() & OP_READ} is nonzero
+     *
+     * @throws  CancelledKeyException
+     *          If this key has been cancelled
+     */
+    public final boolean isReadable() {
+        return (readyOps() & OP_READ) != 0;
+    }
+
+    /**
+     * Tests whether this key's channel is ready for writing.
+     *
+     * <p> An invocation of this method of the form <tt>k.isWritable()</tt>
+     * behaves in exactly the same way as the expression
+     *
+     * <blockquote><pre>{@code
+     * k.readyOps() & OP_WRITE != 0
+     * }</pre></blockquote>
+     *
+     * <p> If this key's channel does not support write operations then this
+     * method always returns <tt>false</tt>.  </p>
+     *
+     * @return  <tt>true</tt> if, and only if,
+     *          {@code readyOps() & OP_WRITE} is nonzero
+     *
+     * @throws  CancelledKeyException
+     *          If this key has been cancelled
+     */
+    public final boolean isWritable() {
+        return (readyOps() & OP_WRITE) != 0;
+    }
+
+    /**
+     * Tests whether this key's channel has either finished, or failed to
+     * finish, its socket-connection operation.
+     *
+     * <p> An invocation of this method of the form <tt>k.isConnectable()</tt>
+     * behaves in exactly the same way as the expression
+     *
+     * <blockquote><pre>{@code
+     * k.readyOps() & OP_CONNECT != 0
+     * }</pre></blockquote>
+     *
+     * <p> If this key's channel does not support socket-connect operations
+     * then this method always returns <tt>false</tt>.  </p>
+     *
+     * @return  <tt>true</tt> if, and only if,
+     *          {@code readyOps() & OP_CONNECT} is nonzero
+     *
+     * @throws  CancelledKeyException
+     *          If this key has been cancelled
+     */
+    public final boolean isConnectable() {
+        return (readyOps() & OP_CONNECT) != 0;
+    }
+
+    /**
+     * Tests whether this key's channel is ready to accept a new socket
+     * connection.
+     *
+     * <p> An invocation of this method of the form <tt>k.isAcceptable()</tt>
+     * behaves in exactly the same way as the expression
+     *
+     * <blockquote><pre>{@code
+     * k.readyOps() & OP_ACCEPT != 0
+     * }</pre></blockquote>
+     *
+     * <p> If this key's channel does not support socket-accept operations then
+     * this method always returns <tt>false</tt>.  </p>
+     *
+     * @return  <tt>true</tt> if, and only if,
+     *          {@code readyOps() & OP_ACCEPT} is nonzero
+     *
+     * @throws  CancelledKeyException
+     *          If this key has been cancelled
+     */
+    public final boolean isAcceptable() {
+        return (readyOps() & OP_ACCEPT) != 0;
+    }
+
+
+    // -- Attachments --
+
+    private volatile Object attachment = null;
+
+    private static final AtomicReferenceFieldUpdater<SelectionKey,Object>
+        attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater(
+            SelectionKey.class, Object.class, "attachment"
+        );
+
+    /**
+     * Attaches the given object to this key.
+     *
+     * <p> An attached object may later be retrieved via the {@link #attachment()
+     * attachment} method.  Only one object may be attached at a time; invoking
+     * this method causes any previous attachment to be discarded.  The current
+     * attachment may be discarded by attaching <tt>null</tt>.  </p>
+     *
+     * @param  ob
+     *         The object to be attached; may be <tt>null</tt>
+     *
+     * @return  The previously-attached object, if any,
+     *          otherwise <tt>null</tt>
+     */
+    public final Object attach(Object ob) {
+        return attachmentUpdater.getAndSet(this, ob);
+    }
+
+    /**
+     * Retrieves the current attachment.
+     *
+     * @return  The object currently attached to this key,
+     *          or <tt>null</tt> if there is no attachment
+     */
+    public final Object attachment() {
+        return attachment;
+    }
+
+}
diff --git a/java/nio/channels/Selector.java b/java/nio/channels/Selector.java
new file mode 100644
index 0000000..ea72acb
--- /dev/null
+++ b/java/nio/channels/Selector.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.nio.channels.spi.SelectorProvider;
+import java.util.Set;
+
+
+/**
+ * A multiplexor of {@link SelectableChannel} objects.
+ *
+ * <p> A selector may be created by invoking the {@link #open open} method of
+ * this class, which will use the system's default {@link
+ * java.nio.channels.spi.SelectorProvider selector provider} to
+ * create a new selector.  A selector may also be created by invoking the
+ * {@link java.nio.channels.spi.SelectorProvider#openSelector openSelector}
+ * method of a custom selector provider.  A selector remains open until it is
+ * closed via its {@link #close close} method.
+ *
+ * <a name="ks"></a>
+ *
+ * <p> A selectable channel's registration with a selector is represented by a
+ * {@link SelectionKey} object.  A selector maintains three sets of selection
+ * keys:
+ *
+ * <ul>
+ *
+ *   <li><p> The <i>key set</i> contains the keys representing the current
+ *   channel registrations of this selector.  This set is returned by the
+ *   {@link #keys() keys} method. </p></li>
+ *
+ *   <li><p> The <i>selected-key set</i> is the set of keys such that each
+ *   key's channel was detected to be ready for at least one of the operations
+ *   identified in the key's interest set during a prior selection operation.
+ *   This set is returned by the {@link #selectedKeys() selectedKeys} method.
+ *   The selected-key set is always a subset of the key set. </p></li>
+ *
+ *   <li><p> The <i>cancelled-key</i> set is the set of keys that have been
+ *   cancelled but whose channels have not yet been deregistered.  This set is
+ *   not directly accessible.  The cancelled-key set is always a subset of the
+ *   key set. </p></li>
+ *
+ * </ul>
+ *
+ * <p> All three sets are empty in a newly-created selector.
+ *
+ * <p> A key is added to a selector's key set as a side effect of registering a
+ * channel via the channel's {@link SelectableChannel#register(Selector,int)
+ * register} method.  Cancelled keys are removed from the key set during
+ * selection operations.  The key set itself is not directly modifiable.
+ *
+ * <p> A key is added to its selector's cancelled-key set when it is cancelled,
+ * whether by closing its channel or by invoking its {@link SelectionKey#cancel
+ * cancel} method.  Cancelling a key will cause its channel to be deregistered
+ * during the next selection operation, at which time the key will removed from
+ * all of the selector's key sets.
+ *
+ * <a name="sks"></a><p> Keys are added to the selected-key set by selection
+ * operations.  A key may be removed directly from the selected-key set by
+ * invoking the set's {@link java.util.Set#remove(java.lang.Object) remove}
+ * method or by invoking the {@link java.util.Iterator#remove() remove} method
+ * of an {@link java.util.Iterator iterator} obtained from the
+ * set.  Keys are never removed from the selected-key set in any other way;
+ * they are not, in particular, removed as a side effect of selection
+ * operations.  Keys may not be added directly to the selected-key set. </p>
+ *
+ *
+ * <a name="selop"></a>
+ * <h2>Selection</h2>
+ *
+ * <p> During each selection operation, keys may be added to and removed from a
+ * selector's selected-key set and may be removed from its key and
+ * cancelled-key sets.  Selection is performed by the {@link #select()}, {@link
+ * #select(long)}, and {@link #selectNow()} methods, and involves three steps:
+ * </p>
+ *
+ * <ol>
+ *
+ *   <li><p> Each key in the cancelled-key set is removed from each key set of
+ *   which it is a member, and its channel is deregistered.  This step leaves
+ *   the cancelled-key set empty. </p></li>
+ *
+ *   <li><p> The underlying operating system is queried for an update as to the
+ *   readiness of each remaining channel to perform any of the operations
+ *   identified by its key's interest set as of the moment that the selection
+ *   operation began.  For a channel that is ready for at least one such
+ *   operation, one of the following two actions is performed: </p>
+ *
+ *   <ol>
+ *
+ *     <li><p> If the channel's key is not already in the selected-key set then
+ *     it is added to that set and its ready-operation set is modified to
+ *     identify exactly those operations for which the channel is now reported
+ *     to be ready.  Any readiness information previously recorded in the ready
+ *     set is discarded.  </p></li>
+ *
+ *     <li><p> Otherwise the channel's key is already in the selected-key set,
+ *     so its ready-operation set is modified to identify any new operations
+ *     for which the channel is reported to be ready.  Any readiness
+ *     information previously recorded in the ready set is preserved; in other
+ *     words, the ready set returned by the underlying system is
+ *     bitwise-disjoined into the key's current ready set. </p></li>
+ *
+ *   </ol>
+ *
+ *   If all of the keys in the key set at the start of this step have empty
+ *   interest sets then neither the selected-key set nor any of the keys'
+ *   ready-operation sets will be updated.
+ *
+ *   <li><p> If any keys were added to the cancelled-key set while step (2) was
+ *   in progress then they are processed as in step (1). </p></li>
+ *
+ * </ol>
+ *
+ * <p> Whether or not a selection operation blocks to wait for one or more
+ * channels to become ready, and if so for how long, is the only essential
+ * difference between the three selection methods. </p>
+ *
+ *
+ * <h2>Concurrency</h2>
+ *
+ * <p> Selectors are themselves safe for use by multiple concurrent threads;
+ * their key sets, however, are not.
+ *
+ * <p> The selection operations synchronize on the selector itself, on the key
+ * set, and on the selected-key set, in that order.  They also synchronize on
+ * the cancelled-key set during steps (1) and (3) above.
+ *
+ * <p> Changes made to the interest sets of a selector's keys while a
+ * selection operation is in progress have no effect upon that operation; they
+ * will be seen by the next selection operation.
+ *
+ * <p> Keys may be cancelled and channels may be closed at any time.  Hence the
+ * presence of a key in one or more of a selector's key sets does not imply
+ * that the key is valid or that its channel is open.  Application code should
+ * be careful to synchronize and check these conditions as necessary if there
+ * is any possibility that another thread will cancel a key or close a channel.
+ *
+ * <p> A thread blocked in one of the {@link #select()} or {@link
+ * #select(long)} methods may be interrupted by some other thread in one of
+ * three ways:
+ *
+ * <ul>
+ *
+ *   <li><p> By invoking the selector's {@link #wakeup wakeup} method,
+ *   </p></li>
+ *
+ *   <li><p> By invoking the selector's {@link #close close} method, or
+ *   </p></li>
+ *
+ *   <li><p> By invoking the blocked thread's {@link
+ *   java.lang.Thread#interrupt() interrupt} method, in which case its
+ *   interrupt status will be set and the selector's {@link #wakeup wakeup}
+ *   method will be invoked. </p></li>
+ *
+ * </ul>
+ *
+ * <p> The {@link #close close} method synchronizes on the selector and all
+ * three key sets in the same order as in a selection operation.
+ *
+ * <a name="ksc"></a>
+ *
+ * <p> A selector's key and selected-key sets are not, in general, safe for use
+ * by multiple concurrent threads.  If such a thread might modify one of these
+ * sets directly then access should be controlled by synchronizing on the set
+ * itself.  The iterators returned by these sets' {@link
+ * java.util.Set#iterator() iterator} methods are <i>fail-fast:</i> If the set
+ * is modified after the iterator is created, in any way except by invoking the
+ * iterator's own {@link java.util.Iterator#remove() remove} method, then a
+ * {@link java.util.ConcurrentModificationException} will be thrown. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see SelectableChannel
+ * @see SelectionKey
+ */
+
+public abstract class Selector implements Closeable {
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected Selector() { }
+
+    /**
+     * Opens a selector.
+     *
+     * <p> The new selector is created by invoking the {@link
+     * java.nio.channels.spi.SelectorProvider#openSelector openSelector} method
+     * of the system-wide default {@link
+     * java.nio.channels.spi.SelectorProvider} object.  </p>
+     *
+     * @return  A new selector
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static Selector open() throws IOException {
+        return SelectorProvider.provider().openSelector();
+    }
+
+    /**
+     * Tells whether or not this selector is open.
+     *
+     * @return <tt>true</tt> if, and only if, this selector is open
+     */
+    public abstract boolean isOpen();
+
+    /**
+     * Returns the provider that created this channel.
+     *
+     * @return  The provider that created this channel
+     */
+    public abstract SelectorProvider provider();
+
+    /**
+     * Returns this selector's key set.
+     *
+     * <p> The key set is not directly modifiable.  A key is removed only after
+     * it has been cancelled and its channel has been deregistered.  Any
+     * attempt to modify the key set will cause an {@link
+     * UnsupportedOperationException} to be thrown.
+     *
+     * <p> The key set is <a href="#ksc">not thread-safe</a>. </p>
+     *
+     * @return  This selector's key set
+     *
+     * @throws  ClosedSelectorException
+     *          If this selector is closed
+     */
+    public abstract Set<SelectionKey> keys();
+
+    /**
+     * Returns this selector's selected-key set.
+     *
+     * <p> Keys may be removed from, but not directly added to, the
+     * selected-key set.  Any attempt to add an object to the key set will
+     * cause an {@link UnsupportedOperationException} to be thrown.
+     *
+     * <p> The selected-key set is <a href="#ksc">not thread-safe</a>. </p>
+     *
+     * @return  This selector's selected-key set
+     *
+     * @throws  ClosedSelectorException
+     *          If this selector is closed
+     */
+    public abstract Set<SelectionKey> selectedKeys();
+
+    /**
+     * Selects a set of keys whose corresponding channels are ready for I/O
+     * operations.
+     *
+     * <p> This method performs a non-blocking <a href="#selop">selection
+     * operation</a>.  If no channels have become selectable since the previous
+     * selection operation then this method immediately returns zero.
+     *
+     * <p> Invoking this method clears the effect of any previous invocations
+     * of the {@link #wakeup wakeup} method.  </p>
+     *
+     * @return  The number of keys, possibly zero, whose ready-operation sets
+     *          were updated by the selection operation
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @throws  ClosedSelectorException
+     *          If this selector is closed
+     */
+    public abstract int selectNow() throws IOException;
+
+    /**
+     * Selects a set of keys whose corresponding channels are ready for I/O
+     * operations.
+     *
+     * <p> This method performs a blocking <a href="#selop">selection
+     * operation</a>.  It returns only after at least one channel is selected,
+     * this selector's {@link #wakeup wakeup} method is invoked, the current
+     * thread is interrupted, or the given timeout period expires, whichever
+     * comes first.
+     *
+     * <p> This method does not offer real-time guarantees: It schedules the
+     * timeout as if by invoking the {@link Object#wait(long)} method. </p>
+     *
+     * @param  timeout  If positive, block for up to <tt>timeout</tt>
+     *                  milliseconds, more or less, while waiting for a
+     *                  channel to become ready; if zero, block indefinitely;
+     *                  must not be negative
+     *
+     * @return  The number of keys, possibly zero,
+     *          whose ready-operation sets were updated
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @throws  ClosedSelectorException
+     *          If this selector is closed
+     *
+     * @throws  IllegalArgumentException
+     *          If the value of the timeout argument is negative
+     */
+    public abstract int select(long timeout)
+        throws IOException;
+
+    /**
+     * Selects a set of keys whose corresponding channels are ready for I/O
+     * operations.
+     *
+     * <p> This method performs a blocking <a href="#selop">selection
+     * operation</a>.  It returns only after at least one channel is selected,
+     * this selector's {@link #wakeup wakeup} method is invoked, or the current
+     * thread is interrupted, whichever comes first.  </p>
+     *
+     * @return  The number of keys, possibly zero,
+     *          whose ready-operation sets were updated
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @throws  ClosedSelectorException
+     *          If this selector is closed
+     */
+    public abstract int select() throws IOException;
+
+    /**
+     * Causes the first selection operation that has not yet returned to return
+     * immediately.
+     *
+     * <p> If another thread is currently blocked in an invocation of the
+     * {@link #select()} or {@link #select(long)} methods then that invocation
+     * will return immediately.  If no selection operation is currently in
+     * progress then the next invocation of one of these methods will return
+     * immediately unless the {@link #selectNow()} method is invoked in the
+     * meantime.  In any case the value returned by that invocation may be
+     * non-zero.  Subsequent invocations of the {@link #select()} or {@link
+     * #select(long)} methods will block as usual unless this method is invoked
+     * again in the meantime.
+     *
+     * <p> Invoking this method more than once between two successive selection
+     * operations has the same effect as invoking it just once.  </p>
+     *
+     * @return  This selector
+     */
+    public abstract Selector wakeup();
+
+    /**
+     * Closes this selector.
+     *
+     * <p> If a thread is currently blocked in one of this selector's selection
+     * methods then it is interrupted as if by invoking the selector's {@link
+     * #wakeup wakeup} method.
+     *
+     * <p> Any uncancelled keys still associated with this selector are
+     * invalidated, their channels are deregistered, and any other resources
+     * associated with this selector are released.
+     *
+     * <p> If this selector is already closed then invoking this method has no
+     * effect.
+     *
+     * <p> After a selector is closed, any further attempt to use it, except by
+     * invoking this method or the {@link #wakeup wakeup} method, will cause a
+     * {@link ClosedSelectorException} to be thrown. </p>
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract void close() throws IOException;
+
+}
diff --git a/java/nio/channels/ServerSocketChannel.java b/java/nio/channels/ServerSocketChannel.java
new file mode 100644
index 0000000..8d967b3
--- /dev/null
+++ b/java/nio/channels/ServerSocketChannel.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * A selectable channel for stream-oriented listening sockets.
+ *
+ * <p> A server-socket channel is created by invoking the {@link #open() open}
+ * method of this class.  It is not possible to create a channel for an arbitrary,
+ * pre-existing {@link ServerSocket}. A newly-created server-socket channel is
+ * open but not yet bound.  An attempt to invoke the {@link #accept() accept}
+ * method of an unbound server-socket channel will cause a {@link NotYetBoundException}
+ * to be thrown. A server-socket channel can be bound by invoking one of the
+ * {@link #bind(java.net.SocketAddress,int) bind} methods defined by this class.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. Server-socket channels support the following options:
+ * <blockquote>
+ * <table border summary="Socket options">
+ *   <tr>
+ *     <th>Option Name</th>
+ *     <th>Description</th>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> The size of the socket receive buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> Re-use address </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <p> Server-socket channels are safe for use by multiple concurrent threads.
+ * </p>
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class ServerSocketChannel
+    extends AbstractSelectableChannel
+    implements NetworkChannel
+{
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @param  provider
+     *         The provider that created this channel
+     */
+    protected ServerSocketChannel(SelectorProvider provider) {
+        super(provider);
+    }
+
+    /**
+     * Opens a server-socket channel.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * java.nio.channels.spi.SelectorProvider#openServerSocketChannel
+     * openServerSocketChannel} method of the system-wide default {@link
+     * java.nio.channels.spi.SelectorProvider} object.
+     *
+     * <p> The new channel's socket is initially unbound; it must be bound to a
+     * specific address via one of its socket's {@link
+     * java.net.ServerSocket#bind(SocketAddress) bind} methods before
+     * connections can be accepted.  </p>
+     *
+     * @return  A new socket channel
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static ServerSocketChannel open() throws IOException {
+        return SelectorProvider.provider().openServerSocketChannel();
+    }
+
+    /**
+     * Returns an operation set identifying this channel's supported
+     * operations.
+     *
+     * <p> Server-socket channels only support the accepting of new
+     * connections, so this method returns {@link SelectionKey#OP_ACCEPT}.
+     * </p>
+     *
+     * @return  The valid-operation set
+     */
+    public final int validOps() {
+        return SelectionKey.OP_ACCEPT;
+    }
+
+
+    // -- ServerSocket-specific operations --
+
+    /**
+     * Binds the channel's socket to a local address and configures the socket
+     * to listen for connections.
+     *
+     * <p> An invocation of this method is equivalent to the following:
+     * <blockquote><pre>
+     * bind(local, 0);
+     * </pre></blockquote>
+     *
+     * @param   local
+     *          The local address to bind the socket, or {@code null} to bind
+     *          to an automatically assigned socket address
+     *
+     * @return  This channel
+     *
+     * @throws  AlreadyBoundException               {@inheritDoc}
+     * @throws  UnsupportedAddressTypeException     {@inheritDoc}
+     * @throws  ClosedChannelException              {@inheritDoc}
+     * @throws  IOException                         {@inheritDoc}
+     * @throws  SecurityException
+     *          If a security manager has been installed and its {@link
+     *          SecurityManager#checkListen checkListen} method denies the
+     *          operation
+     *
+     * @since 1.7
+     */
+    public final ServerSocketChannel bind(SocketAddress local)
+        throws IOException
+    {
+        return bind(local, 0);
+    }
+
+    /**
+     * Binds the channel's socket to a local address and configures the socket to
+     * listen for connections.
+     *
+     * <p> This method is used to establish an association between the socket and
+     * a local address. Once an association is established then the socket remains
+     * bound until the channel is closed.
+     *
+     * <p> The {@code backlog} parameter is the maximum number of pending
+     * connections on the socket. Its exact semantics are implementation specific.
+     * In particular, an implementation may impose a maximum length or may choose
+     * to ignore the parameter altogther. If the {@code backlog} parameter has
+     * the value {@code 0}, or a negative value, then an implementation specific
+     * default is used.
+     *
+     * @param   local
+     *          The address to bind the socket, or {@code null} to bind to an
+     *          automatically assigned socket address
+     * @param   backlog
+     *          The maximum number of pending connections
+     *
+     * @return  This channel
+     *
+     * @throws  AlreadyBoundException
+     *          If the socket is already bound
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given address is not supported
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager has been installed and its {@link
+     *          SecurityManager#checkListen checkListen} method denies the
+     *          operation
+     *
+     * @since 1.7
+     */
+    public abstract ServerSocketChannel bind(SocketAddress local, int backlog)
+        throws IOException;
+
+    /**
+     * @throws  UnsupportedOperationException           {@inheritDoc}
+     * @throws  IllegalArgumentException                {@inheritDoc}
+     * @throws  ClosedChannelException                  {@inheritDoc}
+     * @throws  IOException                             {@inheritDoc}
+     *
+     * @since 1.7
+     */
+    public abstract <T> ServerSocketChannel setOption(SocketOption<T> name, T value)
+        throws IOException;
+
+    /**
+     * Retrieves a server socket associated with this channel.
+     *
+     * <p> The returned object will not declare any public methods that are not
+     * declared in the {@link java.net.ServerSocket} class.  </p>
+     *
+     * @return  A server socket associated with this channel
+     */
+    public abstract ServerSocket socket();
+
+    /**
+     * Accepts a connection made to this channel's socket.
+     *
+     * <p> If this channel is in non-blocking mode then this method will
+     * immediately return <tt>null</tt> if there are no pending connections.
+     * Otherwise it will block indefinitely until a new connection is available
+     * or an I/O error occurs.
+     *
+     * <p> The socket channel returned by this method, if any, will be in
+     * blocking mode regardless of the blocking mode of this channel.
+     *
+     * <p> This method performs exactly the same security checks as the {@link
+     * java.net.ServerSocket#accept accept} method of the {@link
+     * java.net.ServerSocket} class.  That is, if a security manager has been
+     * installed then for each new connection this method verifies that the
+     * address and port number of the connection's remote endpoint are
+     * permitted by the security manager's {@link
+     * java.lang.SecurityManager#checkAccept checkAccept} method.  </p>
+     *
+     * @return  The socket channel for the new connection,
+     *          or <tt>null</tt> if this channel is in non-blocking mode
+     *          and no connection is available to be accepted
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the accept operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the accept operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  NotYetBoundException
+     *          If this channel's socket has not yet been bound
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed
+     *          and it does not permit access to the remote endpoint
+     *          of the new connection
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract SocketChannel accept() throws IOException;
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * If there is a security manager set, its {@code checkConnect} method is
+     * called with the local address and {@code -1} as its arguments to see
+     * if the operation is allowed. If the operation is not allowed,
+     * a {@code SocketAddress} representing the
+     * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+     * local port of the channel's socket is returned.
+     *
+     * @return  The {@code SocketAddress} that the socket is bound to, or the
+     *          {@code SocketAddress} representing the loopback address if
+     *          denied by the security manager, or {@code null} if the
+     *          channel's socket is not bound
+     *
+     * @throws  ClosedChannelException     {@inheritDoc}
+     * @throws  IOException                {@inheritDoc}
+     */
+    @Override
+    public abstract SocketAddress getLocalAddress() throws IOException;
+
+}
diff --git a/java/nio/channels/ShutdownChannelGroupException.java b/java/nio/channels/ShutdownChannelGroupException.java
new file mode 100644
index 0000000..b4e4b7d
--- /dev/null
+++ b/java/nio/channels/ShutdownChannelGroupException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to construct a channel in 
+ * a group that is shutdown or the completion handler for an I/O operation 
+ * cannot be invoked because the channel group has terminated.
+ *
+ * @since 1.7
+ */
+
+public class ShutdownChannelGroupException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = -3903801676350154157L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ShutdownChannelGroupException() { }
+
+}
diff --git a/java/nio/channels/SocketChannel.java b/java/nio/channels/SocketChannel.java
new file mode 100644
index 0000000..eb13b15
--- /dev/null
+++ b/java/nio/channels/SocketChannel.java
@@ -0,0 +1,526 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.SocketOption;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.spi.AbstractSelectableChannel;
+import java.nio.channels.spi.SelectorProvider;
+
+/**
+ * A selectable channel for stream-oriented connecting sockets.
+ *
+ * <p> A socket channel is created by invoking one of the {@link #open open}
+ * methods of this class.  It is not possible to create a channel for an arbitrary,
+ * pre-existing socket. A newly-created socket channel is open but not yet
+ * connected.  An attempt to invoke an I/O operation upon an unconnected
+ * channel will cause a {@link NotYetConnectedException} to be thrown.  A
+ * socket channel can be connected by invoking its {@link #connect connect}
+ * method; once connected, a socket channel remains connected until it is
+ * closed.  Whether or not a socket channel is connected may be determined by
+ * invoking its {@link #isConnected isConnected} method.
+ *
+ * <p> Socket channels support <i>non-blocking connection:</i>&nbsp;A socket
+ * channel may be created and the process of establishing the link to the
+ * remote socket may be initiated via the {@link #connect connect} method for
+ * later completion by the {@link #finishConnect finishConnect} method.
+ * Whether or not a connection operation is in progress may be determined by
+ * invoking the {@link #isConnectionPending isConnectionPending} method.
+ *
+ * <p> Socket channels support <i>asynchronous shutdown,</i> which is similar
+ * to the asynchronous close operation specified in the {@link Channel} class.
+ * If the input side of a socket is shut down by one thread while another
+ * thread is blocked in a read operation on the socket's channel, then the read
+ * operation in the blocked thread will complete without reading any bytes and
+ * will return <tt>-1</tt>.  If the output side of a socket is shut down by one
+ * thread while another thread is blocked in a write operation on the socket's
+ * channel, then the blocked thread will receive an {@link
+ * AsynchronousCloseException}.
+ *
+ * <p> Socket options are configured using the {@link #setOption(SocketOption,Object)
+ * setOption} method. Socket channels support the following options:
+ * <blockquote>
+ * <table border summary="Socket options">
+ *   <tr>
+ *     <th>Option Name</th>
+ *     <th>Description</th>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_SNDBUF SO_SNDBUF} </td>
+ *     <td> The size of the socket send buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_RCVBUF SO_RCVBUF} </td>
+ *     <td> The size of the socket receive buffer </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_KEEPALIVE SO_KEEPALIVE} </td>
+ *     <td> Keep connection alive </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_REUSEADDR SO_REUSEADDR} </td>
+ *     <td> Re-use address </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#SO_LINGER SO_LINGER} </td>
+ *     <td> Linger on close if data is present (when configured in blocking mode
+ *          only) </td>
+ *   </tr>
+ *   <tr>
+ *     <td> {@link java.net.StandardSocketOptions#TCP_NODELAY TCP_NODELAY} </td>
+ *     <td> Disable the Nagle algorithm </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ * Additional (implementation specific) options may also be supported.
+ *
+ * <p> Socket channels are safe for use by multiple concurrent threads.  They
+ * support concurrent reading and writing, though at most one thread may be
+ * reading and at most one thread may be writing at any given time.  The {@link
+ * #connect connect} and {@link #finishConnect finishConnect} methods are
+ * mutually synchronized against each other, and an attempt to initiate a read
+ * or write operation while an invocation of one of these methods is in
+ * progress will block until that invocation is complete.  </p>
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class SocketChannel
+    extends AbstractSelectableChannel
+    implements ByteChannel, ScatteringByteChannel, GatheringByteChannel, NetworkChannel
+{
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @param  provider
+     *         The provider that created this channel
+     */
+    protected SocketChannel(SelectorProvider provider) {
+        super(provider);
+    }
+
+    /**
+     * Opens a socket channel.
+     *
+     * <p> The new channel is created by invoking the {@link
+     * java.nio.channels.spi.SelectorProvider#openSocketChannel
+     * openSocketChannel} method of the system-wide default {@link
+     * java.nio.channels.spi.SelectorProvider} object.  </p>
+     *
+     * @return  A new socket channel
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public static SocketChannel open() throws IOException {
+        return SelectorProvider.provider().openSocketChannel();
+    }
+
+    /**
+     * Opens a socket channel and connects it to a remote address.
+     *
+     * <p> This convenience method works as if by invoking the {@link #open()}
+     * method, invoking the {@link #connect(SocketAddress) connect} method upon
+     * the resulting socket channel, passing it <tt>remote</tt>, and then
+     * returning that channel.  </p>
+     *
+     * @param  remote
+     *         The remote address to which the new channel is to be connected
+     *
+     * @return  A new, and connected, socket channel
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the connect operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the connect operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  UnresolvedAddressException
+     *          If the given remote address is not fully resolved
+     *
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given remote address is not supported
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed
+     *          and it does not permit access to the given remote endpoint
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public static SocketChannel open(SocketAddress remote)
+        throws IOException
+    {
+        SocketChannel sc = open();
+        try {
+            sc.connect(remote);
+        } catch (Throwable x) {
+            try {
+                sc.close();
+            } catch (Throwable suppressed) {
+                x.addSuppressed(suppressed);
+            }
+            throw x;
+        }
+        assert sc.isConnected();
+        return sc;
+    }
+
+    /**
+     * Returns an operation set identifying this channel's supported
+     * operations.
+     *
+     * <p> Socket channels support connecting, reading, and writing, so this
+     * method returns <tt>(</tt>{@link SelectionKey#OP_CONNECT}
+     * <tt>|</tt>&nbsp;{@link SelectionKey#OP_READ} <tt>|</tt>&nbsp;{@link
+     * SelectionKey#OP_WRITE}<tt>)</tt>.  </p>
+     *
+     * @return  The valid-operation set
+     */
+    public final int validOps() {
+        return (SelectionKey.OP_READ
+                | SelectionKey.OP_WRITE
+                | SelectionKey.OP_CONNECT);
+    }
+
+
+    // -- Socket-specific operations --
+
+    /**
+     * @throws  ConnectionPendingException
+     *          If a non-blocking connect operation is already in progress on
+     *          this channel
+     * @throws  AlreadyBoundException               {@inheritDoc}
+     * @throws  UnsupportedAddressTypeException     {@inheritDoc}
+     * @throws  ClosedChannelException              {@inheritDoc}
+     * @throws  IOException                         {@inheritDoc}
+     * @throws  SecurityException
+     *          If a security manager has been installed and its
+     *          {@link SecurityManager#checkListen checkListen} method denies
+     *          the operation
+     *
+     * @since 1.7
+     */
+    @Override
+    public abstract SocketChannel bind(SocketAddress local)
+        throws IOException;
+
+    /**
+     * @throws  UnsupportedOperationException           {@inheritDoc}
+     * @throws  IllegalArgumentException                {@inheritDoc}
+     * @throws  ClosedChannelException                  {@inheritDoc}
+     * @throws  IOException                             {@inheritDoc}
+     *
+     * @since 1.7
+     */
+    @Override
+    public abstract <T> SocketChannel setOption(SocketOption<T> name, T value)
+        throws IOException;
+
+    /**
+     * Shutdown the connection for reading without closing the channel.
+     *
+     * <p> Once shutdown for reading then further reads on the channel will
+     * return {@code -1}, the end-of-stream indication. If the input side of the
+     * connection is already shutdown then invoking this method has no effect.
+     *
+     * @return  The channel
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     *
+     * @since 1.7
+     */
+    public abstract SocketChannel shutdownInput() throws IOException;
+
+    /**
+     * Shutdown the connection for writing without closing the channel.
+     *
+     * <p> Once shutdown for writing then further attempts to write to the
+     * channel will throw {@link ClosedChannelException}. If the output side of
+     * the connection is already shutdown then invoking this method has no
+     * effect.
+     *
+     * @return  The channel
+     *
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     * @throws  IOException
+     *          If some other I/O error occurs
+     *
+     * @since 1.7
+     */
+    public abstract SocketChannel shutdownOutput() throws IOException;
+
+    /**
+     * Retrieves a socket associated with this channel.
+     *
+     * <p> The returned object will not declare any public methods that are not
+     * declared in the {@link java.net.Socket} class.  </p>
+     *
+     * @return  A socket associated with this channel
+     */
+    public abstract Socket socket();
+
+    /**
+     * Tells whether or not this channel's network socket is connected.
+     *
+     * @return  <tt>true</tt> if, and only if, this channel's network socket
+     *          is {@link #isOpen open} and connected
+     */
+    public abstract boolean isConnected();
+
+    /**
+     * Tells whether or not a connection operation is in progress on this
+     * channel.
+     *
+     * @return  <tt>true</tt> if, and only if, a connection operation has been
+     *          initiated on this channel but not yet completed by invoking the
+     *          {@link #finishConnect finishConnect} method
+     */
+    public abstract boolean isConnectionPending();
+
+    /**
+     * Connects this channel's socket.
+     *
+     * <p> If this channel is in non-blocking mode then an invocation of this
+     * method initiates a non-blocking connection operation.  If the connection
+     * is established immediately, as can happen with a local connection, then
+     * this method returns <tt>true</tt>.  Otherwise this method returns
+     * <tt>false</tt> and the connection operation must later be completed by
+     * invoking the {@link #finishConnect finishConnect} method.
+     *
+     * <p> If this channel is in blocking mode then an invocation of this
+     * method will block until the connection is established or an I/O error
+     * occurs.
+     *
+     * <p> This method performs exactly the same security checks as the {@link
+     * java.net.Socket} class.  That is, if a security manager has been
+     * installed then this method verifies that its {@link
+     * java.lang.SecurityManager#checkConnect checkConnect} method permits
+     * connecting to the address and port number of the given remote endpoint.
+     *
+     * <p> This method may be invoked at any time.  If a read or write
+     * operation upon this channel is invoked while an invocation of this
+     * method is in progress then that operation will first block until this
+     * invocation is complete.  If a connection attempt is initiated but fails,
+     * that is, if an invocation of this method throws a checked exception,
+     * then the channel will be closed.  </p>
+     *
+     * @param  remote
+     *         The remote address to which this channel is to be connected
+     *
+     * @return  <tt>true</tt> if a connection was established,
+     *          <tt>false</tt> if this channel is in non-blocking mode
+     *          and the connection operation is in progress
+     *
+     * @throws  AlreadyConnectedException
+     *          If this channel is already connected
+     *
+     * @throws  ConnectionPendingException
+     *          If a non-blocking connection operation is already in progress
+     *          on this channel
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the connect operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the connect operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  UnresolvedAddressException
+     *          If the given remote address is not fully resolved
+     *
+     * @throws  UnsupportedAddressTypeException
+     *          If the type of the given remote address is not supported
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed
+     *          and it does not permit access to the given remote endpoint
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract boolean connect(SocketAddress remote) throws IOException;
+
+    /**
+     * Finishes the process of connecting a socket channel.
+     *
+     * <p> A non-blocking connection operation is initiated by placing a socket
+     * channel in non-blocking mode and then invoking its {@link #connect
+     * connect} method.  Once the connection is established, or the attempt has
+     * failed, the socket channel will become connectable and this method may
+     * be invoked to complete the connection sequence.  If the connection
+     * operation failed then invoking this method will cause an appropriate
+     * {@link java.io.IOException} to be thrown.
+     *
+     * <p> If this channel is already connected then this method will not block
+     * and will immediately return <tt>true</tt>.  If this channel is in
+     * non-blocking mode then this method will return <tt>false</tt> if the
+     * connection process is not yet complete.  If this channel is in blocking
+     * mode then this method will block until the connection either completes
+     * or fails, and will always either return <tt>true</tt> or throw a checked
+     * exception describing the failure.
+     *
+     * <p> This method may be invoked at any time.  If a read or write
+     * operation upon this channel is invoked while an invocation of this
+     * method is in progress then that operation will first block until this
+     * invocation is complete.  If a connection attempt fails, that is, if an
+     * invocation of this method throws a checked exception, then the channel
+     * will be closed.  </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this channel's socket is now
+     *          connected
+     *
+     * @throws  NoConnectionPendingException
+     *          If this channel is not connected and a connection operation
+     *          has not been initiated
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the connect operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the connect operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public abstract boolean finishConnect() throws IOException;
+
+    /**
+     * Returns the remote address to which this channel's socket is connected.
+     *
+     * <p> Where the channel is bound and connected to an Internet Protocol
+     * socket address then the return value from this method is of type {@link
+     * java.net.InetSocketAddress}.
+     *
+     * @return  The remote address; {@code null} if the channel's socket is not
+     *          connected
+     *
+     * @throws  ClosedChannelException
+     *          If the channel is closed
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @since 1.7
+     */
+    public abstract SocketAddress getRemoteAddress() throws IOException;
+
+    // -- ByteChannel operations --
+
+    /**
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     */
+    public abstract int read(ByteBuffer dst) throws IOException;
+
+    /**
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     */
+    public abstract long read(ByteBuffer[] dsts, int offset, int length)
+        throws IOException;
+
+    /**
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     */
+    public final long read(ByteBuffer[] dsts) throws IOException {
+        return read(dsts, 0, dsts.length);
+    }
+
+    /**
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     */
+    public abstract int write(ByteBuffer src) throws IOException;
+
+    /**
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     */
+    public abstract long write(ByteBuffer[] srcs, int offset, int length)
+        throws IOException;
+
+    /**
+     * @throws  NotYetConnectedException
+     *          If this channel is not yet connected
+     */
+    public final long write(ByteBuffer[] srcs) throws IOException {
+        return write(srcs, 0, srcs.length);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * If there is a security manager set, its {@code checkConnect} method is
+     * called with the local address and {@code -1} as its arguments to see
+     * if the operation is allowed. If the operation is not allowed,
+     * a {@code SocketAddress} representing the
+     * {@link java.net.InetAddress#getLoopbackAddress loopback} address and the
+     * local port of the channel's socket is returned.
+     *
+     * @return  The {@code SocketAddress} that the socket is bound to, or the
+     *          {@code SocketAddress} representing the loopback address if
+     *          denied by the security manager, or {@code null} if the
+     *          channel's socket is not bound
+     *
+     * @throws  ClosedChannelException     {@inheritDoc}
+     * @throws  IOException                {@inheritDoc}
+     */
+    @Override
+    public abstract SocketAddress getLocalAddress() throws IOException;
+
+}
diff --git a/java/nio/channels/UnresolvedAddressException.java b/java/nio/channels/UnresolvedAddressException.java
new file mode 100644
index 0000000..f5e61b8
--- /dev/null
+++ b/java/nio/channels/UnresolvedAddressException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke a network
+ * operation upon an unresolved socket address.
+ *
+ * @since 1.4
+ */
+
+public class UnresolvedAddressException
+    extends IllegalArgumentException
+{
+
+    private static final long serialVersionUID = 6136959093620794148L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public UnresolvedAddressException() { }
+
+}
diff --git a/java/nio/channels/UnsupportedAddressTypeException.java b/java/nio/channels/UnsupportedAddressTypeException.java
new file mode 100644
index 0000000..9c88b89
--- /dev/null
+++ b/java/nio/channels/UnsupportedAddressTypeException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to bind or connect
+ * to a socket address of a type that is not supported.
+ *
+ * @since 1.4
+ */
+
+public class UnsupportedAddressTypeException
+    extends IllegalArgumentException
+{
+
+    private static final long serialVersionUID = -2964323842829700493L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public UnsupportedAddressTypeException() { }
+
+}
diff --git a/java/nio/channels/WritableByteChannel.java b/java/nio/channels/WritableByteChannel.java
new file mode 100644
index 0000000..b2ea065
--- /dev/null
+++ b/java/nio/channels/WritableByteChannel.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.channels;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+
+/**
+ * A channel that can write bytes.
+ *
+ * <p> Only one write operation upon a writable channel may be in progress at
+ * any given time.  If one thread initiates a write operation upon a channel
+ * then any other thread that attempts to initiate another write operation will
+ * block until the first operation is complete.  Whether or not other kinds of
+ * I/O operations may proceed concurrently with a write operation depends upon
+ * the type of the channel. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public interface WritableByteChannel
+    extends Channel
+{
+
+    /**
+     * Writes a sequence of bytes to this channel from the given buffer.
+     *
+     * <p> An attempt is made to write up to <i>r</i> bytes to the channel,
+     * where <i>r</i> is the number of bytes remaining in the buffer, that is,
+     * <tt>src.remaining()</tt>, at the moment this method is invoked.
+     *
+     * <p> Suppose that a byte sequence of length <i>n</i> is written, where
+     * <tt>0</tt>&nbsp;<tt>&lt;=</tt>&nbsp;<i>n</i>&nbsp;<tt>&lt;=</tt>&nbsp;<i>r</i>.
+     * This byte sequence will be transferred from the buffer starting at index
+     * <i>p</i>, where <i>p</i> is the buffer's position at the moment this
+     * method is invoked; the index of the last byte written will be
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>&nbsp;<tt>-</tt>&nbsp;<tt>1</tt>.
+     * Upon return the buffer's position will be equal to
+     * <i>p</i>&nbsp;<tt>+</tt>&nbsp;<i>n</i>; its limit will not have changed.
+     *
+     * <p> Unless otherwise specified, a write operation will return only after
+     * writing all of the <i>r</i> requested bytes.  Some types of channels,
+     * depending upon their state, may write only some of the bytes or possibly
+     * none at all.  A socket channel in non-blocking mode, for example, cannot
+     * write any more bytes than are free in the socket's output buffer.
+     *
+     * <p> This method may be invoked at any time.  If another thread has
+     * already initiated a write operation upon this channel, however, then an
+     * invocation of this method will block until the first operation is
+     * complete. </p>
+     *
+     * @param  src
+     *         The buffer from which bytes are to be retrieved
+     *
+     * @return The number of bytes written, possibly zero
+     *
+     * @throws  NonWritableChannelException
+     *          If this channel was not opened for writing
+     *
+     * @throws  ClosedChannelException
+     *          If this channel is closed
+     *
+     * @throws  AsynchronousCloseException
+     *          If another thread closes this channel
+     *          while the write operation is in progress
+     *
+     * @throws  ClosedByInterruptException
+     *          If another thread interrupts the current thread
+     *          while the write operation is in progress, thereby
+     *          closing the channel and setting the current thread's
+     *          interrupt status
+     *
+     * @throws  IOException
+     *          If some other I/O error occurs
+     */
+    public int write(ByteBuffer src) throws IOException;
+
+}
diff --git a/java/nio/channels/WritePendingException.java b/java/nio/channels/WritePendingException.java
new file mode 100644
index 0000000..8957702
--- /dev/null
+++ b/java/nio/channels/WritePendingException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.channels;
+
+
+/**
+ * Unchecked exception thrown when an attempt is made to write to an
+ * asynchronous socket channel and a previous write has not completed.
+ *
+ * @since 1.7
+ */
+
+public class WritePendingException
+    extends IllegalStateException
+{
+
+    private static final long serialVersionUID = 7031871839266032276L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public WritePendingException() { }
+
+}
diff --git a/java/nio/channels/package-info.java b/java/nio/channels/package-info.java
new file mode 100644
index 0000000..8118347
--- /dev/null
+++ b/java/nio/channels/package-info.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (c) 2001, 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.
+ */
+
+/**
+ * Defines channels, which represent connections to entities that are capable of
+ * performing I/O operations, such as files and sockets; defines selectors, for
+ * multiplexed, non-blocking I/O operations.
+ *
+ * <a name="channels"></a>
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists channels and their descriptions">
+ * <tr><th align="left">Channels</th><th align="left">Description</th></tr>
+ * <tr><td valign=top><tt><i>{@link java.nio.channels.Channel}</i></tt></td>
+ *     <td>A nexus for I/O operations</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;<i>{@link java.nio.channels.ReadableByteChannel}</i></tt></td>
+ *     <td>Can read into a buffer</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.channels.ScatteringByteChannel}&nbsp;&nbsp;</i></tt></td>
+ *     <td>Can read into a sequence of&nbsp;buffers</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;<i>{@link java.nio.channels.WritableByteChannel}</i></tt></td>
+ *     <td>Can write from a buffer</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.channels.GatheringByteChannel}</i></tt></td>
+ *     <td>Can write from a sequence of&nbsp;buffers</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;<i>{@link java.nio.channels.ByteChannel}</i></tt></td>
+ *     <td>Can read/write to/from a&nbsp;buffer</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.channels.SeekableByteChannel}</i></tt></td>
+ *     <td>A {@code ByteChannel} connected to an entity that contains a variable-length sequence of bytes</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;<i>{@link java.nio.channels.AsynchronousChannel}</i></tt></td>
+ *     <td>Supports asynchronous I/O operations.</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.channels.AsynchronousByteChannel}</i></tt></td>
+ *     <td>Can read and write bytes asynchronously</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;<i>{@link java.nio.channels.NetworkChannel}</i></tt></td>
+ *     <td>A channel to a network socket</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;<i>{@link java.nio.channels.MulticastChannel}</i></tt></td>
+ *     <td>Can join Internet Protocol (IP) multicast groups</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.Channels}</tt></td>
+ *     <td>Utility methods for channel/stream interoperation</td></tr>
+ * </table></blockquote>
+ *
+ * <p> A <i>channel</i> represents an open connection to an entity such as a
+ * hardware device, a file, a network socket, or a program component that is
+ * capable of performing one or more distinct I/O operations, for example reading
+ * or writing.  As specified in the {@link java.nio.channels.Channel} interface,
+ * channels are either open or closed, and they are both <i>asynchronously
+ * closeable</i> and <i>interruptible</i>.
+ *
+ * <p> The {@link java.nio.channels.Channel} interface is extended by several
+ * other interfaces.
+ *
+ * <p> The {@link java.nio.channels.ReadableByteChannel} interface specifies a
+ * {@link java.nio.channels.ReadableByteChannel#read read} method that reads bytes
+ * from the channel into a buffer; similarly, the {@link
+ * java.nio.channels.WritableByteChannel} interface specifies a {@link
+ * java.nio.channels.WritableByteChannel#write write} method that writes bytes
+ * from a buffer to the channel. The {@link java.nio.channels.ByteChannel}
+ * interface unifies these two interfaces for the common case of channels that can
+ * both read and write bytes. The {@link java.nio.channels.SeekableByteChannel}
+ * interface extends the {@code ByteChannel} interface with methods to {@link
+ * java.nio.channels.SeekableByteChannel#position() query} and {@link
+ * java.nio.channels.SeekableByteChannel#position(long) modify} the channel's
+ * current position, and its {@link java.nio.channels.SeekableByteChannel#size
+ * size}.
+ *
+ * <p> The {@link java.nio.channels.ScatteringByteChannel} and {@link
+ * java.nio.channels.GatheringByteChannel} interfaces extend the {@link
+ * java.nio.channels.ReadableByteChannel} and {@link
+ * java.nio.channels.WritableByteChannel} interfaces, respectively, adding {@link
+ * java.nio.channels.ScatteringByteChannel#read read} and {@link
+ * java.nio.channels.GatheringByteChannel#write write} methods that take a
+ * sequence of buffers rather than a single buffer.
+ *
+ * <p> The {@link java.nio.channels.NetworkChannel} interface specifies methods
+ * to {@link java.nio.channels.NetworkChannel#bind bind} the channel's socket,
+ * obtain the address to which the socket is bound, and methods to {@link
+ * java.nio.channels.NetworkChannel#getOption get} and {@link
+ * java.nio.channels.NetworkChannel#setOption set} socket options. The {@link
+ * java.nio.channels.MulticastChannel} interface specifies methods to join
+ * Internet Protocol (IP) multicast groups.
+ *
+ * <p> The {@link java.nio.channels.Channels} utility class defines static methods
+ * that support the interoperation of the stream classes of the <tt>{@link
+ * java.io}</tt> package with the channel classes of this package.  An appropriate
+ * channel can be constructed from an {@link java.io.InputStream} or an {@link
+ * java.io.OutputStream}, and conversely an {@link java.io.InputStream} or an
+ * {@link java.io.OutputStream} can be constructed from a channel.  A {@link
+ * java.io.Reader} can be constructed that uses a given charset to decode bytes
+ * from a given readable byte channel, and conversely a {@link java.io.Writer} can
+ * be constructed that uses a given charset to encode characters into bytes and
+ * write them to a given writable byte channel.
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists file channels and their descriptions">
+ * <tr><th align="left">File channels</th><th align="left">Description</th></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.FileChannel}</tt></td>
+ *     <td>Reads, writes, maps, and manipulates files</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.FileLock}</tt></td>
+ *     <td>A lock on a (region of a) file</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.MappedByteBuffer}&nbsp;&nbsp;</tt></td>
+ *     <td>A direct byte buffer mapped to a region of a&nbsp;file</td></tr>
+ * </table></blockquote>
+ *
+ * <p> The {@link java.nio.channels.FileChannel} class supports the usual
+ * operations of reading bytes from, and writing bytes to, a channel connected to
+ * a file, as well as those of querying and modifying the current file position
+ * and truncating the file to a specific size.  It defines methods for acquiring
+ * locks on the whole file or on a specific region of a file; these methods return
+ * instances of the {@link java.nio.channels.FileLock} class.  Finally, it defines
+ * methods for forcing updates to the file to be written to the storage device that
+ * contains it, for efficiently transferring bytes between the file and other
+ * channels, and for mapping a region of the file directly into memory.
+ *
+ * <p> A {@code FileChannel} is created by invoking one of its static {@link
+ * java.nio.channels.FileChannel#open open} methods, or by invoking the {@code
+ * getChannel} method of a {@link java.io.FileInputStream}, {@link
+ * java.io.FileOutputStream}, or {@link java.io.RandomAccessFile} to return a
+ * file channel connected to the same underlying file as the <tt>{@link java.io}</tt>
+ * class.
+ *
+ * <a name="multiplex"></a>
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists multiplexed, non-blocking channels and their descriptions">
+ * <tr><th align="left">Multiplexed, non-blocking I/O</th><th align="left"><p>Description</th></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.SelectableChannel}</tt></td>
+ *     <td>A channel that can be multiplexed</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.channels.DatagramChannel}</tt></td>
+ *     <td>A channel to a datagram-oriented socket</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.channels.Pipe.SinkChannel}</tt></td>
+ *     <td>The write end of a pipe</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.channels.Pipe.SourceChannel}</tt></td>
+ *     <td>The read end of a pipe</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.channels.ServerSocketChannel}&nbsp;&nbsp;</tt></td>
+ *     <td>A channel to a stream-oriented listening socket</td></tr>
+ * <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.channels.SocketChannel}</tt></td>
+ *     <td>A channel for a stream-oriented connecting socket</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.Selector}</tt></td>
+ *     <td>A multiplexor of selectable channels</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.SelectionKey}</tt></td>
+ *     <td>A token representing the registration <br> of a channel
+ *     with&nbsp;a&nbsp;selector</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.Pipe}</tt></td>
+ *     <td>Two channels that form a unidirectional&nbsp;pipe</td></tr>
+ * </table></blockquote>
+ *
+ * <p> Multiplexed, non-blocking I/O, which is much more scalable than
+ * thread-oriented, blocking I/O, is provided by <i>selectors</i>, <i>selectable
+ * channels</i>, and <i>selection keys</i>.
+ *
+ * <p> A <a href="Selector.html"><i>selector</i></a> is a multiplexor of <a
+ * href="SelectableChannel.html"><i>selectable channels</i></a>, which in turn are
+ * a special type of channel that can be put into <a
+ * href="SelectableChannel.html#bm"><i>non-blocking mode</i></a>.  To perform
+ * multiplexed I/O operations, one or more selectable channels are first created,
+ * put into non-blocking mode, and {@link
+ * java.nio.channels.SelectableChannel#register <i>registered</i>}
+ * with a selector.  Registering a channel specifies the set of I/O operations
+ * that will be tested for readiness by the selector, and returns a <a
+ * href="SelectionKey.html"><i>selection key</i></a> that represents the
+ * registration.
+ *
+ * <p> Once some channels have been registered with a selector, a <a
+ * href="Selector.html#selop"><i>selection operation</i></a> can be performed in
+ * order to discover which channels, if any, have become ready to perform one or
+ * more of the operations in which interest was previously declared.  If a channel
+ * is ready then the key returned when it was registered will be added to the
+ * selector's <i>selected-key set</i>.  The key set, and the keys within it, can
+ * be examined in order to determine the operations for which each channel is
+ * ready.  From each key one can retrieve the corresponding channel in order to
+ * perform whatever I/O operations are required.
+ *
+ * <p> That a selection key indicates that its channel is ready for some operation
+ * is a hint, but not a guarantee, that such an operation can be performed by a
+ * thread without causing the thread to block.  It is imperative that code that
+ * performs multiplexed I/O be written so as to ignore these hints when they prove
+ * to be incorrect.
+ *
+ * <p> This package defines selectable-channel classes corresponding to the {@link
+ * java.net.DatagramSocket}, {@link java.net.ServerSocket}, and {@link
+ * java.net.Socket} classes defined in the <tt>{@link java.net}</tt> package.
+ * Minor changes to these classes have been made in order to support sockets that
+ * are associated with channels.  This package also defines a simple class that
+ * implements unidirectional pipes.  In all cases, a new selectable channel is
+ * created by invoking the static <tt>open</tt> method of the corresponding class.
+ * If a channel needs an associated socket then a socket will be created as a side
+ * effect of this operation.
+ *
+ * <p> The implementation of selectors, selectable channels, and selection keys
+ * can be replaced by "plugging in" an alternative definition or instance of the
+ * {@link java.nio.channels.spi.SelectorProvider} class defined in the <tt>{@link
+ * java.nio.channels.spi}</tt> package.  It is not expected that many developers
+ * will actually make use of this facility; it is provided primarily so that
+ * sophisticated users can take advantage of operating-system-specific
+ * I/O-multiplexing mechanisms when very high performance is required.
+ *
+ * <p> Much of the bookkeeping and synchronization required to implement the
+ * multiplexed-I/O abstractions is performed by the {@link
+ * java.nio.channels.spi.AbstractInterruptibleChannel}, {@link
+ * java.nio.channels.spi.AbstractSelectableChannel}, {@link
+ * java.nio.channels.spi.AbstractSelectionKey}, and {@link
+ * java.nio.channels.spi.AbstractSelector} classes in the <tt>{@link
+ * java.nio.channels.spi}</tt> package.  When defining a custom selector provider,
+ * only the {@link java.nio.channels.spi.AbstractSelector} and {@link
+ * java.nio.channels.spi.AbstractSelectionKey} classes should be subclassed
+ * directly; custom channel classes should extend the appropriate {@link
+ * java.nio.channels.SelectableChannel} subclasses defined in this package.
+ *
+ * <a name="async"></a>
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Lists asynchronous channels and their descriptions">
+ * <tr><th align="left">Asynchronous I/O</th><th align="left">Description</th></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousFileChannel}</tt></td>
+ *     <td>An asynchronous channel for reading, writing, and manipulating a file</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousSocketChannel}</tt></td>
+ *     <td>An asynchronous channel to a stream-oriented connecting socket</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousServerSocketChannel}&nbsp;&nbsp;</tt></td>
+ *     <td>An asynchronous channel to a stream-oriented listening socket</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.CompletionHandler}</tt></td>
+ *     <td>A handler for consuming the result of an asynchronous operation</td></tr>
+ * <tr><td valign=top><tt>{@link java.nio.channels.AsynchronousChannelGroup}</tt></td>
+ *     <td>A grouping of asynchronous channels for the purpose of resource sharing</td></tr>
+ * </table></blockquote>
+ *
+ * <p> {@link java.nio.channels.AsynchronousChannel Asynchronous channels} are a
+ * special type of channel capable of asynchronous I/O operations. Asynchronous
+ * channels are non-blocking and define methods to initiate asynchronous
+ * operations, returning a {@link java.util.concurrent.Future} representing the
+ * pending result of each operation. The {@code Future} can be used to poll or
+ * wait for the result of the operation. Asynchronous I/O operations can also
+ * specify a {@link java.nio.channels.CompletionHandler} to invoke when the
+ * operation completes. A completion handler is user provided code that is executed
+ * to consume the result of I/O operation.
+ *
+ * <p> This package defines asynchronous-channel classes that are connected to
+ * a stream-oriented connecting or listening socket, or a datagram-oriented socket.
+ * It also defines the {@link java.nio.channels.AsynchronousFileChannel} class
+ * for asynchronous reading, writing, and manipulating a file. As with the {@link
+ * java.nio.channels.FileChannel} it supports operations to truncate the file
+ * to a specific size, force updates to the file to be written to the storage
+ * device, or acquire locks on the whole file or on a specific region of the file.
+ * Unlike the {@code FileChannel} it does not define methods for mapping a
+ * region of the file directly into memory. Where memory mapped I/O is required,
+ * then a {@code FileChannel} can be used.
+ *
+ * <p> Asynchronous channels are bound to an asynchronous channel group for the
+ * purpose of resource sharing. A group has an associated {@link
+ * java.util.concurrent.ExecutorService} to which tasks are submitted to handle
+ * I/O events and dispatch to completion handlers that consume the result of
+ * asynchronous operations performed on channels in the group. The group can
+ * optionally be specified when creating the channel or the channel can be bound
+ * to a <em>default group</em>. Sophisticated users may wish to create their
+ * own asynchronous channel groups or configure the {@code ExecutorService}
+ * that will be used for the default group.
+ *
+ * <p> As with selectors, the implementation of asynchronous channels can be
+ * replaced by "plugging in" an alternative definition or instance of the {@link
+ * java.nio.channels.spi.AsynchronousChannelProvider} class defined in the
+ * <tt>{@link java.nio.channels.spi}</tt> package.  It is not expected that many
+ * developers will actually make use of this facility; it is provided primarily
+ * so that sophisticated users can take advantage of operating-system-specific
+ * asynchronous I/O mechanisms when very high performance is required.
+ *
+ * <hr width="80%">
+ * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
+ * or method in any class or interface in this package will cause a {@link
+ * java.lang.NullPointerException NullPointerException} to be thrown.
+ *
+ * @since 1.4
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ */
+
+package java.nio.channels;
diff --git a/java/nio/channels/spi/AbstractInterruptibleChannel.java b/java/nio/channels/spi/AbstractInterruptibleChannel.java
new file mode 100644
index 0000000..137c449
--- /dev/null
+++ b/java/nio/channels/spi/AbstractInterruptibleChannel.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels.spi;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.channels.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.nio.ch.Interruptible;
+
+
+/**
+ * Base implementation class for interruptible channels.
+ *
+ * <p> This class encapsulates the low-level machinery required to implement
+ * the asynchronous closing and interruption of channels.  A concrete channel
+ * class must invoke the {@link #begin begin} and {@link #end end} methods
+ * before and after, respectively, invoking an I/O operation that might block
+ * indefinitely.  In order to ensure that the {@link #end end} method is always
+ * invoked, these methods should be used within a
+ * <tt>try</tt>&nbsp;...&nbsp;<tt>finally</tt> block:
+ *
+ * <blockquote><pre>
+ * boolean completed = false;
+ * try {
+ *     begin();
+ *     completed = ...;    // Perform blocking I/O operation
+ *     return ...;         // Return result
+ * } finally {
+ *     end(completed);
+ * }</pre></blockquote>
+ *
+ * <p> The <tt>completed</tt> argument to the {@link #end end} method tells
+ * whether or not the I/O operation actually completed, that is, whether it had
+ * any effect that would be visible to the invoker.  In the case of an
+ * operation that reads bytes, for example, this argument should be
+ * <tt>true</tt> if, and only if, some bytes were actually transferred into the
+ * invoker's target buffer.
+ *
+ * <p> A concrete channel class must also implement the {@link
+ * #implCloseChannel implCloseChannel} method in such a way that if it is
+ * invoked while another thread is blocked in a native I/O operation upon the
+ * channel then that operation will immediately return, either by throwing an
+ * exception or by returning normally.  If a thread is interrupted or the
+ * channel upon which it is blocked is asynchronously closed then the channel's
+ * {@link #end end} method will throw the appropriate exception.
+ *
+ * <p> This class performs the synchronization required to implement the {@link
+ * java.nio.channels.Channel} specification.  Implementations of the {@link
+ * #implCloseChannel implCloseChannel} method need not synchronize against
+ * other threads that might be attempting to close the channel.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class AbstractInterruptibleChannel
+    implements Channel, InterruptibleChannel
+{
+
+    private final Object closeLock = new Object();
+    private volatile boolean open = true;
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected AbstractInterruptibleChannel() { }
+
+    /**
+     * Closes this channel.
+     *
+     * <p> If the channel has already been closed then this method returns
+     * immediately.  Otherwise it marks the channel as closed and then invokes
+     * the {@link #implCloseChannel implCloseChannel} method in order to
+     * complete the close operation.  </p>
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public final void close() throws IOException {
+        synchronized (closeLock) {
+            if (!open)
+                return;
+            open = false;
+            implCloseChannel();
+        }
+    }
+
+    /**
+     * Closes this channel.
+     *
+     * <p> This method is invoked by the {@link #close close} method in order
+     * to perform the actual work of closing the channel.  This method is only
+     * invoked if the channel has not yet been closed, and it is never invoked
+     * more than once.
+     *
+     * <p> An implementation of this method must arrange for any other thread
+     * that is blocked in an I/O operation upon this channel to return
+     * immediately, either by throwing an exception or by returning normally.
+     * </p>
+     *
+     * @throws  IOException
+     *          If an I/O error occurs while closing the channel
+     */
+    protected abstract void implCloseChannel() throws IOException;
+
+    public final boolean isOpen() {
+        return open;
+    }
+
+
+    // -- Interruption machinery --
+
+    private Interruptible interruptor;
+    private volatile Thread interrupted;
+
+    /**
+     * Marks the beginning of an I/O operation that might block indefinitely.
+     *
+     * <p> This method should be invoked in tandem with the {@link #end end}
+     * method, using a <tt>try</tt>&nbsp;...&nbsp;<tt>finally</tt> block as
+     * shown <a href="#be">above</a>, in order to implement asynchronous
+     * closing and interruption for this channel.  </p>
+     */
+    protected final void begin() {
+        if (interruptor == null) {
+            interruptor = new Interruptible() {
+                    public void interrupt(Thread target) {
+                        synchronized (closeLock) {
+                            if (!open)
+                                return;
+                            open = false;
+                            interrupted = target;
+                            try {
+                                AbstractInterruptibleChannel.this.implCloseChannel();
+                            } catch (IOException x) { }
+                        }
+                    }};
+        }
+        blockedOn(interruptor);
+        Thread me = Thread.currentThread();
+        if (me.isInterrupted())
+            interruptor.interrupt(me);
+    }
+
+    /**
+     * Marks the end of an I/O operation that might block indefinitely.
+     *
+     * <p> This method should be invoked in tandem with the {@link #begin
+     * begin} method, using a <tt>try</tt>&nbsp;...&nbsp;<tt>finally</tt> block
+     * as shown <a href="#be">above</a>, in order to implement asynchronous
+     * closing and interruption for this channel.  </p>
+     *
+     * @param  completed
+     *         <tt>true</tt> if, and only if, the I/O operation completed
+     *         successfully, that is, had some effect that would be visible to
+     *         the operation's invoker
+     *
+     * @throws  AsynchronousCloseException
+     *          If the channel was asynchronously closed
+     *
+     * @throws  ClosedByInterruptException
+     *          If the thread blocked in the I/O operation was interrupted
+     */
+    protected final void end(boolean completed)
+        throws AsynchronousCloseException
+    {
+        blockedOn(null);
+        Thread interrupted = this.interrupted;
+        if (interrupted != null && interrupted == Thread.currentThread()) {
+            interrupted = null;
+            throw new ClosedByInterruptException();
+        }
+        if (!completed && !open)
+            throw new AsynchronousCloseException();
+    }
+
+
+    // -- sun.misc.SharedSecrets --
+    static void blockedOn(Interruptible intr) {         // package-private
+        // Android-changed: Call Thread.currentThread().blockedOn() directly.
+        Thread.currentThread().blockedOn(intr);
+    }
+}
diff --git a/java/nio/channels/spi/AbstractSelectableChannel.java b/java/nio/channels/spi/AbstractSelectableChannel.java
new file mode 100644
index 0000000..0de212d
--- /dev/null
+++ b/java/nio/channels/spi/AbstractSelectableChannel.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels.spi;
+
+import java.io.IOException;
+import java.nio.channels.*;
+
+
+/**
+ * Base implementation class for selectable channels.
+ *
+ * <p> This class defines methods that handle the mechanics of channel
+ * registration, deregistration, and closing.  It maintains the current
+ * blocking mode of this channel as well as its current set of selection keys.
+ * It performs all of the synchronization required to implement the {@link
+ * java.nio.channels.SelectableChannel} specification.  Implementations of the
+ * abstract protected methods defined in this class need not synchronize
+ * against other threads that might be engaged in the same operations.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author Mike McCloskey
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class AbstractSelectableChannel
+    extends SelectableChannel
+{
+
+    // The provider that created this channel
+    private final SelectorProvider provider;
+
+    // Keys that have been created by registering this channel with selectors.
+    // They are saved because if this channel is closed the keys must be
+    // deregistered.  Protected by keyLock.
+    //
+    private SelectionKey[] keys = null;
+    private int keyCount = 0;
+
+    // Lock for key set and count
+    private final Object keyLock = new Object();
+
+    // Lock for registration and configureBlocking operations
+    private final Object regLock = new Object();
+
+    // Blocking mode, protected by regLock
+    boolean blocking = true;
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @param  provider
+     *         The provider that created this channel
+     */
+    protected AbstractSelectableChannel(SelectorProvider provider) {
+        this.provider = provider;
+    }
+
+    /**
+     * Returns the provider that created this channel.
+     *
+     * @return  The provider that created this channel
+     */
+    public final SelectorProvider provider() {
+        return provider;
+    }
+
+
+    // -- Utility methods for the key set --
+
+    private void addKey(SelectionKey k) {
+        assert Thread.holdsLock(keyLock);
+        int i = 0;
+        if ((keys != null) && (keyCount < keys.length)) {
+            // Find empty element of key array
+            for (i = 0; i < keys.length; i++)
+                if (keys[i] == null)
+                    break;
+        } else if (keys == null) {
+            keys =  new SelectionKey[3];
+        } else {
+            // Grow key array
+            int n = keys.length * 2;
+            SelectionKey[] ks =  new SelectionKey[n];
+            for (i = 0; i < keys.length; i++)
+                ks[i] = keys[i];
+            keys = ks;
+            i = keyCount;
+        }
+        keys[i] = k;
+        keyCount++;
+    }
+
+    private SelectionKey findKey(Selector sel) {
+        synchronized (keyLock) {
+            if (keys == null)
+                return null;
+            for (int i = 0; i < keys.length; i++)
+                if ((keys[i] != null) && (keys[i].selector() == sel))
+                    return keys[i];
+            return null;
+        }
+    }
+
+    void removeKey(SelectionKey k) {                    // package-private
+        synchronized (keyLock) {
+            for (int i = 0; i < keys.length; i++)
+                if (keys[i] == k) {
+                    keys[i] = null;
+                    keyCount--;
+                }
+            ((AbstractSelectionKey)k).invalidate();
+        }
+    }
+
+    private boolean haveValidKeys() {
+        synchronized (keyLock) {
+            if (keyCount == 0)
+                return false;
+            for (int i = 0; i < keys.length; i++) {
+                if ((keys[i] != null) && keys[i].isValid())
+                    return true;
+            }
+            return false;
+        }
+    }
+
+
+    // -- Registration --
+
+    public final boolean isRegistered() {
+        synchronized (keyLock) {
+            return keyCount != 0;
+        }
+    }
+
+    public final SelectionKey keyFor(Selector sel) {
+        return findKey(sel);
+    }
+
+    /**
+     * Registers this channel with the given selector, returning a selection key.
+     *
+     * <p>  This method first verifies that this channel is open and that the
+     * given initial interest set is valid.
+     *
+     * <p> If this channel is already registered with the given selector then
+     * the selection key representing that registration is returned after
+     * setting its interest set to the given value.
+     *
+     * <p> Otherwise this channel has not yet been registered with the given
+     * selector, so the {@link AbstractSelector#register register} method of
+     * the selector is invoked while holding the appropriate locks.  The
+     * resulting key is added to this channel's key set before being returned.
+     * </p>
+     *
+     * @throws  ClosedSelectorException {@inheritDoc}
+     *
+     * @throws  IllegalBlockingModeException {@inheritDoc}
+     *
+     * @throws  IllegalSelectorException {@inheritDoc}
+     *
+     * @throws  CancelledKeyException {@inheritDoc}
+     *
+     * @throws  IllegalArgumentException {@inheritDoc}
+     */
+    public final SelectionKey register(Selector sel, int ops,
+                                       Object att)
+        throws ClosedChannelException
+    {
+        synchronized (regLock) {
+            if (!isOpen())
+                throw new ClosedChannelException();
+            if ((ops & ~validOps()) != 0)
+                throw new IllegalArgumentException();
+            if (blocking)
+                throw new IllegalBlockingModeException();
+            SelectionKey k = findKey(sel);
+            if (k != null) {
+                k.interestOps(ops);
+                k.attach(att);
+            }
+            if (k == null) {
+                // New registration
+                synchronized (keyLock) {
+                    if (!isOpen())
+                        throw new ClosedChannelException();
+                    k = ((AbstractSelector)sel).register(this, ops, att);
+                    addKey(k);
+                }
+            }
+            return k;
+        }
+    }
+
+
+    // -- Closing --
+
+    /**
+     * Closes this channel.
+     *
+     * <p> This method, which is specified in the {@link
+     * AbstractInterruptibleChannel} class and is invoked by the {@link
+     * java.nio.channels.Channel#close close} method, in turn invokes the
+     * {@link #implCloseSelectableChannel implCloseSelectableChannel} method in
+     * order to perform the actual work of closing this channel.  It then
+     * cancels all of this channel's keys.  </p>
+     */
+    protected final void implCloseChannel() throws IOException {
+        implCloseSelectableChannel();
+        synchronized (keyLock) {
+            int count = (keys == null) ? 0 : keys.length;
+            for (int i = 0; i < count; i++) {
+                SelectionKey k = keys[i];
+                if (k != null)
+                    k.cancel();
+            }
+        }
+    }
+
+    /**
+     * Closes this selectable channel.
+     *
+     * <p> This method is invoked by the {@link java.nio.channels.Channel#close
+     * close} method in order to perform the actual work of closing the
+     * channel.  This method is only invoked if the channel has not yet been
+     * closed, and it is never invoked more than once.
+     *
+     * <p> An implementation of this method must arrange for any other thread
+     * that is blocked in an I/O operation upon this channel to return
+     * immediately, either by throwing an exception or by returning normally.
+     * </p>
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    protected abstract void implCloseSelectableChannel() throws IOException;
+
+
+    // -- Blocking --
+
+    public final boolean isBlocking() {
+        synchronized (regLock) {
+            return blocking;
+        }
+    }
+
+    public final Object blockingLock() {
+        return regLock;
+    }
+
+    /**
+     * Adjusts this channel's blocking mode.
+     *
+     * <p> If the given blocking mode is different from the current blocking
+     * mode then this method invokes the {@link #implConfigureBlocking
+     * implConfigureBlocking} method, while holding the appropriate locks, in
+     * order to change the mode.  </p>
+     */
+    public final SelectableChannel configureBlocking(boolean block)
+        throws IOException
+    {
+        synchronized (regLock) {
+            if (!isOpen())
+                throw new ClosedChannelException();
+            if (blocking == block)
+                return this;
+            if (block && haveValidKeys())
+                throw new IllegalBlockingModeException();
+            implConfigureBlocking(block);
+            blocking = block;
+        }
+        return this;
+    }
+
+    /**
+     * Adjusts this channel's blocking mode.
+     *
+     * <p> This method is invoked by the {@link #configureBlocking
+     * configureBlocking} method in order to perform the actual work of
+     * changing the blocking mode.  This method is only invoked if the new mode
+     * is different from the current mode.  </p>
+     *
+     * @param  block  If <tt>true</tt> then this channel will be placed in
+     *                blocking mode; if <tt>false</tt> then it will be placed
+     *                non-blocking mode
+     *
+     * @throws IOException
+     *         If an I/O error occurs
+     */
+    protected abstract void implConfigureBlocking(boolean block)
+        throws IOException;
+
+}
diff --git a/java/nio/channels/spi/AbstractSelectionKey.java b/java/nio/channels/spi/AbstractSelectionKey.java
new file mode 100644
index 0000000..015e6c7
--- /dev/null
+++ b/java/nio/channels/spi/AbstractSelectionKey.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels.spi;
+
+import java.nio.channels.*;
+
+
+/**
+ * Base implementation class for selection keys.
+ *
+ * <p> This class tracks the validity of the key and implements cancellation.
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class AbstractSelectionKey
+    extends SelectionKey
+{
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected AbstractSelectionKey() { }
+
+    private volatile boolean valid = true;
+
+    public final boolean isValid() {
+        return valid;
+    }
+
+    void invalidate() {                                 // package-private
+        valid = false;
+    }
+
+    /**
+     * Cancels this key.
+     *
+     * <p> If this key has not yet been cancelled then it is added to its
+     * selector's cancelled-key set while synchronized on that set.  </p>
+     */
+    public final void cancel() {
+        // Synchronizing "this" to prevent this key from getting canceled
+        // multiple times by different threads, which might cause race
+        // condition between selector's select() and channel's close().
+        synchronized (this) {
+            if (valid) {
+                valid = false;
+                ((AbstractSelector)selector()).cancel(this);
+            }
+        }
+    }
+}
diff --git a/java/nio/channels/spi/AbstractSelector.java b/java/nio/channels/spi/AbstractSelector.java
new file mode 100644
index 0000000..09e3b61
--- /dev/null
+++ b/java/nio/channels/spi/AbstractSelector.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels.spi;
+
+import java.io.IOException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
+import java.util.HashSet;
+import java.util.Set;
+import sun.nio.ch.Interruptible;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+
+/**
+ * Base implementation class for selectors.
+ *
+ * <p> This class encapsulates the low-level machinery required to implement
+ * the interruption of selection operations.  A concrete selector class must
+ * invoke the {@link #begin begin} and {@link #end end} methods before and
+ * after, respectively, invoking an I/O operation that might block
+ * indefinitely.  In order to ensure that the {@link #end end} method is always
+ * invoked, these methods should be used within a
+ * <tt>try</tt>&nbsp;...&nbsp;<tt>finally</tt> block:
+ *
+ * <blockquote><pre>
+ * try {
+ *     begin();
+ *     // Perform blocking I/O operation here
+ *     ...
+ * } finally {
+ *     end();
+ * }</pre></blockquote>
+ *
+ * <p> This class also defines methods for maintaining a selector's
+ * cancelled-key set and for removing a key from its channel's key set, and
+ * declares the abstract {@link #register register} method that is invoked by a
+ * selectable channel's {@link AbstractSelectableChannel#register register}
+ * method in order to perform the actual work of registering a channel.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class AbstractSelector
+    extends Selector
+{
+
+    private AtomicBoolean selectorOpen = new AtomicBoolean(true);
+
+    // The provider that created this selector
+    private final SelectorProvider provider;
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @param  provider
+     *         The provider that created this selector
+     */
+    protected AbstractSelector(SelectorProvider provider) {
+        this.provider = provider;
+    }
+
+    private final Set<SelectionKey> cancelledKeys = new HashSet<SelectionKey>();
+
+    void cancel(SelectionKey k) {                       // package-private
+        synchronized (cancelledKeys) {
+            cancelledKeys.add(k);
+        }
+    }
+
+    /**
+     * Closes this selector.
+     *
+     * <p> If the selector has already been closed then this method returns
+     * immediately.  Otherwise it marks the selector as closed and then invokes
+     * the {@link #implCloseSelector implCloseSelector} method in order to
+     * complete the close operation.  </p>
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public final void close() throws IOException {
+        boolean open = selectorOpen.getAndSet(false);
+        if (!open)
+            return;
+        implCloseSelector();
+    }
+
+    /**
+     * Closes this selector.
+     *
+     * <p> This method is invoked by the {@link #close close} method in order
+     * to perform the actual work of closing the selector.  This method is only
+     * invoked if the selector has not yet been closed, and it is never invoked
+     * more than once.
+     *
+     * <p> An implementation of this method must arrange for any other thread
+     * that is blocked in a selection operation upon this selector to return
+     * immediately as if by invoking the {@link
+     * java.nio.channels.Selector#wakeup wakeup} method. </p>
+     *
+     * @throws  IOException
+     *          If an I/O error occurs while closing the selector
+     */
+    protected abstract void implCloseSelector() throws IOException;
+
+    public final boolean isOpen() {
+        return selectorOpen.get();
+    }
+
+    /**
+     * Returns the provider that created this channel.
+     *
+     * @return  The provider that created this channel
+     */
+    public final SelectorProvider provider() {
+        return provider;
+    }
+
+    /**
+     * Retrieves this selector's cancelled-key set.
+     *
+     * <p> This set should only be used while synchronized upon it.  </p>
+     *
+     * @return  The cancelled-key set
+     */
+    protected final Set<SelectionKey> cancelledKeys() {
+        return cancelledKeys;
+    }
+
+    /**
+     * Registers the given channel with this selector.
+     *
+     * <p> This method is invoked by a channel's {@link
+     * AbstractSelectableChannel#register register} method in order to perform
+     * the actual work of registering the channel with this selector.  </p>
+     *
+     * @param  ch
+     *         The channel to be registered
+     *
+     * @param  ops
+     *         The initial interest set, which must be valid
+     *
+     * @param  att
+     *         The initial attachment for the resulting key
+     *
+     * @return  A new key representing the registration of the given channel
+     *          with this selector
+     */
+    protected abstract SelectionKey register(AbstractSelectableChannel ch,
+                                             int ops, Object att);
+
+    /**
+     * Removes the given key from its channel's key set.
+     *
+     * <p> This method must be invoked by the selector for each channel that it
+     * deregisters.  </p>
+     *
+     * @param  key
+     *         The selection key to be removed
+     */
+    protected final void deregister(AbstractSelectionKey key) {
+        ((AbstractSelectableChannel)key.channel()).removeKey(key);
+    }
+
+
+    // -- Interruption machinery --
+
+    private Interruptible interruptor = null;
+
+    /**
+     * Marks the beginning of an I/O operation that might block indefinitely.
+     *
+     * <p> This method should be invoked in tandem with the {@link #end end}
+     * method, using a <tt>try</tt>&nbsp;...&nbsp;<tt>finally</tt> block as
+     * shown <a href="#be">above</a>, in order to implement interruption for
+     * this selector.
+     *
+     * <p> Invoking this method arranges for the selector's {@link
+     * Selector#wakeup wakeup} method to be invoked if a thread's {@link
+     * Thread#interrupt interrupt} method is invoked while the thread is
+     * blocked in an I/O operation upon the selector.  </p>
+     */
+    protected final void begin() {
+        if (interruptor == null) {
+            interruptor = new Interruptible() {
+                    public void interrupt(Thread ignore) {
+                        AbstractSelector.this.wakeup();
+                    }};
+        }
+        AbstractInterruptibleChannel.blockedOn(interruptor);
+        Thread me = Thread.currentThread();
+        if (me.isInterrupted())
+            interruptor.interrupt(me);
+    }
+
+    /**
+     * Marks the end of an I/O operation that might block indefinitely.
+     *
+     * <p> This method should be invoked in tandem with the {@link #begin begin}
+     * method, using a <tt>try</tt>&nbsp;...&nbsp;<tt>finally</tt> block as
+     * shown <a href="#be">above</a>, in order to implement interruption for
+     * this selector.  </p>
+     */
+    protected final void end() {
+        AbstractInterruptibleChannel.blockedOn(null);
+    }
+
+}
diff --git a/java/nio/channels/spi/AsynchronousChannelProvider.java b/java/nio/channels/spi/AsynchronousChannelProvider.java
new file mode 100644
index 0000000..464b4fc
--- /dev/null
+++ b/java/nio/channels/spi/AsynchronousChannelProvider.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2007, 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.nio.channels.spi;
+
+import java.nio.channels.*;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import java.util.ServiceConfigurationError;
+import java.util.concurrent.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Service-provider class for asynchronous channels.
+ *
+ * <p> An asynchronous channel provider is a concrete subclass of this class that
+ * has a zero-argument constructor and implements the abstract methods specified
+ * below.  A given invocation of the Java virtual machine maintains a single
+ * system-wide default provider instance, which is returned by the {@link
+ * #provider() provider} method.  The first invocation of that method will locate
+ * the default provider as specified below.
+ *
+ * <p> All of the methods in this class are safe for use by multiple concurrent
+ * threads.  </p>
+ *
+ * @since 1.7
+ */
+
+public abstract class AsynchronousChannelProvider {
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null)
+            sm.checkPermission(new RuntimePermission("asynchronousChannelProvider"));
+        return null;
+    }
+    private AsynchronousChannelProvider(Void ignore) { }
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     *          {@link RuntimePermission}<tt>("asynchronousChannelProvider")</tt>
+     */
+    protected AsynchronousChannelProvider() {
+        this(checkPermission());
+    }
+
+    // lazy initialization of default provider
+    private static class ProviderHolder {
+        static final AsynchronousChannelProvider provider = load();
+
+        private static AsynchronousChannelProvider load() {
+            return AccessController
+                .doPrivileged(new PrivilegedAction<AsynchronousChannelProvider>() {
+                    public AsynchronousChannelProvider run() {
+                        AsynchronousChannelProvider p;
+                        p = loadProviderFromProperty();
+                        if (p != null)
+                            return p;
+                        p = loadProviderAsService();
+                        if (p != null)
+                            return p;
+                        return sun.nio.ch.DefaultAsynchronousChannelProvider.create();
+                    }});
+        }
+
+        private static AsynchronousChannelProvider loadProviderFromProperty() {
+            String cn = System.getProperty("java.nio.channels.spi.AsynchronousChannelProvider");
+            if (cn == null)
+                return null;
+            try {
+                Class<?> c = Class.forName(cn, true,
+                                           ClassLoader.getSystemClassLoader());
+                return (AsynchronousChannelProvider)c.newInstance();
+            } catch (ClassNotFoundException x) {
+                throw new ServiceConfigurationError(null, x);
+            } catch (IllegalAccessException x) {
+                throw new ServiceConfigurationError(null, x);
+            } catch (InstantiationException x) {
+                throw new ServiceConfigurationError(null, x);
+            } catch (SecurityException x) {
+                throw new ServiceConfigurationError(null, x);
+            }
+        }
+
+        private static AsynchronousChannelProvider loadProviderAsService() {
+            ServiceLoader<AsynchronousChannelProvider> sl =
+                ServiceLoader.load(AsynchronousChannelProvider.class,
+                                   ClassLoader.getSystemClassLoader());
+            Iterator<AsynchronousChannelProvider> i = sl.iterator();
+            for (;;) {
+                try {
+                    return (i.hasNext()) ? i.next() : null;
+                } catch (ServiceConfigurationError sce) {
+                    if (sce.getCause() instanceof SecurityException) {
+                        // Ignore the security exception, try the next provider
+                        continue;
+                    }
+                    throw sce;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the system-wide default asynchronous channel provider for this
+     * invocation of the Java virtual machine.
+     *
+     * <p> The first invocation of this method locates the default provider
+     * object as follows: </p>
+     *
+     * <ol>
+     *
+     *   <li><p> If the system property
+     *   <tt>java.nio.channels.spi.AsynchronousChannelProvider</tt> is defined
+     *   then it is taken to be the fully-qualified name of a concrete provider class.
+     *   The class is loaded and instantiated; if this process fails then an
+     *   unspecified error is thrown.  </p></li>
+     *
+     *   <li><p> If a provider class has been installed in a jar file that is
+     *   visible to the system class loader, and that jar file contains a
+     *   provider-configuration file named
+     *   <tt>java.nio.channels.spi.AsynchronousChannelProvider</tt> in the resource
+     *   directory <tt>META-INF/services</tt>, then the first class name
+     *   specified in that file is taken.  The class is loaded and
+     *   instantiated; if this process fails then an unspecified error is
+     *   thrown.  </p></li>
+     *
+     *   <li><p> Finally, if no provider has been specified by any of the above
+     *   means then the system-default provider class is instantiated and the
+     *   result is returned.  </p></li>
+     *
+     * </ol>
+     *
+     * <p> Subsequent invocations of this method return the provider that was
+     * returned by the first invocation.  </p>
+     *
+     * @return  The system-wide default AsynchronousChannel provider
+     */
+    public static AsynchronousChannelProvider provider() {
+        return ProviderHolder.provider;
+    }
+
+    /**
+     * Constructs a new asynchronous channel group with a fixed thread pool.
+     *
+     * @param   nThreads
+     *          The number of threads in the pool
+     * @param   threadFactory
+     *          The factory to use when creating new threads
+     *
+     * @return  A new asynchronous channel group
+     *
+     * @throws  IllegalArgumentException
+     *          If {@code nThreads <= 0}
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @see AsynchronousChannelGroup#withFixedThreadPool
+     */
+    public abstract AsynchronousChannelGroup
+        openAsynchronousChannelGroup(int nThreads, ThreadFactory threadFactory) throws IOException;
+
+    /**
+     * Constructs a new asynchronous channel group with the given thread pool.
+     *
+     * @param   executor
+     *          The thread pool
+     * @param   initialSize
+     *          A value {@code >=0} or a negative value for implementation
+     *          specific default
+     *
+     * @return  A new asynchronous channel group
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @see AsynchronousChannelGroup#withCachedThreadPool
+     */
+    public abstract AsynchronousChannelGroup
+        openAsynchronousChannelGroup(ExecutorService executor, int initialSize) throws IOException;
+
+    /**
+     * Opens an asynchronous server-socket channel.
+     *
+     * @param   group
+     *          The group to which the channel is bound, or {@code null} to
+     *          bind to the default group
+     *
+     * @return  The new channel
+     *
+     * @throws  IllegalChannelGroupException
+     *          If the provider that created the group differs from this provider
+     * @throws  ShutdownChannelGroupException
+     *          The group is shutdown
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract AsynchronousServerSocketChannel openAsynchronousServerSocketChannel
+        (AsynchronousChannelGroup group) throws IOException;
+
+    /**
+     * Opens an asynchronous socket channel.
+     *
+     * @param   group
+     *          The group to which the channel is bound, or {@code null} to
+     *          bind to the default group
+     *
+     * @return  The new channel
+     *
+     * @throws  IllegalChannelGroupException
+     *          If the provider that created the group differs from this provider
+     * @throws  ShutdownChannelGroupException
+     *          The group is shutdown
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract AsynchronousSocketChannel openAsynchronousSocketChannel
+        (AsynchronousChannelGroup group) throws IOException;
+}
diff --git a/java/nio/channels/spi/SelectorProvider.java b/java/nio/channels/spi/SelectorProvider.java
new file mode 100644
index 0000000..2dbef05
--- /dev/null
+++ b/java/nio/channels/spi/SelectorProvider.java
@@ -0,0 +1,317 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.channels.spi;
+
+import java.io.IOException;
+import java.net.ProtocolFamily;
+import java.nio.channels.*;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import java.util.ServiceConfigurationError;
+import sun.security.action.GetPropertyAction;
+
+
+/**
+ * Service-provider class for selectors and selectable channels.
+ *
+ * <p> A selector provider is a concrete subclass of this class that has a
+ * zero-argument constructor and implements the abstract methods specified
+ * below.  A given invocation of the Java virtual machine maintains a single
+ * system-wide default provider instance, which is returned by the {@link
+ * #provider() provider} method.  The first invocation of that method will locate
+ * the default provider as specified below.
+ *
+ * <p> The system-wide default provider is used by the static <tt>open</tt>
+ * methods of the {@link java.nio.channels.DatagramChannel#open
+ * DatagramChannel}, {@link java.nio.channels.Pipe#open Pipe}, {@link
+ * java.nio.channels.Selector#open Selector}, {@link
+ * java.nio.channels.ServerSocketChannel#open ServerSocketChannel}, and {@link
+ * java.nio.channels.SocketChannel#open SocketChannel} classes.  It is also
+ * used by the {@link java.lang.System#inheritedChannel System.inheritedChannel()}
+ * method. A program may make use of a provider other than the default provider
+ * by instantiating that provider and then directly invoking the <tt>open</tt>
+ * methods defined in this class.
+ *
+ * <p> All of the methods in this class are safe for use by multiple concurrent
+ * threads.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public abstract class SelectorProvider {
+
+    private static final Object lock = new Object();
+    private static SelectorProvider provider = null;
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     *          {@link RuntimePermission}<tt>("selectorProvider")</tt>
+     */
+    protected SelectorProvider() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null)
+            sm.checkPermission(new RuntimePermission("selectorProvider"));
+    }
+
+    private static boolean loadProviderFromProperty() {
+        String cn = System.getProperty("java.nio.channels.spi.SelectorProvider");
+        if (cn == null)
+            return false;
+        try {
+            Class<?> c = Class.forName(cn, true,
+                                       ClassLoader.getSystemClassLoader());
+            provider = (SelectorProvider)c.newInstance();
+            return true;
+        } catch (ClassNotFoundException x) {
+            throw new ServiceConfigurationError(null, x);
+        } catch (IllegalAccessException x) {
+            throw new ServiceConfigurationError(null, x);
+        } catch (InstantiationException x) {
+            throw new ServiceConfigurationError(null, x);
+        } catch (SecurityException x) {
+            throw new ServiceConfigurationError(null, x);
+        }
+    }
+
+    private static boolean loadProviderAsService() {
+
+        ServiceLoader<SelectorProvider> sl =
+            ServiceLoader.load(SelectorProvider.class,
+                               ClassLoader.getSystemClassLoader());
+        Iterator<SelectorProvider> i = sl.iterator();
+        for (;;) {
+            try {
+                if (!i.hasNext())
+                    return false;
+                provider = i.next();
+                return true;
+            } catch (ServiceConfigurationError sce) {
+                if (sce.getCause() instanceof SecurityException) {
+                    // Ignore the security exception, try the next provider
+                    continue;
+                }
+                throw sce;
+            }
+        }
+    }
+
+    /**
+     * Returns the system-wide default selector provider for this invocation of
+     * the Java virtual machine.
+     *
+     * <p> The first invocation of this method locates the default provider
+     * object as follows: </p>
+     *
+     * <ol>
+     *
+     *   <li><p> If the system property
+     *   <tt>java.nio.channels.spi.SelectorProvider</tt> is defined then it is
+     *   taken to be the fully-qualified name of a concrete provider class.
+     *   The class is loaded and instantiated; if this process fails then an
+     *   unspecified error is thrown.  </p></li>
+     *
+     *   <li><p> If a provider class has been installed in a jar file that is
+     *   visible to the system class loader, and that jar file contains a
+     *   provider-configuration file named
+     *   <tt>java.nio.channels.spi.SelectorProvider</tt> in the resource
+     *   directory <tt>META-INF/services</tt>, then the first class name
+     *   specified in that file is taken.  The class is loaded and
+     *   instantiated; if this process fails then an unspecified error is
+     *   thrown.  </p></li>
+     *
+     *   <li><p> Finally, if no provider has been specified by any of the above
+     *   means then the system-default provider class is instantiated and the
+     *   result is returned.  </p></li>
+     *
+     * </ol>
+     *
+     * <p> Subsequent invocations of this method return the provider that was
+     * returned by the first invocation.  </p>
+     *
+     * @return  The system-wide default selector provider
+     */
+    public static SelectorProvider provider() {
+        synchronized (lock) {
+            if (provider != null)
+                return provider;
+            return AccessController.doPrivileged(
+                new PrivilegedAction<SelectorProvider>() {
+                    public SelectorProvider run() {
+                            if (loadProviderFromProperty())
+                                return provider;
+                            if (loadProviderAsService())
+                                return provider;
+                            provider = sun.nio.ch.DefaultSelectorProvider.create();
+                            return provider;
+                        }
+                    });
+        }
+    }
+
+    /**
+     * Opens a datagram channel.
+     *
+     * @return  The new channel
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract DatagramChannel openDatagramChannel()
+        throws IOException;
+
+    /**
+     * Opens a datagram channel.
+     *
+     * @param   family
+     *          The protocol family
+     *
+     * @return  A new datagram channel
+     *
+     * @throws  UnsupportedOperationException
+     *          If the specified protocol family is not supported
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @since 1.7
+     */
+    public abstract DatagramChannel openDatagramChannel(ProtocolFamily family)
+        throws IOException;
+
+    /**
+     * Opens a pipe.
+     *
+     * @return  The new pipe
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract Pipe openPipe()
+        throws IOException;
+
+    /**
+     * Opens a selector.
+     *
+     * @return  The new selector
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract AbstractSelector openSelector()
+        throws IOException;
+
+    /**
+     * Opens a server-socket channel.
+     *
+     * @return  The new channel
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract ServerSocketChannel openServerSocketChannel()
+        throws IOException;
+
+    /**
+     * Opens a socket channel.
+     *
+     * @return  The new channel
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract SocketChannel openSocketChannel()
+        throws IOException;
+
+    /**
+     * Returns the channel inherited from the entity that created this
+     * Java virtual machine.
+     *
+     * <p> On many operating systems a process, such as a Java virtual
+     * machine, can be started in a manner that allows the process to
+     * inherit a channel from the entity that created the process. The
+     * manner in which this is done is system dependent, as are the
+     * possible entities to which the channel may be connected. For example,
+     * on UNIX systems, the Internet services daemon (<i>inetd</i>) is used to
+     * start programs to service requests when a request arrives on an
+     * associated network port. In this example, the process that is started,
+     * inherits a channel representing a network socket.
+     *
+     * <p> In cases where the inherited channel represents a network socket
+     * then the {@link java.nio.channels.Channel Channel} type returned
+     * by this method is determined as follows:
+     *
+     * <ul>
+     *
+     *  <li><p> If the inherited channel represents a stream-oriented connected
+     *  socket then a {@link java.nio.channels.SocketChannel SocketChannel} is
+     *  returned. The socket channel is, at least initially, in blocking
+     *  mode, bound to a socket address, and connected to a peer.
+     *  </p></li>
+     *
+     *  <li><p> If the inherited channel represents a stream-oriented listening
+     *  socket then a {@link java.nio.channels.ServerSocketChannel
+     *  ServerSocketChannel} is returned. The server-socket channel is, at
+     *  least initially, in blocking mode, and bound to a socket address.
+     *  </p></li>
+     *
+     *  <li><p> If the inherited channel is a datagram-oriented socket
+     *  then a {@link java.nio.channels.DatagramChannel DatagramChannel} is
+     *  returned. The datagram channel is, at least initially, in blocking
+     *  mode, and bound to a socket address.
+     *  </p></li>
+     *
+     * </ul>
+     *
+     * <p> In addition to the network-oriented channels described, this method
+     * may return other kinds of channels in the future.
+     *
+     * <p> The first invocation of this method creates the channel that is
+     * returned. Subsequent invocations of this method return the same
+     * channel. </p>
+     *
+     * @return  The inherited channel, if any, otherwise <tt>null</tt>.
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     *          {@link RuntimePermission}<tt>("inheritedChannel")</tt>
+     *
+     * @since 1.5
+     */
+   public Channel inheritedChannel() throws IOException {
+        return null;
+   }
+
+}
diff --git a/java/nio/charset/CharacterCodingException.java b/java/nio/charset/CharacterCodingException.java
new file mode 100644
index 0000000..1cfeb5f
--- /dev/null
+++ b/java/nio/charset/CharacterCodingException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.charset;
+
+
+/**
+ * Checked exception thrown when a character encoding
+ * or decoding error occurs.
+ *
+ * @since 1.4
+ */
+
+public class CharacterCodingException
+    extends java.io.IOException
+{
+
+    private static final long serialVersionUID = 8421532232154627783L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public CharacterCodingException() { }
+
+}
diff --git a/java/nio/charset/Charset.java b/java/nio/charset/Charset.java
new file mode 100644
index 0000000..5a3b35a
--- /dev/null
+++ b/java/nio/charset/Charset.java
@@ -0,0 +1,967 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.charset;
+
+import com.android.icu.charset.CharsetICU;
+import java.io.UnsupportedEncodingException;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.spi.CharsetProvider;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.ServiceLoader;
+import java.util.ServiceConfigurationError;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import sun.misc.ASCIICaseInsensitiveComparator;
+import sun.nio.cs.ThreadLocalCoders;
+import sun.security.action.GetPropertyAction;
+
+
+// Android-changed: Docs to say UTF-8 is always the platform default charset.
+/**
+ * A named mapping between sequences of sixteen-bit Unicode <a
+ * href="../../lang/Character.html#unicode">code units</a> and sequences of
+ * bytes.  This class defines methods for creating decoders and encoders and
+ * for retrieving the various names associated with a charset.  Instances of
+ * this class are immutable.
+ *
+ * <p> This class also defines static methods for testing whether a particular
+ * charset is supported, for locating charset instances by name, and for
+ * constructing a map that contains every charset for which support is
+ * available in the current Java virtual machine.  Support for new charsets can
+ * be added via the service-provider interface defined in the {@link
+ * java.nio.charset.spi.CharsetProvider} class.
+ *
+ * <p> All of the methods defined in this class are safe for use by multiple
+ * concurrent threads.
+ *
+ *
+ * <a name="names"></a><a name="charenc"></a>
+ * <h2>Charset names</h2>
+ *
+ * <p> Charsets are named by strings composed of the following characters:
+ *
+ * <ul>
+ *
+ *   <li> The uppercase letters <tt>'A'</tt> through <tt>'Z'</tt>
+ *        (<tt>'&#92;u0041'</tt>&nbsp;through&nbsp;<tt>'&#92;u005a'</tt>),
+ *
+ *   <li> The lowercase letters <tt>'a'</tt> through <tt>'z'</tt>
+ *        (<tt>'&#92;u0061'</tt>&nbsp;through&nbsp;<tt>'&#92;u007a'</tt>),
+ *
+ *   <li> The digits <tt>'0'</tt> through <tt>'9'</tt>
+ *        (<tt>'&#92;u0030'</tt>&nbsp;through&nbsp;<tt>'&#92;u0039'</tt>),
+ *
+ *   <li> The dash character <tt>'-'</tt>
+ *        (<tt>'&#92;u002d'</tt>,&nbsp;<small>HYPHEN-MINUS</small>),
+ *
+ *   <li> The plus character <tt>'+'</tt>
+ *        (<tt>'&#92;u002b'</tt>,&nbsp;<small>PLUS SIGN</small>),
+ *
+ *   <li> The period character <tt>'.'</tt>
+ *        (<tt>'&#92;u002e'</tt>,&nbsp;<small>FULL STOP</small>),
+ *
+ *   <li> The colon character <tt>':'</tt>
+ *        (<tt>'&#92;u003a'</tt>,&nbsp;<small>COLON</small>), and
+ *
+ *   <li> The underscore character <tt>'_'</tt>
+ *        (<tt>'&#92;u005f'</tt>,&nbsp;<small>LOW&nbsp;LINE</small>).
+ *
+ * </ul>
+ *
+ * A charset name must begin with either a letter or a digit.  The empty string
+ * is not a legal charset name.  Charset names are not case-sensitive; that is,
+ * case is always ignored when comparing charset names.  Charset names
+ * generally follow the conventions documented in <a
+ * href="http://www.ietf.org/rfc/rfc2278.txt"><i>RFC&nbsp;2278:&nbsp;IANA Charset
+ * Registration Procedures</i></a>.
+ *
+ * <p> Every charset has a <i>canonical name</i> and may also have one or more
+ * <i>aliases</i>.  The canonical name is returned by the {@link #name() name} method
+ * of this class.  Canonical names are, by convention, usually in upper case.
+ * The aliases of a charset are returned by the {@link #aliases() aliases}
+ * method.
+ *
+ * <p><a name="hn">Some charsets have an <i>historical name</i> that is defined for
+ * compatibility with previous versions of the Java platform.</a>  A charset's
+ * historical name is either its canonical name or one of its aliases.  The
+ * historical name is returned by the <tt>getEncoding()</tt> methods of the
+ * {@link java.io.InputStreamReader#getEncoding InputStreamReader} and {@link
+ * java.io.OutputStreamWriter#getEncoding OutputStreamWriter} classes.
+ *
+ * <p><a name="iana"> </a>If a charset listed in the <a
+ * href="http://www.iana.org/assignments/character-sets"><i>IANA Charset
+ * Registry</i></a> is supported by an implementation of the Java platform then
+ * its canonical name must be the name listed in the registry. Many charsets
+ * are given more than one name in the registry, in which case the registry
+ * identifies one of the names as <i>MIME-preferred</i>.  If a charset has more
+ * than one registry name then its canonical name must be the MIME-preferred
+ * name and the other names in the registry must be valid aliases.  If a
+ * supported charset is not listed in the IANA registry then its canonical name
+ * must begin with one of the strings <tt>"X-"</tt> or <tt>"x-"</tt>.
+ *
+ * <p> The IANA charset registry does change over time, and so the canonical
+ * name and the aliases of a particular charset may also change over time.  To
+ * ensure compatibility it is recommended that no alias ever be removed from a
+ * charset, and that if the canonical name of a charset is changed then its
+ * previous canonical name be made into an alias.
+ *
+ *
+ * <h2>Standard charsets</h2>
+ *
+ *
+ *
+ * <p><a name="standard">Every implementation of the Java platform is required to support the
+ * following standard charsets.</a>  Consult the release documentation for your
+ * implementation to see if any other charsets are supported.  The behavior
+ * of such optional charsets may differ between implementations.
+ *
+ * <blockquote><table width="80%" summary="Description of standard charsets">
+ * <tr><th align="left">Charset</th><th align="left">Description</th></tr>
+ * <tr><td valign=top><tt>US-ASCII</tt></td>
+ *     <td>Seven-bit ASCII, a.k.a. <tt>ISO646-US</tt>,
+ *         a.k.a. the Basic Latin block of the Unicode character set</td></tr>
+ * <tr><td valign=top><tt>ISO-8859-1&nbsp;&nbsp;</tt></td>
+ *     <td>ISO Latin Alphabet No. 1, a.k.a. <tt>ISO-LATIN-1</tt></td></tr>
+ * <tr><td valign=top><tt>UTF-8</tt></td>
+ *     <td>Eight-bit UCS Transformation Format</td></tr>
+ * <tr><td valign=top><tt>UTF-16BE</tt></td>
+ *     <td>Sixteen-bit UCS Transformation Format,
+ *         big-endian byte&nbsp;order</td></tr>
+ * <tr><td valign=top><tt>UTF-16LE</tt></td>
+ *     <td>Sixteen-bit UCS Transformation Format,
+ *         little-endian byte&nbsp;order</td></tr>
+ * <tr><td valign=top><tt>UTF-16</tt></td>
+ *     <td>Sixteen-bit UCS Transformation Format,
+ *         byte&nbsp;order identified by an optional byte-order mark</td></tr>
+ * </table></blockquote>
+ *
+ * <p> The <tt>UTF-8</tt> charset is specified by <a
+ * href="http://www.ietf.org/rfc/rfc2279.txt"><i>RFC&nbsp;2279</i></a>; the
+ * transformation format upon which it is based is specified in
+ * Amendment&nbsp;2 of ISO&nbsp;10646-1 and is also described in the <a
+ * href="http://www.unicode.org/unicode/standard/standard.html"><i>Unicode
+ * Standard</i></a>.
+ *
+ * <p> The <tt>UTF-16</tt> charsets are specified by <a
+ * href="http://www.ietf.org/rfc/rfc2781.txt"><i>RFC&nbsp;2781</i></a>; the
+ * transformation formats upon which they are based are specified in
+ * Amendment&nbsp;1 of ISO&nbsp;10646-1 and are also described in the <a
+ * href="http://www.unicode.org/unicode/standard/standard.html"><i>Unicode
+ * Standard</i></a>.
+ *
+ * <p> The <tt>UTF-16</tt> charsets use sixteen-bit quantities and are
+ * therefore sensitive to byte order.  In these encodings the byte order of a
+ * stream may be indicated by an initial <i>byte-order mark</i> represented by
+ * the Unicode character <tt>'&#92;uFEFF'</tt>.  Byte-order marks are handled
+ * as follows:
+ *
+ * <ul>
+ *
+ *   <li><p> When decoding, the <tt>UTF-16BE</tt> and <tt>UTF-16LE</tt>
+ *   charsets interpret the initial byte-order marks as a <small>ZERO-WIDTH
+ *   NON-BREAKING SPACE</small>; when encoding, they do not write
+ *   byte-order marks. </p></li>
+
+ *
+ *   <li><p> When decoding, the <tt>UTF-16</tt> charset interprets the
+ *   byte-order mark at the beginning of the input stream to indicate the
+ *   byte-order of the stream but defaults to big-endian if there is no
+ *   byte-order mark; when encoding, it uses big-endian byte order and writes
+ *   a big-endian byte-order mark. </p></li>
+ *
+ * </ul>
+ *
+ * In any case, byte order marks occurring after the first element of an
+ * input sequence are not omitted since the same code is used to represent
+ * <small>ZERO-WIDTH NON-BREAKING SPACE</small>.
+ *
+ * <p>Android note: The Android platform default is always UTF-8.
+ *
+ * <p>The {@link StandardCharsets} class defines constants for each of the
+ * standard charsets.
+ *
+ * <h2>Terminology</h2>
+ *
+ * <p> The name of this class is taken from the terms used in
+ * <a href="http://www.ietf.org/rfc/rfc2278.txt"><i>RFC&nbsp;2278</i></a>.
+ * In that document a <i>charset</i> is defined as the combination of
+ * one or more coded character sets and a character-encoding scheme.
+ * (This definition is confusing; some other software systems define
+ * <i>charset</i> as a synonym for <i>coded character set</i>.)
+ *
+ * <p> A <i>coded character set</i> is a mapping between a set of abstract
+ * characters and a set of integers.  US-ASCII, ISO&nbsp;8859-1,
+ * JIS&nbsp;X&nbsp;0201, and Unicode are examples of coded character sets.
+ *
+ * <p> Some standards have defined a <i>character set</i> to be simply a
+ * set of abstract characters without an associated assigned numbering.
+ * An alphabet is an example of such a character set.  However, the subtle
+ * distinction between <i>character set</i> and <i>coded character set</i>
+ * is rarely used in practice; the former has become a short form for the
+ * latter, including in the Java API specification.
+ *
+ * <p> A <i>character-encoding scheme</i> is a mapping between one or more
+ * coded character sets and a set of octet (eight-bit byte) sequences.
+ * UTF-8, UTF-16, ISO&nbsp;2022, and EUC are examples of
+ * character-encoding schemes.  Encoding schemes are often associated with
+ * a particular coded character set; UTF-8, for example, is used only to
+ * encode Unicode.  Some schemes, however, are associated with multiple
+ * coded character sets; EUC, for example, can be used to encode
+ * characters in a variety of Asian coded character sets.
+ *
+ * <p> When a coded character set is used exclusively with a single
+ * character-encoding scheme then the corresponding charset is usually
+ * named for the coded character set; otherwise a charset is usually named
+ * for the encoding scheme and, possibly, the locale of the coded
+ * character sets that it supports.  Hence <tt>US-ASCII</tt> is both the
+ * name of a coded character set and of the charset that encodes it, while
+ * <tt>EUC-JP</tt> is the name of the charset that encodes the
+ * JIS&nbsp;X&nbsp;0201, JIS&nbsp;X&nbsp;0208, and JIS&nbsp;X&nbsp;0212
+ * coded character sets for the Japanese language.
+ *
+ * <p> The native character encoding of the Java programming language is
+ * UTF-16.  A charset in the Java platform therefore defines a mapping
+ * between sequences of sixteen-bit UTF-16 code units (that is, sequences
+ * of chars) and sequences of bytes. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see CharsetDecoder
+ * @see CharsetEncoder
+ * @see java.nio.charset.spi.CharsetProvider
+ * @see java.lang.Character
+ */
+
+public abstract class Charset
+    implements Comparable<Charset>
+{
+
+    /* -- Static methods -- */
+
+    private static volatile String bugLevel = null;
+
+    static boolean atBugLevel(String bl) {              // package-private
+        String level = bugLevel;
+        if (level == null) {
+            if (!sun.misc.VM.isBooted())
+                return false;
+            bugLevel = level = AccessController.doPrivileged(
+                new GetPropertyAction("sun.nio.cs.bugLevel", ""));
+        }
+        return level.equals(bl);
+    }
+
+    /**
+     * Checks that the given string is a legal charset name. </p>
+     *
+     * @param  s
+     *         A purported charset name
+     *
+     * @throws  IllegalCharsetNameException
+     *          If the given name is not a legal charset name
+     */
+    private static void checkName(String s) {
+        int n = s.length();
+        if (!atBugLevel("1.4")) {
+            if (n == 0)
+                throw new IllegalCharsetNameException(s);
+        }
+        for (int i = 0; i < n; i++) {
+            char c = s.charAt(i);
+            if (c >= 'A' && c <= 'Z') continue;
+            if (c >= 'a' && c <= 'z') continue;
+            if (c >= '0' && c <= '9') continue;
+            if (c == '-' && i != 0) continue;
+            if (c == '+' && i != 0) continue;
+            if (c == ':' && i != 0) continue;
+            if (c == '_' && i != 0) continue;
+            if (c == '.' && i != 0) continue;
+            throw new IllegalCharsetNameException(s);
+        }
+    }
+
+    // Android-removed: We use ICU's list of standard charsets.
+    /* The standard set of charsets */
+    // private static CharsetProvider standardProvider = new StandardCharsets();
+
+    // Cache of the most-recently-returned charsets,
+    // along with the names that were used to find them
+    //
+    // cache1/2 usage is explained in the lookup method
+    //
+    private static volatile Map.Entry<String, Charset> cache1 = null; // "Level 1" cache
+    private static final HashMap<String, Charset> cache2 = new HashMap<>(); // "Level 2" cache
+
+    private static void cache(String charsetName, Charset cs) {
+        synchronized(cache2) {
+            String canonicalName = cs.name();
+            Charset canonicalCharset = cache2.get(canonicalName);
+
+            if (canonicalCharset != null) {
+                cs = canonicalCharset;
+            } else {
+                cache2.put(canonicalName, cs);
+
+                for (String alias : cs.aliases()) {
+                    cache2.put(alias, cs);
+                }
+            }
+
+            cache2.put(charsetName, cs);
+        }
+
+        cache1 = new AbstractMap.SimpleImmutableEntry<>(charsetName, cs);
+    }
+
+    // Creates an iterator that walks over the available providers, ignoring
+    // those whose lookup or instantiation causes a security exception to be
+    // thrown.  Should be invoked with full privileges.
+    //
+    private static Iterator<CharsetProvider> providers() {
+        return new Iterator<CharsetProvider>() {
+
+                ServiceLoader<CharsetProvider> sl =
+                    ServiceLoader.load(CharsetProvider.class);
+                Iterator<CharsetProvider> i = sl.iterator();
+
+                CharsetProvider next = null;
+
+                private boolean getNext() {
+                    while (next == null) {
+                        try {
+                            if (!i.hasNext())
+                                return false;
+                            next = i.next();
+                        } catch (ServiceConfigurationError sce) {
+                            if (sce.getCause() instanceof SecurityException) {
+                                // Ignore security exceptions
+                                continue;
+                            }
+                            throw sce;
+                        }
+                    }
+                    return true;
+                }
+
+                public boolean hasNext() {
+                    return getNext();
+                }
+
+                public CharsetProvider next() {
+                    if (!getNext())
+                        throw new NoSuchElementException();
+                    CharsetProvider n = next;
+                    next = null;
+                    return n;
+                }
+
+                public void remove() {
+                    throw new UnsupportedOperationException();
+                }
+
+            };
+    }
+
+    // Thread-local gate to prevent recursive provider lookups
+    private static ThreadLocal<ThreadLocal<?>> gate =
+            new ThreadLocal<ThreadLocal<?>>();
+
+    private static Charset lookupViaProviders(final String charsetName) {
+
+        // The runtime startup sequence looks up standard charsets as a
+        // consequence of the VM's invocation of System.initializeSystemClass
+        // in order to, e.g., set system properties and encode filenames.  At
+        // that point the application class loader has not been initialized,
+        // however, so we can't look for providers because doing so will cause
+        // that loader to be prematurely initialized with incomplete
+        // information.
+        //
+        if (!sun.misc.VM.isBooted())
+            return null;
+
+        if (gate.get() != null)
+            // Avoid recursive provider lookups
+            return null;
+        try {
+            gate.set(gate);
+
+            return AccessController.doPrivileged(
+                new PrivilegedAction<Charset>() {
+                    public Charset run() {
+                        for (Iterator<CharsetProvider> i = providers();
+                             i.hasNext();) {
+                            CharsetProvider cp = i.next();
+                            Charset cs = cp.charsetForName(charsetName);
+                            if (cs != null)
+                                return cs;
+                        }
+                        return null;
+                    }
+                });
+
+        } finally {
+            gate.set(null);
+        }
+    }
+
+    // Android-removed: Remove support for the extended charset provider.
+    //
+    /* The extended set of charsets */
+    // private static Object extendedProviderLock = new Object();
+    // private static boolean extendedProviderProbed = false;
+    // private static CharsetProvider extendedProvider = null;
+    //
+    // private static void probeExtendedProvider() {
+    //     AccessController.doPrivileged(new PrivilegedAction<Object>() {
+    //            public Object run() {
+    //                 try {
+    //                     Class epc
+    //                         = Class.forName("sun.nio.cs.ext.ExtendedCharsets");
+    //                     extendedProvider = (CharsetProvider)epc.newInstance();
+    //                 } catch (ClassNotFoundException x) {
+    //                     // Extended charsets not available
+    //                     // (charsets.jar not present)
+    //                 } catch (InstantiationException x) {
+    //                     throw new Error(x);
+    //                 } catch (IllegalAccessException x) {
+    //                     throw new Error(x);
+    //                }
+    //                 return null;
+    //             }
+    //         });
+    // }
+    //
+    // private static Charset lookupExtendedCharset(String charsetName) {
+    //     CharsetProvider ecp = null;
+    //     synchronized (extendedProviderLock) {
+    //         if (!extendedProviderProbed) {
+    //             probeExtendedProvider();
+    //             extendedProviderProbed = true;
+    //         }
+    //         ecp = extendedProvider;
+    //     }
+    //     return (ecp != null) ? ecp.charsetForName(charsetName) : null;
+    // }
+
+    // We expect most programs to use one Charset repeatedly, so the most recently used Charset
+    // instance is stored in the level 1 cache. We convey a hint to this effect to the VM by putting
+    // the level 1 cache miss code in a separate method. Since charsetName is not necessarily in
+    // canonical form, we store the mapping from both the canonical name and the aliases to the
+    // instance in a map for level 2 cache.
+    private static Charset lookup(String charsetName) {
+        if (charsetName == null)
+            throw new IllegalArgumentException("Null charset name");
+
+
+        final Map.Entry<String, Charset> cached = cache1;
+        if (cached != null && charsetName.equals(cached.getKey()))
+            return cached.getValue();
+        return lookup2(charsetName);
+    }
+
+    private static Charset lookup2(String charsetName) {
+        Charset cs;
+        synchronized (cache2) {
+            if ((cs = cache2.get(charsetName)) != null) {
+                cache1 = new AbstractMap.SimpleImmutableEntry<>(charsetName, cs);
+                return cs;
+            }
+        }
+
+        // Android-changed: Drop support for "standard" and "extended"
+        // providers.
+        if ((cs = CharsetICU.charsetForName(charsetName))  != null ||
+            (cs = lookupViaProviders(charsetName))              != null)
+        {
+            cache(charsetName, cs);
+            return cs;
+        }
+
+        /* Only need to check the name if we didn't find a charset for it */
+        checkName(charsetName);
+        return null;
+    }
+
+    /**
+     * Tells whether the named charset is supported.
+     *
+     * @param  charsetName
+     *         The name of the requested charset; may be either
+     *         a canonical name or an alias
+     *
+     * @return  <tt>true</tt> if, and only if, support for the named charset
+     *          is available in the current Java virtual machine
+     *
+     * @throws IllegalCharsetNameException
+     *         If the given charset name is illegal
+     *
+     * @throws  IllegalArgumentException
+     *          If the given <tt>charsetName</tt> is null
+     */
+    public static boolean isSupported(String charsetName) {
+        return (lookup(charsetName) != null);
+    }
+
+    /**
+     * Returns a charset object for the named charset.
+     *
+     * @param  charsetName
+     *         The name of the requested charset; may be either
+     *         a canonical name or an alias
+     *
+     * @return  A charset object for the named charset
+     *
+     * @throws  IllegalCharsetNameException
+     *          If the given charset name is illegal
+     *
+     * @throws  IllegalArgumentException
+     *          If the given <tt>charsetName</tt> is null
+     *
+     * @throws  UnsupportedCharsetException
+     *          If no support for the named charset is available
+     *          in this instance of the Java virtual machine
+     */
+    public static Charset forName(String charsetName) {
+        Charset cs = lookup(charsetName);
+        if (cs != null)
+            return cs;
+        throw new UnsupportedCharsetException(charsetName);
+    }
+
+    // BEGIN Android-added: forNameUEE(String) method.
+    /**
+     * Equivalent to {@code forName} but only throws {@code UnsupportedEncodingException},
+     * which is all pre-nio code claims to throw.
+     *
+     * @hide internal use only
+     */
+    public static Charset forNameUEE(String charsetName) throws UnsupportedEncodingException {
+        try {
+            return Charset.forName(charsetName);
+        } catch (Exception cause) {
+            UnsupportedEncodingException ex = new UnsupportedEncodingException(charsetName);
+            ex.initCause(cause);
+            throw ex;
+        }
+    }
+    // END Android-added: forNameUEE(String) method.
+
+    // Fold charsets from the given iterator into the given map, ignoring
+    // charsets whose names already have entries in the map.
+    //
+    private static void put(Iterator<Charset> i, Map<String,Charset> m) {
+        while (i.hasNext()) {
+            Charset cs = i.next();
+            if (!m.containsKey(cs.name()))
+                m.put(cs.name(), cs);
+        }
+    }
+
+    /**
+     * Constructs a sorted map from canonical charset names to charset objects.
+     *
+     * <p> The map returned by this method will have one entry for each charset
+     * for which support is available in the current Java virtual machine.  If
+     * two or more supported charsets have the same canonical name then the
+     * resulting map will contain just one of them; which one it will contain
+     * is not specified. </p>
+     *
+     * <p> The invocation of this method, and the subsequent use of the
+     * resulting map, may cause time-consuming disk or network I/O operations
+     * to occur.  This method is provided for applications that need to
+     * enumerate all of the available charsets, for example to allow user
+     * charset selection.  This method is not used by the {@link #forName
+     * forName} method, which instead employs an efficient incremental lookup
+     * algorithm.
+     *
+     * <p> This method may return different results at different times if new
+     * charset providers are dynamically made available to the current Java
+     * virtual machine.  In the absence of such changes, the charsets returned
+     * by this method are exactly those that can be retrieved via the {@link
+     * #forName forName} method.  </p>
+     *
+     * @return An immutable, case-insensitive map from canonical charset names
+     *         to charset objects
+     */
+    public static SortedMap<String,Charset> availableCharsets() {
+        return AccessController.doPrivileged(
+            new PrivilegedAction<SortedMap<String,Charset>>() {
+                public SortedMap<String,Charset> run() {
+                    TreeMap<String,Charset> m =
+                        new TreeMap<String,Charset>(
+                            ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER);
+                    for (String charsetName : CharsetICU.getAvailableCharsetNames()) {
+                        Charset charset = CharsetICU.charsetForName(charsetName);
+                        m.put(charset.name(), charset);
+                    }
+                    // Android-changed: No more "standard" provider.
+                    // put(standardProvider.charsets(), m);
+                    for (Iterator i = providers(); i.hasNext();) {
+                        CharsetProvider cp = (CharsetProvider)i.next();
+                        put(cp.charsets(), m);
+                    }
+                    return Collections.unmodifiableSortedMap(m);
+                }
+            });
+    }
+
+    private static Charset defaultCharset;
+
+    /**
+     * Returns the default charset of this Java virtual machine.
+     *
+     * <p>Android note: The Android platform default is always UTF-8.
+     *
+     * @return  A charset object for the default charset
+     *
+     * @since 1.5
+     */
+    public static Charset defaultCharset() {
+        // Android-changed: Use UTF_8 unconditionally.
+        synchronized (Charset.class) {
+            if (defaultCharset == null) {
+                defaultCharset = java.nio.charset.StandardCharsets.UTF_8;
+            }
+
+            return defaultCharset;
+        }
+    }
+
+
+    /* -- Instance fields and methods -- */
+
+    private final String name;          // tickles a bug in oldjavac
+    private final String[] aliases;     // tickles a bug in oldjavac
+    private Set<String> aliasSet = null;
+
+    /**
+     * Initializes a new charset with the given canonical name and alias
+     * set.
+     *
+     * @param  canonicalName
+     *         The canonical name of this charset
+     *
+     * @param  aliases
+     *         An array of this charset's aliases, or null if it has no aliases
+     *
+     * @throws IllegalCharsetNameException
+     *         If the canonical name or any of the aliases are illegal
+     */
+    @libcore.api.IntraCoreApi
+    protected Charset(String canonicalName, String[] aliases) {
+        checkName(canonicalName);
+        String[] as = (aliases == null) ? new String[0] : aliases;
+        for (int i = 0; i < as.length; i++)
+            checkName(as[i]);
+        this.name = canonicalName;
+        this.aliases = as;
+    }
+
+    /**
+     * Returns this charset's canonical name.
+     *
+     * @return  The canonical name of this charset
+     */
+    public final String name() {
+        return name;
+    }
+
+    /**
+     * Returns a set containing this charset's aliases.
+     *
+     * @return  An immutable set of this charset's aliases
+     */
+    public final Set<String> aliases() {
+        if (aliasSet != null)
+            return aliasSet;
+        int n = aliases.length;
+        HashSet<String> hs = new HashSet<String>(n);
+        for (int i = 0; i < n; i++)
+            hs.add(aliases[i]);
+        aliasSet = Collections.unmodifiableSet(hs);
+        return aliasSet;
+    }
+
+    /**
+     * Returns this charset's human-readable name for the default locale.
+     *
+     * <p> The default implementation of this method simply returns this
+     * charset's canonical name.  Concrete subclasses of this class may
+     * override this method in order to provide a localized display name. </p>
+     *
+     * @return  The display name of this charset in the default locale
+     */
+    public String displayName() {
+        return name;
+    }
+
+    /**
+     * Tells whether or not this charset is registered in the <a
+     * href="http://www.iana.org/assignments/character-sets">IANA Charset
+     * Registry</a>.
+     *
+     * @return  <tt>true</tt> if, and only if, this charset is known by its
+     *          implementor to be registered with the IANA
+     */
+    public final boolean isRegistered() {
+        return !name.startsWith("X-") && !name.startsWith("x-");
+    }
+
+    /**
+     * Returns this charset's human-readable name for the given locale.
+     *
+     * <p> The default implementation of this method simply returns this
+     * charset's canonical name.  Concrete subclasses of this class may
+     * override this method in order to provide a localized display name. </p>
+     *
+     * @param  locale
+     *         The locale for which the display name is to be retrieved
+     *
+     * @return  The display name of this charset in the given locale
+     */
+    public String displayName(Locale locale) {
+        return name;
+    }
+
+    /**
+     * Tells whether or not this charset contains the given charset.
+     *
+     * <p> A charset <i>C</i> is said to <i>contain</i> a charset <i>D</i> if,
+     * and only if, every character representable in <i>D</i> is also
+     * representable in <i>C</i>.  If this relationship holds then it is
+     * guaranteed that every string that can be encoded in <i>D</i> can also be
+     * encoded in <i>C</i> without performing any replacements.
+     *
+     * <p> That <i>C</i> contains <i>D</i> does not imply that each character
+     * representable in <i>C</i> by a particular byte sequence is represented
+     * in <i>D</i> by the same byte sequence, although sometimes this is the
+     * case.
+     *
+     * <p> Every charset contains itself.
+     *
+     * <p> This method computes an approximation of the containment relation:
+     * If it returns <tt>true</tt> then the given charset is known to be
+     * contained by this charset; if it returns <tt>false</tt>, however, then
+     * it is not necessarily the case that the given charset is not contained
+     * in this charset.
+     *
+     * @param   cs
+     *          The given charset
+     *
+     * @return  <tt>true</tt> if the given charset is contained in this charset
+     */
+    public abstract boolean contains(Charset cs);
+
+    /**
+     * Constructs a new decoder for this charset.
+     *
+     * @return  A new decoder for this charset
+     */
+    public abstract CharsetDecoder newDecoder();
+
+    /**
+     * Constructs a new encoder for this charset.
+     *
+     * @return  A new encoder for this charset
+     *
+     * @throws  UnsupportedOperationException
+     *          If this charset does not support encoding
+     */
+    public abstract CharsetEncoder newEncoder();
+
+    /**
+     * Tells whether or not this charset supports encoding.
+     *
+     * <p> Nearly all charsets support encoding.  The primary exceptions are
+     * special-purpose <i>auto-detect</i> charsets whose decoders can determine
+     * which of several possible encoding schemes is in use by examining the
+     * input byte sequence.  Such charsets do not support encoding because
+     * there is no way to determine which encoding should be used on output.
+     * Implementations of such charsets should override this method to return
+     * <tt>false</tt>. </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this charset supports encoding
+     */
+    public boolean canEncode() {
+        return true;
+    }
+
+    /**
+     * Convenience method that decodes bytes in this charset into Unicode
+     * characters.
+     *
+     * <p> An invocation of this method upon a charset <tt>cs</tt> returns the
+     * same result as the expression
+     *
+     * <pre>
+     *     cs.newDecoder()
+     *       .onMalformedInput(CodingErrorAction.REPLACE)
+     *       .onUnmappableCharacter(CodingErrorAction.REPLACE)
+     *       .decode(bb); </pre>
+     *
+     * except that it is potentially more efficient because it can cache
+     * decoders between successive invocations.
+     *
+     * <p> This method always replaces malformed-input and unmappable-character
+     * sequences with this charset's default replacement byte array.  In order
+     * to detect such sequences, use the {@link
+     * CharsetDecoder#decode(java.nio.ByteBuffer)} method directly.  </p>
+     *
+     * @param  bb  The byte buffer to be decoded
+     *
+     * @return  A char buffer containing the decoded characters
+     */
+    public final CharBuffer decode(ByteBuffer bb) {
+        try {
+            return ThreadLocalCoders.decoderFor(this)
+                .onMalformedInput(CodingErrorAction.REPLACE)
+                .onUnmappableCharacter(CodingErrorAction.REPLACE)
+                .decode(bb);
+        } catch (CharacterCodingException x) {
+            throw new Error(x);         // Can't happen
+        }
+    }
+
+    /**
+     * Convenience method that encodes Unicode characters into bytes in this
+     * charset.
+     *
+     * <p> An invocation of this method upon a charset <tt>cs</tt> returns the
+     * same result as the expression
+     *
+     * <pre>
+     *     cs.newEncoder()
+     *       .onMalformedInput(CodingErrorAction.REPLACE)
+     *       .onUnmappableCharacter(CodingErrorAction.REPLACE)
+     *       .encode(bb); </pre>
+     *
+     * except that it is potentially more efficient because it can cache
+     * encoders between successive invocations.
+     *
+     * <p> This method always replaces malformed-input and unmappable-character
+     * sequences with this charset's default replacement string.  In order to
+     * detect such sequences, use the {@link
+     * CharsetEncoder#encode(java.nio.CharBuffer)} method directly.  </p>
+     *
+     * @param  cb  The char buffer to be encoded
+     *
+     * @return  A byte buffer containing the encoded characters
+     */
+    public final ByteBuffer encode(CharBuffer cb) {
+        try {
+            return ThreadLocalCoders.encoderFor(this)
+                .onMalformedInput(CodingErrorAction.REPLACE)
+                .onUnmappableCharacter(CodingErrorAction.REPLACE)
+                .encode(cb);
+        } catch (CharacterCodingException x) {
+            throw new Error(x);         // Can't happen
+        }
+    }
+
+    /**
+     * Convenience method that encodes a string into bytes in this charset.
+     *
+     * <p> An invocation of this method upon a charset <tt>cs</tt> returns the
+     * same result as the expression
+     *
+     * <pre>
+     *     cs.encode(CharBuffer.wrap(s)); </pre>
+     *
+     * @param  str  The string to be encoded
+     *
+     * @return  A byte buffer containing the encoded characters
+     */
+    public final ByteBuffer encode(String str) {
+        return encode(CharBuffer.wrap(str));
+    }
+
+    /**
+     * Compares this charset to another.
+     *
+     * <p> Charsets are ordered by their canonical names, without regard to
+     * case. </p>
+     *
+     * @param  that
+     *         The charset to which this charset is to be compared
+     *
+     * @return A negative integer, zero, or a positive integer as this charset
+     *         is less than, equal to, or greater than the specified charset
+     */
+    public final int compareTo(Charset that) {
+        return (name().compareToIgnoreCase(that.name()));
+    }
+
+    /**
+     * Computes a hashcode for this charset.
+     *
+     * @return  An integer hashcode
+     */
+    public final int hashCode() {
+        return name().hashCode();
+    }
+
+    /**
+     * Tells whether or not this object is equal to another.
+     *
+     * <p> Two charsets are equal if, and only if, they have the same canonical
+     * names.  A charset is never equal to any other type of object.  </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this charset is equal to the
+     *          given object
+     */
+    public final boolean equals(Object ob) {
+        if (!(ob instanceof Charset))
+            return false;
+        if (this == ob)
+            return true;
+        return name.equals(((Charset)ob).name());
+    }
+
+    /**
+     * Returns a string describing this charset.
+     *
+     * @return  A string describing this charset
+     */
+    public final String toString() {
+        return name();
+    }
+
+}
diff --git a/java/nio/charset/CharsetDecoder.annotated.java b/java/nio/charset/CharsetDecoder.annotated.java
new file mode 100644
index 0000000..ed0f378
--- /dev/null
+++ b/java/nio/charset/CharsetDecoder.annotated.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+
+package java.nio.charset;
+
+import java.nio.CharBuffer;
+import java.nio.ByteBuffer;
+import java.nio.Buffer;
+import java.nio.charset.CoderMalfunctionError;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class CharsetDecoder {
+
[email protected]
+protected CharsetDecoder(java.nio.charset.Charset cs, float averageCharsPerByte, float maxCharsPerByte) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.Charset charset() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String replacement() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetDecoder replaceWith(java.lang.String newReplacement) { throw new RuntimeException("Stub!"); }
+
+protected void implReplaceWith(java.lang.String newReplacement) { throw new RuntimeException("Stub!"); }
+
+public java.nio.charset.CodingErrorAction malformedInputAction() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetDecoder onMalformedInput(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+protected void implOnMalformedInput(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+public java.nio.charset.CodingErrorAction unmappableCharacterAction() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetDecoder onUnmappableCharacter(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+protected void implOnUnmappableCharacter(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+public final float averageCharsPerByte() { throw new RuntimeException("Stub!"); }
+
+public final float maxCharsPerByte() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CoderResult decode(java.nio.ByteBuffer in, java.nio.CharBuffer out, boolean endOfInput) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CoderResult flush(java.nio.CharBuffer out) { throw new RuntimeException("Stub!"); }
+
+protected java.nio.charset.CoderResult implFlush(java.nio.CharBuffer out) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetDecoder reset() { throw new RuntimeException("Stub!"); }
+
+protected void implReset() { throw new RuntimeException("Stub!"); }
+
+protected abstract java.nio.charset.CoderResult decodeLoop(java.nio.ByteBuffer in, java.nio.CharBuffer out);
+
+public final java.nio.CharBuffer decode(java.nio.ByteBuffer in) throws java.nio.charset.CharacterCodingException { throw new RuntimeException("Stub!"); }
+
+public boolean isAutoDetecting() { throw new RuntimeException("Stub!"); }
+
+public boolean isCharsetDetected() { throw new RuntimeException("Stub!"); }
+
+public java.nio.charset.Charset detectedCharset() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/nio/charset/CharsetDecoder.java b/java/nio/charset/CharsetDecoder.java
new file mode 100644
index 0000000..34065ee
--- /dev/null
+++ b/java/nio/charset/CharsetDecoder.java
@@ -0,0 +1,998 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.charset;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.lang.ref.WeakReference;
+import java.nio.charset.CoderMalfunctionError;                  // javadoc
+import java.util.Arrays;
+
+
+/**
+ * An engine that can transform a sequence of bytes in a specific charset into a sequence of
+ * sixteen-bit Unicode characters.
+ *
+ * <a name="steps"></a>
+ *
+ * <p> The input byte sequence is provided in a byte buffer or a series
+ * of such buffers.  The output character sequence is written to a character buffer
+ * or a series of such buffers.  A decoder should always be used by making
+ * the following sequence of method invocations, hereinafter referred to as a
+ * <i>decoding operation</i>:
+ *
+ * <ol>
+ *
+ *   <li><p> Reset the decoder via the {@link #reset reset} method, unless it
+ *   has not been used before; </p></li>
+ *
+ *   <li><p> Invoke the {@link #decode decode} method zero or more times, as
+ *   long as additional input may be available, passing <tt>false</tt> for the
+ *   <tt>endOfInput</tt> argument and filling the input buffer and flushing the
+ *   output buffer between invocations; </p></li>
+ *
+ *   <li><p> Invoke the {@link #decode decode} method one final time, passing
+ *   <tt>true</tt> for the <tt>endOfInput</tt> argument; and then </p></li>
+ *
+ *   <li><p> Invoke the {@link #flush flush} method so that the decoder can
+ *   flush any internal state to the output buffer. </p></li>
+ *
+ * </ol>
+ *
+ * Each invocation of the {@link #decode decode} method will decode as many
+ * bytes as possible from the input buffer, writing the resulting characters
+ * to the output buffer.  The {@link #decode decode} method returns when more
+ * input is required, when there is not enough room in the output buffer, or
+ * when a decoding error has occurred.  In each case a {@link CoderResult}
+ * object is returned to describe the reason for termination.  An invoker can
+ * examine this object and fill the input buffer, flush the output buffer, or
+ * attempt to recover from a decoding error, as appropriate, and try again.
+ *
+ * <a name="ce"></a>
+ *
+ * <p> There are two general types of decoding errors.  If the input byte
+ * sequence is not legal for this charset then the input is considered <i>malformed</i>.  If
+ * the input byte sequence is legal but cannot be mapped to a valid
+ * Unicode character then an <i>unmappable character</i> has been encountered.
+ *
+ * <a name="cae"></a>
+ *
+ * <p> How a decoding error is handled depends upon the action requested for
+ * that type of error, which is described by an instance of the {@link
+ * CodingErrorAction} class.  The possible error actions are to {@linkplain
+ * CodingErrorAction#IGNORE ignore} the erroneous input, {@linkplain
+ * CodingErrorAction#REPORT report} the error to the invoker via
+ * the returned {@link CoderResult} object, or {@linkplain CodingErrorAction#REPLACE
+ * replace} the erroneous input with the current value of the
+ * replacement string.  The replacement
+ *
+
+
+
+
+
+ * has the initial value <tt>"&#92;uFFFD"</tt>;
+
+ *
+ * its value may be changed via the {@link #replaceWith(java.lang.String)
+ * replaceWith} method.
+ *
+ * <p> The default action for malformed-input and unmappable-character errors
+ * is to {@linkplain CodingErrorAction#REPORT report} them.  The
+ * malformed-input error action may be changed via the {@link
+ * #onMalformedInput(CodingErrorAction) onMalformedInput} method; the
+ * unmappable-character action may be changed via the {@link
+ * #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter} method.
+ *
+ * <p> This class is designed to handle many of the details of the decoding
+ * process, including the implementation of error actions.  A decoder for a
+ * specific charset, which is a concrete subclass of this class, need only
+ * implement the abstract {@link #decodeLoop decodeLoop} method, which
+ * encapsulates the basic decoding loop.  A subclass that maintains internal
+ * state should, additionally, override the {@link #implFlush implFlush} and
+ * {@link #implReset implReset} methods.
+ *
+ * <p> Instances of this class are not safe for use by multiple concurrent
+ * threads.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see ByteBuffer
+ * @see CharBuffer
+ * @see Charset
+ * @see CharsetEncoder
+ */
+
+public abstract class CharsetDecoder {
+
+    private final Charset charset;
+    private final float averageCharsPerByte;
+    private final float maxCharsPerByte;
+
+    private String replacement;
+    private CodingErrorAction malformedInputAction
+        = CodingErrorAction.REPORT;
+    private CodingErrorAction unmappableCharacterAction
+        = CodingErrorAction.REPORT;
+
+    // Internal states
+    //
+    private static final int ST_RESET   = 0;
+    private static final int ST_CODING  = 1;
+    private static final int ST_END     = 2;
+    private static final int ST_FLUSHED = 3;
+
+    private int state = ST_RESET;
+
+    private static String stateNames[]
+        = { "RESET", "CODING", "CODING_END", "FLUSHED" };
+
+
+    /**
+     * Initializes a new decoder.  The new decoder will have the given
+     * chars-per-byte and replacement values.
+     *
+     * @param  cs
+     *         The charset that created this decoder
+     *
+     * @param  averageCharsPerByte
+     *         A positive float value indicating the expected number of
+     *         characters that will be produced for each input byte
+     *
+     * @param  maxCharsPerByte
+     *         A positive float value indicating the maximum number of
+     *         characters that will be produced for each input byte
+     *
+     * @param  replacement
+     *         The initial replacement; must not be <tt>null</tt>, must have
+     *         non-zero length, must not be longer than maxCharsPerByte,
+     *         and must be {@linkplain #isLegalReplacement legal}
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameters do not hold
+     */
+    private
+    CharsetDecoder(Charset cs,
+                   float averageCharsPerByte,
+                   float maxCharsPerByte,
+                   String replacement)
+    {
+        this.charset = cs;
+        if (averageCharsPerByte <= 0.0f)
+            throw new IllegalArgumentException("Non-positive "
+                                               + "averageCharsPerByte");
+        if (maxCharsPerByte <= 0.0f)
+            throw new IllegalArgumentException("Non-positive "
+                                               + "maxCharsPerByte");
+        if (!Charset.atBugLevel("1.4")) {
+            if (averageCharsPerByte > maxCharsPerByte)
+                throw new IllegalArgumentException("averageCharsPerByte"
+                                                   + " exceeds "
+                                                   + "maxCharsPerByte");
+        }
+        this.replacement = replacement;
+        this.averageCharsPerByte = averageCharsPerByte;
+        this.maxCharsPerByte = maxCharsPerByte;
+        // Android-removed
+        // replaceWith(replacement);
+    }
+
+    /**
+     * Initializes a new decoder.  The new decoder will have the given
+     * chars-per-byte values and its replacement will be the
+     * string <tt>"&#92;uFFFD"</tt>.
+     *
+     * @param  cs
+     *         The charset that created this decoder
+     *
+     * @param  averageCharsPerByte
+     *         A positive float value indicating the expected number of
+     *         characters that will be produced for each input byte
+     *
+     * @param  maxCharsPerByte
+     *         A positive float value indicating the maximum number of
+     *         characters that will be produced for each input byte
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameters do not hold
+     */
+    protected CharsetDecoder(Charset cs,
+                             float averageCharsPerByte,
+                             float maxCharsPerByte)
+    {
+        this(cs,
+             averageCharsPerByte, maxCharsPerByte,
+             "\uFFFD");
+    }
+
+    /**
+     * Returns the charset that created this decoder.
+     *
+     * @return  This decoder's charset
+     */
+    public final Charset charset() {
+        return charset;
+    }
+
+    /**
+     * Returns this decoder's replacement value.
+     *
+     * @return  This decoder's current replacement,
+     *          which is never <tt>null</tt> and is never empty
+     */
+    public final String replacement() {
+
+        return replacement;
+
+
+
+
+    }
+
+    /**
+     * Changes this decoder's replacement value.
+     *
+     * <p> This method invokes the {@link #implReplaceWith implReplaceWith}
+     * method, passing the new replacement, after checking that the new
+     * replacement is acceptable.  </p>
+     *
+     * @param  newReplacement  The replacement value
+     *
+
+     *         The new replacement; must not be <tt>null</tt>
+     *         and must have non-zero length
+
+
+
+
+
+
+
+     *
+     * @return  This decoder
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameter do not hold
+     */
+    public final CharsetDecoder replaceWith(String newReplacement) {
+        if (newReplacement == null)
+            throw new IllegalArgumentException("Null replacement");
+        int len = newReplacement.length();
+        if (len == 0)
+            throw new IllegalArgumentException("Empty replacement");
+        if (len > maxCharsPerByte)
+            throw new IllegalArgumentException("Replacement too long");
+
+        this.replacement = newReplacement;
+
+
+
+
+
+
+        implReplaceWith(this.replacement);
+        return this;
+    }
+
+    /**
+     * Reports a change to this decoder's replacement value.
+     *
+     * <p> The default implementation of this method does nothing.  This method
+     * should be overridden by decoders that require notification of changes to
+     * the replacement.  </p>
+     *
+     * @param  newReplacement    The replacement value
+     */
+    protected void implReplaceWith(String newReplacement) {
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    /**
+     * Returns this decoder's current action for malformed-input errors.
+     *
+     * @return The current malformed-input action, which is never <tt>null</tt>
+     */
+    public CodingErrorAction malformedInputAction() {
+        return malformedInputAction;
+    }
+
+    /**
+     * Changes this decoder's action for malformed-input errors.
+     *
+     * <p> This method invokes the {@link #implOnMalformedInput
+     * implOnMalformedInput} method, passing the new action.  </p>
+     *
+     * @param  newAction  The new action; must not be <tt>null</tt>
+     *
+     * @return  This decoder
+     *
+     * @throws IllegalArgumentException
+     *         If the precondition on the parameter does not hold
+     */
+    public final CharsetDecoder onMalformedInput(CodingErrorAction newAction) {
+        if (newAction == null)
+            throw new IllegalArgumentException("Null action");
+        malformedInputAction = newAction;
+        implOnMalformedInput(newAction);
+        return this;
+    }
+
+    /**
+     * Reports a change to this decoder's malformed-input action.
+     *
+     * <p> The default implementation of this method does nothing.  This method
+     * should be overridden by decoders that require notification of changes to
+     * the malformed-input action.  </p>
+     *
+     * @param  newAction  The new action
+     */
+    protected void implOnMalformedInput(CodingErrorAction newAction) { }
+
+    /**
+     * Returns this decoder's current action for unmappable-character errors.
+     *
+     * @return The current unmappable-character action, which is never
+     *         <tt>null</tt>
+     */
+    public CodingErrorAction unmappableCharacterAction() {
+        return unmappableCharacterAction;
+    }
+
+    /**
+     * Changes this decoder's action for unmappable-character errors.
+     *
+     * <p> This method invokes the {@link #implOnUnmappableCharacter
+     * implOnUnmappableCharacter} method, passing the new action.  </p>
+     *
+     * @param  newAction  The new action; must not be <tt>null</tt>
+     *
+     * @return  This decoder
+     *
+     * @throws IllegalArgumentException
+     *         If the precondition on the parameter does not hold
+     */
+    public final CharsetDecoder onUnmappableCharacter(CodingErrorAction
+                                                      newAction)
+    {
+        if (newAction == null)
+            throw new IllegalArgumentException("Null action");
+        unmappableCharacterAction = newAction;
+        implOnUnmappableCharacter(newAction);
+        return this;
+    }
+
+    /**
+     * Reports a change to this decoder's unmappable-character action.
+     *
+     * <p> The default implementation of this method does nothing.  This method
+     * should be overridden by decoders that require notification of changes to
+     * the unmappable-character action.  </p>
+     *
+     * @param  newAction  The new action
+     */
+    protected void implOnUnmappableCharacter(CodingErrorAction newAction) { }
+
+    /**
+     * Returns the average number of characters that will be produced for each
+     * byte of input.  This heuristic value may be used to estimate the size
+     * of the output buffer required for a given input sequence.
+     *
+     * @return  The average number of characters produced
+     *          per byte of input
+     */
+    public final float averageCharsPerByte() {
+        return averageCharsPerByte;
+    }
+
+    /**
+     * Returns the maximum number of characters that will be produced for each
+     * byte of input.  This value may be used to compute the worst-case size
+     * of the output buffer required for a given input sequence.
+     *
+     * @return  The maximum number of characters that will be produced per
+     *          byte of input
+     */
+    public final float maxCharsPerByte() {
+        return maxCharsPerByte;
+    }
+
+    /**
+     * Decodes as many bytes as possible from the given input buffer,
+     * writing the results to the given output buffer.
+     *
+     * <p> The buffers are read from, and written to, starting at their current
+     * positions.  At most {@link Buffer#remaining in.remaining()} bytes
+     * will be read and at most {@link Buffer#remaining out.remaining()}
+     * characters will be written.  The buffers' positions will be advanced to
+     * reflect the bytes read and the characters written, but their marks and
+     * limits will not be modified.
+     *
+     * <p> In addition to reading bytes from the input buffer and writing
+     * characters to the output buffer, this method returns a {@link CoderResult}
+     * object to describe its reason for termination:
+     *
+     * <ul>
+     *
+     *   <li><p> {@link CoderResult#UNDERFLOW} indicates that as much of the
+     *   input buffer as possible has been decoded.  If there is no further
+     *   input then the invoker can proceed to the next step of the
+     *   <a href="#steps">decoding operation</a>.  Otherwise this method
+     *   should be invoked again with further input.  </p></li>
+     *
+     *   <li><p> {@link CoderResult#OVERFLOW} indicates that there is
+     *   insufficient space in the output buffer to decode any more bytes.
+     *   This method should be invoked again with an output buffer that has
+     *   more {@linkplain Buffer#remaining remaining} characters. This is
+     *   typically done by draining any decoded characters from the output
+     *   buffer.  </p></li>
+     *
+     *   <li><p> A {@linkplain CoderResult#malformedForLength
+     *   malformed-input} result indicates that a malformed-input
+     *   error has been detected.  The malformed bytes begin at the input
+     *   buffer's (possibly incremented) position; the number of malformed
+     *   bytes may be determined by invoking the result object's {@link
+     *   CoderResult#length() length} method.  This case applies only if the
+     *   {@linkplain #onMalformedInput malformed action} of this decoder
+     *   is {@link CodingErrorAction#REPORT}; otherwise the malformed input
+     *   will be ignored or replaced, as requested.  </p></li>
+     *
+     *   <li><p> An {@linkplain CoderResult#unmappableForLength
+     *   unmappable-character} result indicates that an
+     *   unmappable-character error has been detected.  The bytes that
+     *   decode the unmappable character begin at the input buffer's (possibly
+     *   incremented) position; the number of such bytes may be determined
+     *   by invoking the result object's {@link CoderResult#length() length}
+     *   method.  This case applies only if the {@linkplain #onUnmappableCharacter
+     *   unmappable action} of this decoder is {@link
+     *   CodingErrorAction#REPORT}; otherwise the unmappable character will be
+     *   ignored or replaced, as requested.  </p></li>
+     *
+     * </ul>
+     *
+     * In any case, if this method is to be reinvoked in the same decoding
+     * operation then care should be taken to preserve any bytes remaining
+     * in the input buffer so that they are available to the next invocation.
+     *
+     * <p> The <tt>endOfInput</tt> parameter advises this method as to whether
+     * the invoker can provide further input beyond that contained in the given
+     * input buffer.  If there is a possibility of providing additional input
+     * then the invoker should pass <tt>false</tt> for this parameter; if there
+     * is no possibility of providing further input then the invoker should
+     * pass <tt>true</tt>.  It is not erroneous, and in fact it is quite
+     * common, to pass <tt>false</tt> in one invocation and later discover that
+     * no further input was actually available.  It is critical, however, that
+     * the final invocation of this method in a sequence of invocations always
+     * pass <tt>true</tt> so that any remaining undecoded input will be treated
+     * as being malformed.
+     *
+     * <p> This method works by invoking the {@link #decodeLoop decodeLoop}
+     * method, interpreting its results, handling error conditions, and
+     * reinvoking it as necessary.  </p>
+     *
+     *
+     * @param  in
+     *         The input byte buffer
+     *
+     * @param  out
+     *         The output character buffer
+     *
+     * @param  endOfInput
+     *         <tt>true</tt> if, and only if, the invoker can provide no
+     *         additional input bytes beyond those in the given buffer
+     *
+     * @return  A coder-result object describing the reason for termination
+     *
+     * @throws  IllegalStateException
+     *          If a decoding operation is already in progress and the previous
+     *          step was an invocation neither of the {@link #reset reset}
+     *          method, nor of this method with a value of <tt>false</tt> for
+     *          the <tt>endOfInput</tt> parameter, nor of this method with a
+     *          value of <tt>true</tt> for the <tt>endOfInput</tt> parameter
+     *          but a return value indicating an incomplete decoding operation
+     *
+     * @throws  CoderMalfunctionError
+     *          If an invocation of the decodeLoop method threw
+     *          an unexpected exception
+     */
+    public final CoderResult decode(ByteBuffer in, CharBuffer out,
+                                    boolean endOfInput)
+    {
+        int newState = endOfInput ? ST_END : ST_CODING;
+        if ((state != ST_RESET) && (state != ST_CODING)
+            && !(endOfInput && (state == ST_END)))
+            throwIllegalStateException(state, newState);
+        state = newState;
+
+        for (;;) {
+
+            CoderResult cr;
+            try {
+                cr = decodeLoop(in, out);
+            } catch (BufferUnderflowException x) {
+                throw new CoderMalfunctionError(x);
+            } catch (BufferOverflowException x) {
+                throw new CoderMalfunctionError(x);
+            }
+
+            if (cr.isOverflow())
+                return cr;
+
+            if (cr.isUnderflow()) {
+                if (endOfInput && in.hasRemaining()) {
+                    cr = CoderResult.malformedForLength(in.remaining());
+                    // Fall through to malformed-input case
+                } else {
+                    return cr;
+                }
+            }
+
+            CodingErrorAction action = null;
+            if (cr.isMalformed())
+                action = malformedInputAction;
+            else if (cr.isUnmappable())
+                action = unmappableCharacterAction;
+            else
+                assert false : cr.toString();
+
+            if (action == CodingErrorAction.REPORT)
+                return cr;
+
+            if (action == CodingErrorAction.REPLACE) {
+                if (out.remaining() < replacement.length())
+                    return CoderResult.OVERFLOW;
+                out.put(replacement);
+            }
+
+            if ((action == CodingErrorAction.IGNORE)
+                || (action == CodingErrorAction.REPLACE)) {
+                // Skip erroneous input either way
+                in.position(in.position() + cr.length());
+                continue;
+            }
+
+            assert false;
+        }
+
+    }
+
+    /**
+     * Flushes this decoder.
+     *
+     * <p> Some decoders maintain internal state and may need to write some
+     * final characters to the output buffer once the overall input sequence has
+     * been read.
+     *
+     * <p> Any additional output is written to the output buffer beginning at
+     * its current position.  At most {@link Buffer#remaining out.remaining()}
+     * characters will be written.  The buffer's position will be advanced
+     * appropriately, but its mark and limit will not be modified.
+     *
+     * <p> If this method completes successfully then it returns {@link
+     * CoderResult#UNDERFLOW}.  If there is insufficient room in the output
+     * buffer then it returns {@link CoderResult#OVERFLOW}.  If this happens
+     * then this method must be invoked again, with an output buffer that has
+     * more room, in order to complete the current <a href="#steps">decoding
+     * operation</a>.
+     *
+     * <p> If this decoder has already been flushed then invoking this method
+     * has no effect.
+     *
+     * <p> This method invokes the {@link #implFlush implFlush} method to
+     * perform the actual flushing operation.  </p>
+     *
+     * @param  out
+     *         The output character buffer
+     *
+     * @return  A coder-result object, either {@link CoderResult#UNDERFLOW} or
+     *          {@link CoderResult#OVERFLOW}
+     *
+     * @throws  IllegalStateException
+     *          If the previous step of the current decoding operation was an
+     *          invocation neither of the {@link #flush flush} method nor of
+     *          the three-argument {@link
+     *          #decode(ByteBuffer,CharBuffer,boolean) decode} method
+     *          with a value of <tt>true</tt> for the <tt>endOfInput</tt>
+     *          parameter
+     */
+    public final CoderResult flush(CharBuffer out) {
+        if (state == ST_END) {
+            CoderResult cr = implFlush(out);
+            if (cr.isUnderflow())
+                state = ST_FLUSHED;
+            return cr;
+        }
+
+        if (state != ST_FLUSHED)
+            throwIllegalStateException(state, ST_FLUSHED);
+
+        return CoderResult.UNDERFLOW; // Already flushed
+    }
+
+    /**
+     * Flushes this decoder.
+     *
+     * <p> The default implementation of this method does nothing, and always
+     * returns {@link CoderResult#UNDERFLOW}.  This method should be overridden
+     * by decoders that may need to write final characters to the output buffer
+     * once the entire input sequence has been read. </p>
+     *
+     * @param  out
+     *         The output character buffer
+     *
+     * @return  A coder-result object, either {@link CoderResult#UNDERFLOW} or
+     *          {@link CoderResult#OVERFLOW}
+     */
+    protected CoderResult implFlush(CharBuffer out) {
+        return CoderResult.UNDERFLOW;
+    }
+
+    /**
+     * Resets this decoder, clearing any internal state.
+     *
+     * <p> This method resets charset-independent state and also invokes the
+     * {@link #implReset() implReset} method in order to perform any
+     * charset-specific reset actions.  </p>
+     *
+     * @return  This decoder
+     *
+     */
+    public final CharsetDecoder reset() {
+        implReset();
+        state = ST_RESET;
+        return this;
+    }
+
+    /**
+     * Resets this decoder, clearing any charset-specific internal state.
+     *
+     * <p> The default implementation of this method does nothing.  This method
+     * should be overridden by decoders that maintain internal state.  </p>
+     */
+    protected void implReset() { }
+
+    /**
+     * Decodes one or more bytes into one or more characters.
+     *
+     * <p> This method encapsulates the basic decoding loop, decoding as many
+     * bytes as possible until it either runs out of input, runs out of room
+     * in the output buffer, or encounters a decoding error.  This method is
+     * invoked by the {@link #decode decode} method, which handles result
+     * interpretation and error recovery.
+     *
+     * <p> The buffers are read from, and written to, starting at their current
+     * positions.  At most {@link Buffer#remaining in.remaining()} bytes
+     * will be read, and at most {@link Buffer#remaining out.remaining()}
+     * characters will be written.  The buffers' positions will be advanced to
+     * reflect the bytes read and the characters written, but their marks and
+     * limits will not be modified.
+     *
+     * <p> This method returns a {@link CoderResult} object to describe its
+     * reason for termination, in the same manner as the {@link #decode decode}
+     * method.  Most implementations of this method will handle decoding errors
+     * by returning an appropriate result object for interpretation by the
+     * {@link #decode decode} method.  An optimized implementation may instead
+     * examine the relevant error action and implement that action itself.
+     *
+     * <p> An implementation of this method may perform arbitrary lookahead by
+     * returning {@link CoderResult#UNDERFLOW} until it receives sufficient
+     * input.  </p>
+     *
+     * @param  in
+     *         The input byte buffer
+     *
+     * @param  out
+     *         The output character buffer
+     *
+     * @return  A coder-result object describing the reason for termination
+     */
+    protected abstract CoderResult decodeLoop(ByteBuffer in,
+                                              CharBuffer out);
+
+    /**
+     * Convenience method that decodes the remaining content of a single input
+     * byte buffer into a newly-allocated character buffer.
+     *
+     * <p> This method implements an entire <a href="#steps">decoding
+     * operation</a>; that is, it resets this decoder, then it decodes the
+     * bytes in the given byte buffer, and finally it flushes this
+     * decoder.  This method should therefore not be invoked if a decoding
+     * operation is already in progress.  </p>
+     *
+     * @param  in
+     *         The input byte buffer
+     *
+     * @return A newly-allocated character buffer containing the result of the
+     *         decoding operation.  The buffer's position will be zero and its
+     *         limit will follow the last character written.
+     *
+     * @throws  IllegalStateException
+     *          If a decoding operation is already in progress
+     *
+     * @throws  MalformedInputException
+     *          If the byte sequence starting at the input buffer's current
+     *          position is not legal for this charset and the current malformed-input action
+     *          is {@link CodingErrorAction#REPORT}
+     *
+     * @throws  UnmappableCharacterException
+     *          If the byte sequence starting at the input buffer's current
+     *          position cannot be mapped to an equivalent character sequence and
+     *          the current unmappable-character action is {@link
+     *          CodingErrorAction#REPORT}
+     */
+    public final CharBuffer decode(ByteBuffer in)
+        throws CharacterCodingException
+    {
+        int n = (int)(in.remaining() * averageCharsPerByte());
+        CharBuffer out = CharBuffer.allocate(n);
+
+        if ((n == 0) && (in.remaining() == 0))
+            return out;
+        reset();
+        for (;;) {
+            CoderResult cr = in.hasRemaining() ?
+                decode(in, out, true) : CoderResult.UNDERFLOW;
+            if (cr.isUnderflow())
+                cr = flush(out);
+
+            if (cr.isUnderflow())
+                break;
+            if (cr.isOverflow()) {
+                n = 2*n + 1;    // Ensure progress; n might be 0!
+                CharBuffer o = CharBuffer.allocate(n);
+                out.flip();
+                o.put(out);
+                out = o;
+                continue;
+            }
+            cr.throwException();
+        }
+        out.flip();
+        return out;
+    }
+
+
+
+    /**
+     * Tells whether or not this decoder implements an auto-detecting charset.
+     *
+     * <p> The default implementation of this method always returns
+     * <tt>false</tt>; it should be overridden by auto-detecting decoders to
+     * return <tt>true</tt>.  </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this decoder implements an
+     *          auto-detecting charset
+     */
+    public boolean isAutoDetecting() {
+        return false;
+    }
+
+    /**
+     * Tells whether or not this decoder has yet detected a
+     * charset&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> If this decoder implements an auto-detecting charset then at a
+     * single point during a decoding operation this method may start returning
+     * <tt>true</tt> to indicate that a specific charset has been detected in
+     * the input byte sequence.  Once this occurs, the {@link #detectedCharset
+     * detectedCharset} method may be invoked to retrieve the detected charset.
+     *
+     * <p> That this method returns <tt>false</tt> does not imply that no bytes
+     * have yet been decoded.  Some auto-detecting decoders are capable of
+     * decoding some, or even all, of an input byte sequence without fixing on
+     * a particular charset.
+     *
+     * <p> The default implementation of this method always throws an {@link
+     * UnsupportedOperationException}; it should be overridden by
+     * auto-detecting decoders to return <tt>true</tt> once the input charset
+     * has been determined.  </p>
+     *
+     * @return  <tt>true</tt> if, and only if, this decoder has detected a
+     *          specific charset
+     *
+     * @throws  UnsupportedOperationException
+     *          If this decoder does not implement an auto-detecting charset
+     */
+    public boolean isCharsetDetected() {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Retrieves the charset that was detected by this
+     * decoder&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * <p> If this decoder implements an auto-detecting charset then this
+     * method returns the actual charset once it has been detected.  After that
+     * point, this method returns the same value for the duration of the
+     * current decoding operation.  If not enough input bytes have yet been
+     * read to determine the actual charset then this method throws an {@link
+     * IllegalStateException}.
+     *
+     * <p> The default implementation of this method always throws an {@link
+     * UnsupportedOperationException}; it should be overridden by
+     * auto-detecting decoders to return the appropriate value.  </p>
+     *
+     * @return  The charset detected by this auto-detecting decoder,
+     *          or <tt>null</tt> if the charset has not yet been determined
+     *
+     * @throws  IllegalStateException
+     *          If insufficient bytes have been read to determine a charset
+     *
+     * @throws  UnsupportedOperationException
+     *          If this decoder does not implement an auto-detecting charset
+     */
+    public Charset detectedCharset() {
+        throw new UnsupportedOperationException();
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    private void throwIllegalStateException(int from, int to) {
+        throw new IllegalStateException("Current state = " + stateNames[from]
+                                        + ", new state = " + stateNames[to]);
+    }
+
+}
diff --git a/java/nio/charset/CharsetEncoder.annotated.java b/java/nio/charset/CharsetEncoder.annotated.java
new file mode 100644
index 0000000..ceb323e
--- /dev/null
+++ b/java/nio/charset/CharsetEncoder.annotated.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+
+package java.nio.charset;
+
+import java.nio.CharBuffer;
+import java.nio.ByteBuffer;
+import java.nio.Buffer;
+import java.nio.charset.CoderMalfunctionError;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class CharsetEncoder {
+
+protected CharsetEncoder(java.nio.charset.Charset cs, float averageBytesPerChar, float maxBytesPerChar, byte[] replacement) { throw new RuntimeException("Stub!"); }
+
[email protected]
+protected CharsetEncoder(java.nio.charset.Charset cs, float averageBytesPerChar, float maxBytesPerChar, byte[] replacement, boolean trusted) { throw new RuntimeException("Stub!"); }
+
+protected CharsetEncoder(java.nio.charset.Charset cs, float averageBytesPerChar, float maxBytesPerChar) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.Charset charset() { throw new RuntimeException("Stub!"); }
+
+public final byte[] replacement() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetEncoder replaceWith(byte[] newReplacement) { throw new RuntimeException("Stub!"); }
+
+protected void implReplaceWith(byte[] newReplacement) { throw new RuntimeException("Stub!"); }
+
+public boolean isLegalReplacement(byte[] repl) { throw new RuntimeException("Stub!"); }
+
+public java.nio.charset.CodingErrorAction malformedInputAction() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetEncoder onMalformedInput(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+protected void implOnMalformedInput(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+public java.nio.charset.CodingErrorAction unmappableCharacterAction() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetEncoder onUnmappableCharacter(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+protected void implOnUnmappableCharacter(java.nio.charset.CodingErrorAction newAction) { throw new RuntimeException("Stub!"); }
+
+public final float averageBytesPerChar() { throw new RuntimeException("Stub!"); }
+
+public final float maxBytesPerChar() { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CoderResult encode(java.nio.CharBuffer in, java.nio.ByteBuffer out, boolean endOfInput) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CoderResult flush(java.nio.ByteBuffer out) { throw new RuntimeException("Stub!"); }
+
+protected java.nio.charset.CoderResult implFlush(java.nio.ByteBuffer out) { throw new RuntimeException("Stub!"); }
+
+public final java.nio.charset.CharsetEncoder reset() { throw new RuntimeException("Stub!"); }
+
+protected void implReset() { throw new RuntimeException("Stub!"); }
+
+protected abstract java.nio.charset.CoderResult encodeLoop(java.nio.CharBuffer in, java.nio.ByteBuffer out);
+
+public final java.nio.ByteBuffer encode(java.nio.CharBuffer in) throws java.nio.charset.CharacterCodingException { throw new RuntimeException("Stub!"); }
+
+public boolean canEncode(char c) { throw new RuntimeException("Stub!"); }
+
+public boolean canEncode(java.lang.CharSequence cs) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/nio/charset/CharsetEncoder.java b/java/nio/charset/CharsetEncoder.java
new file mode 100644
index 0000000..98b4dea
--- /dev/null
+++ b/java/nio/charset/CharsetEncoder.java
@@ -0,0 +1,1026 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.charset;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.BufferOverflowException;
+import java.nio.BufferUnderflowException;
+import java.lang.ref.WeakReference;
+import java.nio.charset.CoderMalfunctionError;                  // javadoc
+import java.util.Arrays;
+
+
+/**
+ * An engine that can transform a sequence of sixteen-bit Unicode characters into a sequence of
+ * bytes in a specific charset.
+ *
+ * <a name="steps"></a>
+ *
+ * <p> The input character sequence is provided in a character buffer or a series
+ * of such buffers.  The output byte sequence is written to a byte buffer
+ * or a series of such buffers.  An encoder should always be used by making
+ * the following sequence of method invocations, hereinafter referred to as an
+ * <i>encoding operation</i>:
+ *
+ * <ol>
+ *
+ *   <li><p> Reset the encoder via the {@link #reset reset} method, unless it
+ *   has not been used before; </p></li>
+ *
+ *   <li><p> Invoke the {@link #encode encode} method zero or more times, as
+ *   long as additional input may be available, passing <tt>false</tt> for the
+ *   <tt>endOfInput</tt> argument and filling the input buffer and flushing the
+ *   output buffer between invocations; </p></li>
+ *
+ *   <li><p> Invoke the {@link #encode encode} method one final time, passing
+ *   <tt>true</tt> for the <tt>endOfInput</tt> argument; and then </p></li>
+ *
+ *   <li><p> Invoke the {@link #flush flush} method so that the encoder can
+ *   flush any internal state to the output buffer. </p></li>
+ *
+ * </ol>
+ *
+ * Each invocation of the {@link #encode encode} method will encode as many
+ * characters as possible from the input buffer, writing the resulting bytes
+ * to the output buffer.  The {@link #encode encode} method returns when more
+ * input is required, when there is not enough room in the output buffer, or
+ * when an encoding error has occurred.  In each case a {@link CoderResult}
+ * object is returned to describe the reason for termination.  An invoker can
+ * examine this object and fill the input buffer, flush the output buffer, or
+ * attempt to recover from an encoding error, as appropriate, and try again.
+ *
+ * <a name="ce"></a>
+ *
+ * <p> There are two general types of encoding errors.  If the input character
+ * sequence is not a legal sixteen-bit Unicode sequence then the input is considered <i>malformed</i>.  If
+ * the input character sequence is legal but cannot be mapped to a valid
+ * byte sequence in the given charset then an <i>unmappable character</i> has been encountered.
+ *
+ * <a name="cae"></a>
+ *
+ * <p> How an encoding error is handled depends upon the action requested for
+ * that type of error, which is described by an instance of the {@link
+ * CodingErrorAction} class.  The possible error actions are to {@linkplain
+ * CodingErrorAction#IGNORE ignore} the erroneous input, {@linkplain
+ * CodingErrorAction#REPORT report} the error to the invoker via
+ * the returned {@link CoderResult} object, or {@linkplain CodingErrorAction#REPLACE
+ * replace} the erroneous input with the current value of the
+ * replacement byte array.  The replacement
+ *
+
+ * is initially set to the encoder's default replacement, which often
+ * (but not always) has the initial value&nbsp;<tt>{</tt>&nbsp;<tt>(byte)'?'</tt>&nbsp;<tt>}</tt>;
+
+
+
+
+ *
+ * its value may be changed via the {@link #replaceWith(byte[])
+ * replaceWith} method.
+ *
+ * <p> The default action for malformed-input and unmappable-character errors
+ * is to {@linkplain CodingErrorAction#REPORT report} them.  The
+ * malformed-input error action may be changed via the {@link
+ * #onMalformedInput(CodingErrorAction) onMalformedInput} method; the
+ * unmappable-character action may be changed via the {@link
+ * #onUnmappableCharacter(CodingErrorAction) onUnmappableCharacter} method.
+ *
+ * <p> This class is designed to handle many of the details of the encoding
+ * process, including the implementation of error actions.  An encoder for a
+ * specific charset, which is a concrete subclass of this class, need only
+ * implement the abstract {@link #encodeLoop encodeLoop} method, which
+ * encapsulates the basic encoding loop.  A subclass that maintains internal
+ * state should, additionally, override the {@link #implFlush implFlush} and
+ * {@link #implReset implReset} methods.
+ *
+ * <p> Instances of this class are not safe for use by multiple concurrent
+ * threads.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see ByteBuffer
+ * @see CharBuffer
+ * @see Charset
+ * @see CharsetDecoder
+ */
+
+public abstract class CharsetEncoder {
+
+    private final Charset charset;
+    private final float averageBytesPerChar;
+    private final float maxBytesPerChar;
+
+    private byte[] replacement;
+    private CodingErrorAction malformedInputAction
+        = CodingErrorAction.REPORT;
+    private CodingErrorAction unmappableCharacterAction
+        = CodingErrorAction.REPORT;
+
+    // Internal states
+    //
+    private static final int ST_RESET   = 0;
+    private static final int ST_CODING  = 1;
+    private static final int ST_END     = 2;
+    private static final int ST_FLUSHED = 3;
+
+    private int state = ST_RESET;
+
+    private static String stateNames[]
+        = { "RESET", "CODING", "CODING_END", "FLUSHED" };
+
+
+    /**
+     * Initializes a new encoder.  The new encoder will have the given
+     * bytes-per-char and replacement values.
+     *
+     * @param  cs
+     *         The charset that created this encoder
+     *
+     * @param  averageBytesPerChar
+     *         A positive float value indicating the expected number of
+     *         bytes that will be produced for each input character
+     *
+     * @param  maxBytesPerChar
+     *         A positive float value indicating the maximum number of
+     *         bytes that will be produced for each input character
+     *
+     * @param  replacement
+     *         The initial replacement; must not be <tt>null</tt>, must have
+     *         non-zero length, must not be longer than maxBytesPerChar,
+     *         and must be {@linkplain #isLegalReplacement legal}
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameters do not hold
+     */
+    protected
+    CharsetEncoder(Charset cs,
+                   float averageBytesPerChar,
+                   float maxBytesPerChar,
+                   byte[] replacement)
+    {
+        // BEGIN Android-added: A hidden constructor for the CharsetEncoderICU subclass.
+        this(cs, averageBytesPerChar, maxBytesPerChar, replacement, false);
+    }
+
+    /**
+     * This constructor is for subclasses to specify whether {@code replacement} can be used as it
+     * is ("trusted"). If it is trusted, {@link #replaceWith(byte[])} and
+     * {@link #implReplaceWith(byte[])} will not be called.
+     * @hide
+     */
+    protected CharsetEncoder(Charset cs, float averageBytesPerChar, float maxBytesPerChar, byte[] replacement,
+            boolean trusted)
+    {
+        // END Android-added: A hidden constructor for the CharsetEncoderICU subclass.
+        this.charset = cs;
+        if (averageBytesPerChar <= 0.0f)
+            throw new IllegalArgumentException("Non-positive "
+                                               + "averageBytesPerChar");
+        if (maxBytesPerChar <= 0.0f)
+            throw new IllegalArgumentException("Non-positive "
+                                               + "maxBytesPerChar");
+        if (!Charset.atBugLevel("1.4")) {
+            if (averageBytesPerChar > maxBytesPerChar)
+                throw new IllegalArgumentException("averageBytesPerChar"
+                                                   + " exceeds "
+                                                   + "maxBytesPerChar");
+        }
+        this.replacement = replacement;
+        this.averageBytesPerChar = averageBytesPerChar;
+        this.maxBytesPerChar = maxBytesPerChar;
+        // BEGIN Android-changed: Avoid calling replaceWith() for trusted subclasses.
+        // replaceWith(replacement);
+        if (!trusted) {
+            replaceWith(replacement);
+        }
+        // END Android-changed: Avoid calling replaceWith() for trusted subclasses.
+    }
+
+    /**
+     * Initializes a new encoder.  The new encoder will have the given
+     * bytes-per-char values and its replacement will be the
+     * byte array <tt>{</tt>&nbsp;<tt>(byte)'?'</tt>&nbsp;<tt>}</tt>.
+     *
+     * @param  cs
+     *         The charset that created this encoder
+     *
+     * @param  averageBytesPerChar
+     *         A positive float value indicating the expected number of
+     *         bytes that will be produced for each input character
+     *
+     * @param  maxBytesPerChar
+     *         A positive float value indicating the maximum number of
+     *         bytes that will be produced for each input character
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameters do not hold
+     */
+    protected CharsetEncoder(Charset cs,
+                             float averageBytesPerChar,
+                             float maxBytesPerChar)
+    {
+        this(cs,
+             averageBytesPerChar, maxBytesPerChar,
+             new byte[] { (byte)'?' });
+    }
+
+    /**
+     * Returns the charset that created this encoder.
+     *
+     * @return  This encoder's charset
+     */
+    public final Charset charset() {
+        return charset;
+    }
+
+    /**
+     * Returns this encoder's replacement value.
+     *
+     * @return  This encoder's current replacement,
+     *          which is never <tt>null</tt> and is never empty
+     */
+    public final byte[] replacement() {
+
+
+
+
+        return Arrays.copyOf(replacement, replacement.length);
+
+    }
+
+    /**
+     * Changes this encoder's replacement value.
+     *
+     * <p> This method invokes the {@link #implReplaceWith implReplaceWith}
+     * method, passing the new replacement, after checking that the new
+     * replacement is acceptable.  </p>
+     *
+     * @param  newReplacement  The replacement value
+     *
+
+
+
+
+
+     *         The new replacement; must not be <tt>null</tt>, must have
+     *         non-zero length, must not be longer than the value returned by
+     *         the {@link #maxBytesPerChar() maxBytesPerChar} method, and
+     *         must be {@link #isLegalReplacement legal}
+
+     *
+     * @return  This encoder
+     *
+     * @throws  IllegalArgumentException
+     *          If the preconditions on the parameter do not hold
+     */
+    public final CharsetEncoder replaceWith(byte[] newReplacement) {
+        if (newReplacement == null)
+            throw new IllegalArgumentException("Null replacement");
+        int len = newReplacement.length;
+        if (len == 0)
+            throw new IllegalArgumentException("Empty replacement");
+        if (len > maxBytesPerChar)
+            throw new IllegalArgumentException("Replacement too long");
+
+
+
+
+        if (!isLegalReplacement(newReplacement))
+            throw new IllegalArgumentException("Illegal replacement");
+        this.replacement = Arrays.copyOf(newReplacement, newReplacement.length);
+
+        implReplaceWith(this.replacement);
+        return this;
+    }
+
+    /**
+     * Reports a change to this encoder's replacement value.
+     *
+     * <p> The default implementation of this method does nothing.  This method
+     * should be overridden by encoders that require notification of changes to
+     * the replacement.  </p>
+     *
+     * @param  newReplacement    The replacement value
+     */
+    protected void implReplaceWith(byte[] newReplacement) {
+    }
+
+
+
+    private WeakReference<CharsetDecoder> cachedDecoder = null;
+
+    /**
+     * Tells whether or not the given byte array is a legal replacement value
+     * for this encoder.
+     *
+     * <p> A replacement is legal if, and only if, it is a legal sequence of
+     * bytes in this encoder's charset; that is, it must be possible to decode
+     * the replacement into one or more sixteen-bit Unicode characters.
+     *
+     * <p> The default implementation of this method is not very efficient; it
+     * should generally be overridden to improve performance.  </p>
+     *
+     * @param  repl  The byte array to be tested
+     *
+     * @return  <tt>true</tt> if, and only if, the given byte array
+     *          is a legal replacement value for this encoder
+     */
+    public boolean isLegalReplacement(byte[] repl) {
+        WeakReference<CharsetDecoder> wr = cachedDecoder;
+        CharsetDecoder dec = null;
+        if ((wr == null) || ((dec = wr.get()) == null)) {
+            dec = charset().newDecoder();
+            dec.onMalformedInput(CodingErrorAction.REPORT);
+            dec.onUnmappableCharacter(CodingErrorAction.REPORT);
+            cachedDecoder = new WeakReference<CharsetDecoder>(dec);
+        } else {
+            dec.reset();
+        }
+        ByteBuffer bb = ByteBuffer.wrap(repl);
+        CharBuffer cb = CharBuffer.allocate((int)(bb.remaining()
+                                                  * dec.maxCharsPerByte()));
+        CoderResult cr = dec.decode(bb, cb, true);
+        return !cr.isError();
+    }
+
+
+
+    /**
+     * Returns this encoder's current action for malformed-input errors.
+     *
+     * @return The current malformed-input action, which is never <tt>null</tt>
+     */
+    public CodingErrorAction malformedInputAction() {
+        return malformedInputAction;
+    }
+
+    /**
+     * Changes this encoder's action for malformed-input errors.
+     *
+     * <p> This method invokes the {@link #implOnMalformedInput
+     * implOnMalformedInput} method, passing the new action.  </p>
+     *
+     * @param  newAction  The new action; must not be <tt>null</tt>
+     *
+     * @return  This encoder
+     *
+     * @throws IllegalArgumentException
+     *         If the precondition on the parameter does not hold
+     */
+    public final CharsetEncoder onMalformedInput(CodingErrorAction newAction) {
+        if (newAction == null)
+            throw new IllegalArgumentException("Null action");
+        malformedInputAction = newAction;
+        implOnMalformedInput(newAction);
+        return this;
+    }
+
+    /**
+     * Reports a change to this encoder's malformed-input action.
+     *
+     * <p> The default implementation of this method does nothing.  This method
+     * should be overridden by encoders that require notification of changes to
+     * the malformed-input action.  </p>
+     *
+     * @param  newAction  The new action
+     */
+    protected void implOnMalformedInput(CodingErrorAction newAction) { }
+
+    /**
+     * Returns this encoder's current action for unmappable-character errors.
+     *
+     * @return The current unmappable-character action, which is never
+     *         <tt>null</tt>
+     */
+    public CodingErrorAction unmappableCharacterAction() {
+        return unmappableCharacterAction;
+    }
+
+    /**
+     * Changes this encoder's action for unmappable-character errors.
+     *
+     * <p> This method invokes the {@link #implOnUnmappableCharacter
+     * implOnUnmappableCharacter} method, passing the new action.  </p>
+     *
+     * @param  newAction  The new action; must not be <tt>null</tt>
+     *
+     * @return  This encoder
+     *
+     * @throws IllegalArgumentException
+     *         If the precondition on the parameter does not hold
+     */
+    public final CharsetEncoder onUnmappableCharacter(CodingErrorAction
+                                                      newAction)
+    {
+        if (newAction == null)
+            throw new IllegalArgumentException("Null action");
+        unmappableCharacterAction = newAction;
+        implOnUnmappableCharacter(newAction);
+        return this;
+    }
+
+    /**
+     * Reports a change to this encoder's unmappable-character action.
+     *
+     * <p> The default implementation of this method does nothing.  This method
+     * should be overridden by encoders that require notification of changes to
+     * the unmappable-character action.  </p>
+     *
+     * @param  newAction  The new action
+     */
+    protected void implOnUnmappableCharacter(CodingErrorAction newAction) { }
+
+    /**
+     * Returns the average number of bytes that will be produced for each
+     * character of input.  This heuristic value may be used to estimate the size
+     * of the output buffer required for a given input sequence.
+     *
+     * @return  The average number of bytes produced
+     *          per character of input
+     */
+    public final float averageBytesPerChar() {
+        return averageBytesPerChar;
+    }
+
+    /**
+     * Returns the maximum number of bytes that will be produced for each
+     * character of input.  This value may be used to compute the worst-case size
+     * of the output buffer required for a given input sequence.
+     *
+     * @return  The maximum number of bytes that will be produced per
+     *          character of input
+     */
+    public final float maxBytesPerChar() {
+        return maxBytesPerChar;
+    }
+
+    /**
+     * Encodes as many characters as possible from the given input buffer,
+     * writing the results to the given output buffer.
+     *
+     * <p> The buffers are read from, and written to, starting at their current
+     * positions.  At most {@link Buffer#remaining in.remaining()} characters
+     * will be read and at most {@link Buffer#remaining out.remaining()}
+     * bytes will be written.  The buffers' positions will be advanced to
+     * reflect the characters read and the bytes written, but their marks and
+     * limits will not be modified.
+     *
+     * <p> In addition to reading characters from the input buffer and writing
+     * bytes to the output buffer, this method returns a {@link CoderResult}
+     * object to describe its reason for termination:
+     *
+     * <ul>
+     *
+     *   <li><p> {@link CoderResult#UNDERFLOW} indicates that as much of the
+     *   input buffer as possible has been encoded.  If there is no further
+     *   input then the invoker can proceed to the next step of the
+     *   <a href="#steps">encoding operation</a>.  Otherwise this method
+     *   should be invoked again with further input.  </p></li>
+     *
+     *   <li><p> {@link CoderResult#OVERFLOW} indicates that there is
+     *   insufficient space in the output buffer to encode any more characters.
+     *   This method should be invoked again with an output buffer that has
+     *   more {@linkplain Buffer#remaining remaining} bytes. This is
+     *   typically done by draining any encoded bytes from the output
+     *   buffer.  </p></li>
+     *
+     *   <li><p> A {@linkplain CoderResult#malformedForLength
+     *   malformed-input} result indicates that a malformed-input
+     *   error has been detected.  The malformed characters begin at the input
+     *   buffer's (possibly incremented) position; the number of malformed
+     *   characters may be determined by invoking the result object's {@link
+     *   CoderResult#length() length} method.  This case applies only if the
+     *   {@linkplain #onMalformedInput malformed action} of this encoder
+     *   is {@link CodingErrorAction#REPORT}; otherwise the malformed input
+     *   will be ignored or replaced, as requested.  </p></li>
+     *
+     *   <li><p> An {@linkplain CoderResult#unmappableForLength
+     *   unmappable-character} result indicates that an
+     *   unmappable-character error has been detected.  The characters that
+     *   encode the unmappable character begin at the input buffer's (possibly
+     *   incremented) position; the number of such characters may be determined
+     *   by invoking the result object's {@link CoderResult#length() length}
+     *   method.  This case applies only if the {@linkplain #onUnmappableCharacter
+     *   unmappable action} of this encoder is {@link
+     *   CodingErrorAction#REPORT}; otherwise the unmappable character will be
+     *   ignored or replaced, as requested.  </p></li>
+     *
+     * </ul>
+     *
+     * In any case, if this method is to be reinvoked in the same encoding
+     * operation then care should be taken to preserve any characters remaining
+     * in the input buffer so that they are available to the next invocation.
+     *
+     * <p> The <tt>endOfInput</tt> parameter advises this method as to whether
+     * the invoker can provide further input beyond that contained in the given
+     * input buffer.  If there is a possibility of providing additional input
+     * then the invoker should pass <tt>false</tt> for this parameter; if there
+     * is no possibility of providing further input then the invoker should
+     * pass <tt>true</tt>.  It is not erroneous, and in fact it is quite
+     * common, to pass <tt>false</tt> in one invocation and later discover that
+     * no further input was actually available.  It is critical, however, that
+     * the final invocation of this method in a sequence of invocations always
+     * pass <tt>true</tt> so that any remaining unencoded input will be treated
+     * as being malformed.
+     *
+     * <p> This method works by invoking the {@link #encodeLoop encodeLoop}
+     * method, interpreting its results, handling error conditions, and
+     * reinvoking it as necessary.  </p>
+     *
+     *
+     * @param  in
+     *         The input character buffer
+     *
+     * @param  out
+     *         The output byte buffer
+     *
+     * @param  endOfInput
+     *         <tt>true</tt> if, and only if, the invoker can provide no
+     *         additional input characters beyond those in the given buffer
+     *
+     * @return  A coder-result object describing the reason for termination
+     *
+     * @throws  IllegalStateException
+     *          If an encoding operation is already in progress and the previous
+     *          step was an invocation neither of the {@link #reset reset}
+     *          method, nor of this method with a value of <tt>false</tt> for
+     *          the <tt>endOfInput</tt> parameter, nor of this method with a
+     *          value of <tt>true</tt> for the <tt>endOfInput</tt> parameter
+     *          but a return value indicating an incomplete encoding operation
+     *
+     * @throws  CoderMalfunctionError
+     *          If an invocation of the encodeLoop method threw
+     *          an unexpected exception
+     */
+    public final CoderResult encode(CharBuffer in, ByteBuffer out,
+                                    boolean endOfInput)
+    {
+        int newState = endOfInput ? ST_END : ST_CODING;
+        if ((state != ST_RESET) && (state != ST_CODING)
+            && !(endOfInput && (state == ST_END)))
+            throwIllegalStateException(state, newState);
+        state = newState;
+
+        for (;;) {
+
+            CoderResult cr;
+            try {
+                cr = encodeLoop(in, out);
+            } catch (BufferUnderflowException x) {
+                throw new CoderMalfunctionError(x);
+            } catch (BufferOverflowException x) {
+                throw new CoderMalfunctionError(x);
+            }
+
+            if (cr.isOverflow())
+                return cr;
+
+            if (cr.isUnderflow()) {
+                if (endOfInput && in.hasRemaining()) {
+                    cr = CoderResult.malformedForLength(in.remaining());
+                    // Fall through to malformed-input case
+                } else {
+                    return cr;
+                }
+            }
+
+            CodingErrorAction action = null;
+            if (cr.isMalformed())
+                action = malformedInputAction;
+            else if (cr.isUnmappable())
+                action = unmappableCharacterAction;
+            else
+                assert false : cr.toString();
+
+            if (action == CodingErrorAction.REPORT)
+                return cr;
+
+            if (action == CodingErrorAction.REPLACE) {
+                if (out.remaining() < replacement.length)
+                    return CoderResult.OVERFLOW;
+                out.put(replacement);
+            }
+
+            if ((action == CodingErrorAction.IGNORE)
+                || (action == CodingErrorAction.REPLACE)) {
+                // Skip erroneous input either way
+                in.position(in.position() + cr.length());
+                continue;
+            }
+
+            assert false;
+        }
+
+    }
+
+    /**
+     * Flushes this encoder.
+     *
+     * <p> Some encoders maintain internal state and may need to write some
+     * final bytes to the output buffer once the overall input sequence has
+     * been read.
+     *
+     * <p> Any additional output is written to the output buffer beginning at
+     * its current position.  At most {@link Buffer#remaining out.remaining()}
+     * bytes will be written.  The buffer's position will be advanced
+     * appropriately, but its mark and limit will not be modified.
+     *
+     * <p> If this method completes successfully then it returns {@link
+     * CoderResult#UNDERFLOW}.  If there is insufficient room in the output
+     * buffer then it returns {@link CoderResult#OVERFLOW}.  If this happens
+     * then this method must be invoked again, with an output buffer that has
+     * more room, in order to complete the current <a href="#steps">encoding
+     * operation</a>.
+     *
+     * <p> If this encoder has already been flushed then invoking this method
+     * has no effect.
+     *
+     * <p> This method invokes the {@link #implFlush implFlush} method to
+     * perform the actual flushing operation.  </p>
+     *
+     * @param  out
+     *         The output byte buffer
+     *
+     * @return  A coder-result object, either {@link CoderResult#UNDERFLOW} or
+     *          {@link CoderResult#OVERFLOW}
+     *
+     * @throws  IllegalStateException
+     *          If the previous step of the current encoding operation was an
+     *          invocation neither of the {@link #flush flush} method nor of
+     *          the three-argument {@link
+     *          #encode(CharBuffer,ByteBuffer,boolean) encode} method
+     *          with a value of <tt>true</tt> for the <tt>endOfInput</tt>
+     *          parameter
+     */
+    public final CoderResult flush(ByteBuffer out) {
+        if (state == ST_END) {
+            CoderResult cr = implFlush(out);
+            if (cr.isUnderflow())
+                state = ST_FLUSHED;
+            return cr;
+        }
+
+        if (state != ST_FLUSHED)
+            throwIllegalStateException(state, ST_FLUSHED);
+
+        return CoderResult.UNDERFLOW; // Already flushed
+    }
+
+    /**
+     * Flushes this encoder.
+     *
+     * <p> The default implementation of this method does nothing, and always
+     * returns {@link CoderResult#UNDERFLOW}.  This method should be overridden
+     * by encoders that may need to write final bytes to the output buffer
+     * once the entire input sequence has been read. </p>
+     *
+     * @param  out
+     *         The output byte buffer
+     *
+     * @return  A coder-result object, either {@link CoderResult#UNDERFLOW} or
+     *          {@link CoderResult#OVERFLOW}
+     */
+    protected CoderResult implFlush(ByteBuffer out) {
+        return CoderResult.UNDERFLOW;
+    }
+
+    /**
+     * Resets this encoder, clearing any internal state.
+     *
+     * <p> This method resets charset-independent state and also invokes the
+     * {@link #implReset() implReset} method in order to perform any
+     * charset-specific reset actions.  </p>
+     *
+     * @return  This encoder
+     *
+     */
+    public final CharsetEncoder reset() {
+        implReset();
+        state = ST_RESET;
+        return this;
+    }
+
+    /**
+     * Resets this encoder, clearing any charset-specific internal state.
+     *
+     * <p> The default implementation of this method does nothing.  This method
+     * should be overridden by encoders that maintain internal state.  </p>
+     */
+    protected void implReset() { }
+
+    /**
+     * Encodes one or more characters into one or more bytes.
+     *
+     * <p> This method encapsulates the basic encoding loop, encoding as many
+     * characters as possible until it either runs out of input, runs out of room
+     * in the output buffer, or encounters an encoding error.  This method is
+     * invoked by the {@link #encode encode} method, which handles result
+     * interpretation and error recovery.
+     *
+     * <p> The buffers are read from, and written to, starting at their current
+     * positions.  At most {@link Buffer#remaining in.remaining()} characters
+     * will be read, and at most {@link Buffer#remaining out.remaining()}
+     * bytes will be written.  The buffers' positions will be advanced to
+     * reflect the characters read and the bytes written, but their marks and
+     * limits will not be modified.
+     *
+     * <p> This method returns a {@link CoderResult} object to describe its
+     * reason for termination, in the same manner as the {@link #encode encode}
+     * method.  Most implementations of this method will handle encoding errors
+     * by returning an appropriate result object for interpretation by the
+     * {@link #encode encode} method.  An optimized implementation may instead
+     * examine the relevant error action and implement that action itself.
+     *
+     * <p> An implementation of this method may perform arbitrary lookahead by
+     * returning {@link CoderResult#UNDERFLOW} until it receives sufficient
+     * input.  </p>
+     *
+     * @param  in
+     *         The input character buffer
+     *
+     * @param  out
+     *         The output byte buffer
+     *
+     * @return  A coder-result object describing the reason for termination
+     */
+    protected abstract CoderResult encodeLoop(CharBuffer in,
+                                              ByteBuffer out);
+
+    /**
+     * Convenience method that encodes the remaining content of a single input
+     * character buffer into a newly-allocated byte buffer.
+     *
+     * <p> This method implements an entire <a href="#steps">encoding
+     * operation</a>; that is, it resets this encoder, then it encodes the
+     * characters in the given character buffer, and finally it flushes this
+     * encoder.  This method should therefore not be invoked if an encoding
+     * operation is already in progress.  </p>
+     *
+     * @param  in
+     *         The input character buffer
+     *
+     * @return A newly-allocated byte buffer containing the result of the
+     *         encoding operation.  The buffer's position will be zero and its
+     *         limit will follow the last byte written.
+     *
+     * @throws  IllegalStateException
+     *          If an encoding operation is already in progress
+     *
+     * @throws  MalformedInputException
+     *          If the character sequence starting at the input buffer's current
+     *          position is not a legal sixteen-bit Unicode sequence and the current malformed-input action
+     *          is {@link CodingErrorAction#REPORT}
+     *
+     * @throws  UnmappableCharacterException
+     *          If the character sequence starting at the input buffer's current
+     *          position cannot be mapped to an equivalent byte sequence and
+     *          the current unmappable-character action is {@link
+     *          CodingErrorAction#REPORT}
+     */
+    public final ByteBuffer encode(CharBuffer in)
+        throws CharacterCodingException
+    {
+        int n = (int)(in.remaining() * averageBytesPerChar());
+        ByteBuffer out = ByteBuffer.allocate(n);
+
+        if ((n == 0) && (in.remaining() == 0))
+            return out;
+        reset();
+        for (;;) {
+            CoderResult cr = in.hasRemaining() ?
+                encode(in, out, true) : CoderResult.UNDERFLOW;
+            if (cr.isUnderflow())
+                cr = flush(out);
+
+            if (cr.isUnderflow())
+                break;
+            if (cr.isOverflow()) {
+                n = 2*n + 1;    // Ensure progress; n might be 0!
+                ByteBuffer o = ByteBuffer.allocate(n);
+                out.flip();
+                o.put(out);
+                out = o;
+                continue;
+            }
+            cr.throwException();
+        }
+        out.flip();
+        return out;
+    }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    private boolean canEncode(CharBuffer cb) {
+        if (state == ST_FLUSHED)
+            reset();
+        else if (state != ST_RESET)
+            throwIllegalStateException(state, ST_CODING);
+
+        // BEGIN Android-added: Fast path handling for empty buffers.
+        // Empty buffers can always be "encoded".
+        if (!cb.hasRemaining()) {
+            return true;
+        }
+        // END Android-added: Fast path handling for empty buffers.
+
+        CodingErrorAction ma = malformedInputAction();
+        CodingErrorAction ua = unmappableCharacterAction();
+        try {
+            onMalformedInput(CodingErrorAction.REPORT);
+            onUnmappableCharacter(CodingErrorAction.REPORT);
+            encode(cb);
+        } catch (CharacterCodingException x) {
+            return false;
+        } finally {
+            onMalformedInput(ma);
+            onUnmappableCharacter(ua);
+            reset();
+        }
+        return true;
+    }
+
+    /**
+     * Tells whether or not this encoder can encode the given character.
+     *
+     * <p> This method returns <tt>false</tt> if the given character is a
+     * surrogate character; such characters can be interpreted only when they
+     * are members of a pair consisting of a high surrogate followed by a low
+     * surrogate.  The {@link #canEncode(java.lang.CharSequence)
+     * canEncode(CharSequence)} method may be used to test whether or not a
+     * character sequence can be encoded.
+     *
+     * <p> This method may modify this encoder's state; it should therefore not
+     * be invoked if an <a href="#steps">encoding operation</a> is already in
+     * progress.
+     *
+     * <p> The default implementation of this method is not very efficient; it
+     * should generally be overridden to improve performance.  </p>
+     *
+     * @param   c
+     *          The given character
+     *
+     * @return  <tt>true</tt> if, and only if, this encoder can encode
+     *          the given character
+     *
+     * @throws  IllegalStateException
+     *          If an encoding operation is already in progress
+     */
+    public boolean canEncode(char c) {
+        CharBuffer cb = CharBuffer.allocate(1);
+        cb.put(c);
+        cb.flip();
+        return canEncode(cb);
+    }
+
+    /**
+     * Tells whether or not this encoder can encode the given character
+     * sequence.
+     *
+     * <p> If this method returns <tt>false</tt> for a particular character
+     * sequence then more information about why the sequence cannot be encoded
+     * may be obtained by performing a full <a href="#steps">encoding
+     * operation</a>.
+     *
+     * <p> This method may modify this encoder's state; it should therefore not
+     * be invoked if an encoding operation is already in progress.
+     *
+     * <p> The default implementation of this method is not very efficient; it
+     * should generally be overridden to improve performance.  </p>
+     *
+     * @param   cs
+     *          The given character sequence
+     *
+     * @return  <tt>true</tt> if, and only if, this encoder can encode
+     *          the given character without throwing any exceptions and without
+     *          performing any replacements
+     *
+     * @throws  IllegalStateException
+     *          If an encoding operation is already in progress
+     */
+    public boolean canEncode(CharSequence cs) {
+        CharBuffer cb;
+        if (cs instanceof CharBuffer)
+            cb = ((CharBuffer)cs).duplicate();
+        else
+            // Android-removed: An unnecessary call to toString().
+            // cb = CharBuffer.wrap(cs.toString());
+            cb = CharBuffer.wrap(cs);
+        return canEncode(cb);
+    }
+
+
+
+
+    private void throwIllegalStateException(int from, int to) {
+        throw new IllegalStateException("Current state = " + stateNames[from]
+                                        + ", new state = " + stateNames[to]);
+    }
+
+}
diff --git a/java/nio/charset/CoderMalfunctionError.java b/java/nio/charset/CoderMalfunctionError.java
new file mode 100644
index 0000000..aec47e5
--- /dev/null
+++ b/java/nio/charset/CoderMalfunctionError.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2001, 2007, 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.nio.charset;
+
+
+/**
+ * Error thrown when the {@link CharsetDecoder#decodeLoop decodeLoop} method of
+ * a {@link CharsetDecoder}, or the {@link CharsetEncoder#encodeLoop
+ * encodeLoop} method of a {@link CharsetEncoder}, throws an unexpected
+ * exception.
+ *
+ * @since 1.4
+ */
+
+public class CoderMalfunctionError
+    extends Error
+{
+
+    private static final long serialVersionUID = -1151412348057794301L;
+
+    /**
+     * Initializes an instance of this class.
+     *
+     * @param  cause
+     *         The unexpected exception that was thrown
+     */
+    public CoderMalfunctionError(Exception cause) {
+        super(cause);
+    }
+
+}
diff --git a/java/nio/charset/CoderResult.java b/java/nio/charset/CoderResult.java
new file mode 100644
index 0000000..d087c97
--- /dev/null
+++ b/java/nio/charset/CoderResult.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2001, 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.nio.charset;
+
+import java.lang.ref.WeakReference;
+import java.nio.*;
+import java.util.Map;
+import java.util.HashMap;
+
+
+/**
+ * A description of the result state of a coder.
+ *
+ * <p> A charset coder, that is, either a decoder or an encoder, consumes bytes
+ * (or characters) from an input buffer, translates them, and writes the
+ * resulting characters (or bytes) to an output buffer.  A coding process
+ * terminates for one of four categories of reasons, which are described by
+ * instances of this class:
+ *
+ * <ul>
+ *
+ *   <li><p> <i>Underflow</i> is reported when there is no more input to be
+ *   processed, or there is insufficient input and additional input is
+ *   required.  This condition is represented by the unique result object
+ *   {@link #UNDERFLOW}, whose {@link #isUnderflow() isUnderflow} method
+ *   returns <tt>true</tt>.  </p></li>
+ *
+ *   <li><p> <i>Overflow</i> is reported when there is insufficient room
+ *   remaining in the output buffer.  This condition is represented by the
+ *   unique result object {@link #OVERFLOW}, whose {@link #isOverflow()
+ *   isOverflow} method returns <tt>true</tt>.  </p></li>
+ *
+ *   <li><p> A <i>malformed-input error</i> is reported when a sequence of
+ *   input units is not well-formed.  Such errors are described by instances of
+ *   this class whose {@link #isMalformed() isMalformed} method returns
+ *   <tt>true</tt> and whose {@link #length() length} method returns the length
+ *   of the malformed sequence.  There is one unique instance of this class for
+ *   all malformed-input errors of a given length.  </p></li>
+ *
+ *   <li><p> An <i>unmappable-character error</i> is reported when a sequence
+ *   of input units denotes a character that cannot be represented in the
+ *   output charset.  Such errors are described by instances of this class
+ *   whose {@link #isUnmappable() isUnmappable} method returns <tt>true</tt> and
+ *   whose {@link #length() length} method returns the length of the input
+ *   sequence denoting the unmappable character.  There is one unique instance
+ *   of this class for all unmappable-character errors of a given length.
+ *   </p></li>
+ *
+ * </ul>
+ *
+ * <p> For convenience, the {@link #isError() isError} method returns <tt>true</tt>
+ * for result objects that describe malformed-input and unmappable-character
+ * errors but <tt>false</tt> for those that describe underflow or overflow
+ * conditions.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public class CoderResult {
+
+    private static final int CR_UNDERFLOW  = 0;
+    private static final int CR_OVERFLOW   = 1;
+    private static final int CR_ERROR_MIN  = 2;
+    private static final int CR_MALFORMED  = 2;
+    private static final int CR_UNMAPPABLE = 3;
+
+    private static final String[] names
+        = { "UNDERFLOW", "OVERFLOW", "MALFORMED", "UNMAPPABLE" };
+
+    private final int type;
+    private final int length;
+
+    private CoderResult(int type, int length) {
+        this.type = type;
+        this.length = length;
+    }
+
+    /**
+     * Returns a string describing this coder result.
+     *
+     * @return  A descriptive string
+     */
+    public String toString() {
+        String nm = names[type];
+        return isError() ? nm + "[" + length + "]" : nm;
+    }
+
+    /**
+     * Tells whether or not this object describes an underflow condition.
+     *
+     * @return  <tt>true</tt> if, and only if, this object denotes underflow
+     */
+    public boolean isUnderflow() {
+        return (type == CR_UNDERFLOW);
+    }
+
+    /**
+     * Tells whether or not this object describes an overflow condition.
+     *
+     * @return  <tt>true</tt> if, and only if, this object denotes overflow
+     */
+    public boolean isOverflow() {
+        return (type == CR_OVERFLOW);
+    }
+
+    /**
+     * Tells whether or not this object describes an error condition.
+     *
+     * @return  <tt>true</tt> if, and only if, this object denotes either a
+     *          malformed-input error or an unmappable-character error
+     */
+    public boolean isError() {
+        return (type >= CR_ERROR_MIN);
+    }
+
+    /**
+     * Tells whether or not this object describes a malformed-input error.
+     *
+     * @return  <tt>true</tt> if, and only if, this object denotes a
+     *          malformed-input error
+     */
+    public boolean isMalformed() {
+        return (type == CR_MALFORMED);
+    }
+
+    /**
+     * Tells whether or not this object describes an unmappable-character
+     * error.
+     *
+     * @return  <tt>true</tt> if, and only if, this object denotes an
+     *          unmappable-character error
+     */
+    public boolean isUnmappable() {
+        return (type == CR_UNMAPPABLE);
+    }
+
+    /**
+     * Returns the length of the erroneous input described by this
+     * object&nbsp;&nbsp;<i>(optional operation)</i>.
+     *
+     * @return  The length of the erroneous input, a positive integer
+     *
+     * @throws  UnsupportedOperationException
+     *          If this object does not describe an error condition, that is,
+     *          if the {@link #isError() isError} does not return <tt>true</tt>
+     */
+    public int length() {
+        if (!isError())
+            throw new UnsupportedOperationException();
+        return length;
+    }
+
+    /**
+     * Result object indicating underflow, meaning that either the input buffer
+     * has been completely consumed or, if the input buffer is not yet empty,
+     * that additional input is required.
+     */
+    public static final CoderResult UNDERFLOW
+        = new CoderResult(CR_UNDERFLOW, 0);
+
+    /**
+     * Result object indicating overflow, meaning that there is insufficient
+     * room in the output buffer.
+     */
+    public static final CoderResult OVERFLOW
+        = new CoderResult(CR_OVERFLOW, 0);
+
+    private static abstract class Cache {
+
+        private Map<Integer,WeakReference<CoderResult>> cache = null;
+
+        protected abstract CoderResult create(int len);
+
+        private synchronized CoderResult get(int len) {
+            if (len <= 0)
+                throw new IllegalArgumentException("Non-positive length");
+            Integer k = new Integer(len);
+            WeakReference<CoderResult> w;
+            CoderResult e = null;
+            if (cache == null) {
+                cache = new HashMap<Integer,WeakReference<CoderResult>>();
+            } else if ((w = cache.get(k)) != null) {
+                e = w.get();
+            }
+            if (e == null) {
+                e = create(len);
+                cache.put(k, new WeakReference<CoderResult>(e));
+            }
+            return e;
+        }
+
+    }
+
+    private static Cache malformedCache
+        = new Cache() {
+                public CoderResult create(int len) {
+                    return new CoderResult(CR_MALFORMED, len);
+                }};
+
+    /**
+     * Static factory method that returns the unique object describing a
+     * malformed-input error of the given length.
+     *
+     * @param   length
+     *          The given length
+     *
+     * @return  The requested coder-result object
+     */
+    public static CoderResult malformedForLength(int length) {
+        return malformedCache.get(length);
+    }
+
+    private static Cache unmappableCache
+        = new Cache() {
+                public CoderResult create(int len) {
+                    return new CoderResult(CR_UNMAPPABLE, len);
+                }};
+
+    /**
+     * Static factory method that returns the unique result object describing
+     * an unmappable-character error of the given length.
+     *
+     * @param   length
+     *          The given length
+     *
+     * @return  The requested coder-result object
+     */
+    public static CoderResult unmappableForLength(int length) {
+        return unmappableCache.get(length);
+    }
+
+    /**
+     * Throws an exception appropriate to the result described by this object.
+     *
+     * @throws  BufferUnderflowException
+     *          If this object is {@link #UNDERFLOW}
+     *
+     * @throws  BufferOverflowException
+     *          If this object is {@link #OVERFLOW}
+     *
+     * @throws  MalformedInputException
+     *          If this object represents a malformed-input error; the
+     *          exception's length value will be that of this object
+     *
+     * @throws  UnmappableCharacterException
+     *          If this object represents an unmappable-character error; the
+     *          exceptions length value will be that of this object
+     */
+    public void throwException()
+        throws CharacterCodingException
+    {
+        switch (type) {
+        case CR_UNDERFLOW:   throw new BufferUnderflowException();
+        case CR_OVERFLOW:    throw new BufferOverflowException();
+        case CR_MALFORMED:   throw new MalformedInputException(length);
+        case CR_UNMAPPABLE:  throw new UnmappableCharacterException(length);
+        default:
+            assert false;
+        }
+    }
+
+}
diff --git a/java/nio/charset/CodingErrorAction.java b/java/nio/charset/CodingErrorAction.java
new file mode 100644
index 0000000..c708e63
--- /dev/null
+++ b/java/nio/charset/CodingErrorAction.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001, 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.nio.charset;
+
+
+/**
+ * A typesafe enumeration for coding-error actions.
+ *
+ * <p> Instances of this class are used to specify how malformed-input and
+ * unmappable-character errors are to be handled by charset <a
+ * href="CharsetDecoder.html#cae">decoders</a> and <a
+ * href="CharsetEncoder.html#cae">encoders</a>.  </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ */
+
+public class CodingErrorAction {
+
+    private String name;
+
+    private CodingErrorAction(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Action indicating that a coding error is to be handled by dropping the
+     * erroneous input and resuming the coding operation.
+     */
+    public static final CodingErrorAction IGNORE
+        = new CodingErrorAction("IGNORE");
+
+    /**
+     * Action indicating that a coding error is to be handled by dropping the
+     * erroneous input, appending the coder's replacement value to the output
+     * buffer, and resuming the coding operation.
+     */
+    public static final CodingErrorAction REPLACE
+        = new CodingErrorAction("REPLACE");
+
+    /**
+     * Action indicating that a coding error is to be reported, either by
+     * returning a {@link CoderResult} object or by throwing a {@link
+     * CharacterCodingException}, whichever is appropriate for the method
+     * implementing the coding process.
+     */
+    public static final CodingErrorAction REPORT
+        = new CodingErrorAction("REPORT");
+
+    /**
+     * Returns a string describing this action.
+     *
+     * @return  A descriptive string
+     */
+    public String toString() {
+        return name;
+    }
+
+}
diff --git a/java/nio/charset/IllegalCharsetNameException.java b/java/nio/charset/IllegalCharsetNameException.java
new file mode 100644
index 0000000..9124282
--- /dev/null
+++ b/java/nio/charset/IllegalCharsetNameException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.charset;
+
+
+/**
+ * Unchecked exception thrown when a string that is not a
+ * <a href=Charset.html#names>legal charset name</a> is used as such.
+ *
+ * @since 1.4
+ */
+
+public class IllegalCharsetNameException
+    extends IllegalArgumentException
+{
+
+    private static final long serialVersionUID = 1457525358470002989L;
+
+    private String charsetName;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param  charsetName
+     *         The illegal charset name
+     */
+    public IllegalCharsetNameException(String charsetName) {
+        super(String.valueOf(charsetName));
+	this.charsetName = charsetName;
+    }
+
+    /**
+     * Retrieves the illegal charset name.
+     *
+     * @return  The illegal charset name
+     */
+    public String getCharsetName() {
+        return charsetName;
+    }
+
+}
diff --git a/java/nio/charset/MalformedInputException.java b/java/nio/charset/MalformedInputException.java
new file mode 100644
index 0000000..aadbadc
--- /dev/null
+++ b/java/nio/charset/MalformedInputException.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.charset;
+
+
+/**
+ * Checked exception thrown when an input byte sequence is not legal for given
+ * charset, or an input character sequence is not a legal sixteen-bit Unicode
+ * sequence.
+ *
+ * @since 1.4
+ */
+
+public class MalformedInputException
+    extends CharacterCodingException
+{
+
+    private static final long serialVersionUID = -3438823399834806194L;
+
+    private int inputLength;
+
+    /**
+     * Constructs an {@code MalformedInputException} with the given
+     * length.
+     * @param inputLength the length of the input
+     */
+    public MalformedInputException(int inputLength) {
+        this.inputLength = inputLength;
+    }
+
+    /**
+     * Returns the length of the input.
+     * @return the length of the input
+     */
+    public int getInputLength() {
+        return inputLength;
+    }
+
+    /**
+     * Returns the message.
+     * @return the message
+     */
+    public String getMessage() {
+        return "Input length = " + inputLength;
+    }
+
+}
diff --git a/java/nio/charset/StandardCharsets.java b/java/nio/charset/StandardCharsets.java
new file mode 100644
index 0000000..b2572c3
--- /dev/null
+++ b/java/nio/charset/StandardCharsets.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.charset;
+
+/**
+ * Constant definitions for the standard {@link Charset Charsets}. These
+ * charsets are guaranteed to be available on every implementation of the Java
+ * platform.
+ *
+ * @see <a href="Charset#standard">Standard Charsets</a>
+ * @since 1.7
+ */
+public final class StandardCharsets {
+
+    private StandardCharsets() {
+        throw new AssertionError("No java.nio.charset.StandardCharsets instances for you!");
+    }
+    /**
+     * Seven-bit ASCII, a.k.a. ISO646-US, a.k.a. the Basic Latin block of the
+     * Unicode character set
+     */
+    public static final Charset US_ASCII = Charset.forName("US-ASCII");
+    /**
+     * ISO Latin Alphabet No. 1, a.k.a. ISO-LATIN-1
+     */
+    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+    /**
+     * Eight-bit UCS Transformation Format
+     */
+    public static final Charset UTF_8 = Charset.forName("UTF-8");
+    /**
+     * Sixteen-bit UCS Transformation Format, big-endian byte order
+     */
+    public static final Charset UTF_16BE = Charset.forName("UTF-16BE");
+    /**
+     * Sixteen-bit UCS Transformation Format, little-endian byte order
+     */
+    public static final Charset UTF_16LE = Charset.forName("UTF-16LE");
+    /**
+     * Sixteen-bit UCS Transformation Format, byte order identified by an
+     * optional byte-order mark
+     */
+    public static final Charset UTF_16 = Charset.forName("UTF-16");
+}
diff --git a/java/nio/charset/UnmappableCharacterException.java b/java/nio/charset/UnmappableCharacterException.java
new file mode 100644
index 0000000..c33f040
--- /dev/null
+++ b/java/nio/charset/UnmappableCharacterException.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2001, 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.nio.charset;
+
+
+/**
+ * Checked exception thrown when an input character (or byte) sequence
+ * is valid but cannot be mapped to an output byte (or character)
+ * sequence.
+ *
+ * @since 1.4
+ */
+
+public class UnmappableCharacterException
+    extends CharacterCodingException
+{
+
+    private static final long serialVersionUID = -7026962371537706123L;
+
+    private int inputLength;
+
+    /**
+     * Constructs an {@code UnmappableCharacterException} with the
+     * given length.
+     * @param inputLength the length of the input
+     */
+    public UnmappableCharacterException(int inputLength) {
+        this.inputLength = inputLength;
+    }
+
+    /**
+     * Returns the length of the input.
+     * @return the length of the input
+     */
+    public int getInputLength() {
+        return inputLength;
+    }
+
+    /**
+     * Returns the message.
+     * @return the message
+     */
+    public String getMessage() {
+        return "Input length = " + inputLength;
+    }
+
+}
diff --git a/java/nio/charset/UnsupportedCharsetException.java b/java/nio/charset/UnsupportedCharsetException.java
new file mode 100644
index 0000000..1774fc0
--- /dev/null
+++ b/java/nio/charset/UnsupportedCharsetException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2000, 2007, 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.
+ *
+ */
+
+// -- This file was mechanically generated: Do not edit! -- //
+
+package java.nio.charset;
+
+
+/**
+ * Unchecked exception thrown when no support is available
+ * for a requested charset.
+ *
+ * @since 1.4
+ */
+
+public class UnsupportedCharsetException
+    extends IllegalArgumentException
+{
+
+    private static final long serialVersionUID = 1490765524727386367L;
+
+    private String charsetName;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param  charsetName
+     *         The name of the unsupported charset
+     */
+    public UnsupportedCharsetException(String charsetName) {
+        super(String.valueOf(charsetName));
+	this.charsetName = charsetName;
+    }
+
+    /**
+     * Retrieves the name of the unsupported charset.
+     *
+     * @return  The name of the unsupported charset
+     */
+    public String getCharsetName() {
+        return charsetName;
+    }
+
+}
diff --git a/java/nio/charset/package-info.java b/java/nio/charset/package-info.java
new file mode 100644
index 0000000..1fc81e0
--- /dev/null
+++ b/java/nio/charset/package-info.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Defines charsets, decoders, and encoders, for translating between bytes and
+ * Unicode characters.
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Summary of charsets, decoders, and encoders in this package">
+ *  <tr><th><p align="left">Class name</p></th><th><p align="left">Description</p></th></tr>
+ *   <tr><td valign=top><tt>{@link java.nio.charset.Charset}</tt></td>
+ *       <td>A named mapping between characters<br>and bytes</td></tr>
+ *   <tr><td valign=top><tt>{@link java.nio.charset.CharsetDecoder}</tt></td>
+ *       <td>Decodes bytes into characters</td></tr>
+ *   <tr><td valign=top><tt>{@link java.nio.charset.CharsetEncoder}&nbsp;&nbsp;</tt></td>
+ *       <td>Encodes characters into bytes</td></tr>
+ *   <tr><td valign=top><tt>{@link java.nio.charset.CoderResult}&nbsp;&nbsp;</tt></td>
+ *       <td>Describes coder results</td></tr>
+ *   <tr><td valign=top><tt>{@link java.nio.charset.CodingErrorAction}&nbsp;&nbsp;</tt></td>
+ *       <td>Describes actions to take when<br>coding errors are detected</td></tr>
+ *
+ * </table></blockquote>
+ *
+ * <p> A <i>charset</i> is named mapping between sequences of sixteen-bit Unicode
+ * characters and sequences of bytes, in the sense defined in <a
+ * href="http://www.ietf.org/rfc/rfc2278.txt"><i>RFC&nbsp;2278</i></a>.  A
+ * <i>decoder</i> is an engine which transforms bytes in a specific charset into
+ * characters, and an <i>encoder</i> is an engine which transforms characters into
+ * bytes.  Encoders and decoders operate on byte and character buffers.  They are
+ * collectively referred to as <i>coders</i>.
+ *
+ * <p> The {@link java.nio.charset.Charset} class defines methods for creating
+ * coders for a given charset and for retrieving the various names associated with
+ * a charset.  It also defines static methods for testing whether a particular
+ * charset is supported, for locating charset instances by name, and for
+ * constructing a map that contains every charset for which support is available
+ * in the current Java virtual machine.
+ *
+ * <p> Most users will not use these classes directly; instead they will use the
+ * existing charset-related constructors and methods in the {@link
+ * java.lang.String} class, together with the existing {@link
+ * java.io.InputStreamReader} and {@link java.io.OutputStreamWriter} classes, all
+ * of whose implementations have been reworked to make use of the charset
+ * facilities defined in this package.  A small number of changes have been made
+ * to the {@link java.io.InputStreamReader} and {@link java.io.OutputStreamWriter}
+ * classes in order to allow explicit charset objects to be specified in the
+ * construction of instances of those classes.
+ *
+ * <p> Support for new charsets can be made available via the interface defined in
+ * the {@link java.nio.charset.spi.CharsetProvider} class in the <tt>{@link
+ * java.nio.charset.spi}</tt> package.
+ *
+ * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
+ * or method in any class or interface in this package will cause a {@link
+ * java.lang.NullPointerException NullPointerException} to be thrown.
+ *
+ *
+ * @since 1.4
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ */
+
+package java.nio.charset;
diff --git a/java/nio/charset/spi/CharsetProvider.java b/java/nio/charset/spi/CharsetProvider.java
new file mode 100644
index 0000000..f7821e7
--- /dev/null
+++ b/java/nio/charset/spi/CharsetProvider.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.charset.spi;
+
+import java.nio.charset.Charset;
+import java.util.Iterator;
+
+
+/**
+ * Charset service-provider class.
+ *
+ * <p> A charset provider is a concrete subclass of this class that has a
+ * zero-argument constructor and some number of associated charset
+ * implementation classes.  Charset providers may be installed in an instance
+ * of the Java platform as extensions, that is, jar files placed into any of
+ * the usual extension directories.  Providers may also be made available by
+ * adding them to the applet or application class path or by some other
+ * platform-specific means.  Charset providers are looked up via the current
+ * thread's {@link java.lang.Thread#getContextClassLoader() context class
+ * loader}.
+ *
+ * <p> A charset provider identifies itself with a provider-configuration file
+ * named <tt>java.nio.charset.spi.CharsetProvider</tt> in the resource
+ * directory <tt>META-INF/services</tt>.  The file should contain a list of
+ * fully-qualified concrete charset-provider class names, one per line.  A line
+ * is terminated by any one of a line feed (<tt>'\n'</tt>), a carriage return
+ * (<tt>'\r'</tt>), or a carriage return followed immediately by a line feed.
+ * Space and tab characters surrounding each name, as well as blank lines, are
+ * ignored.  The comment character is <tt>'#'</tt> (<tt>'&#92;u0023'</tt>); on
+ * each line all characters following the first comment character are ignored.
+ * The file must be encoded in UTF-8.
+ *
+ * <p> If a particular concrete charset provider class is named in more than
+ * one configuration file, or is named in the same configuration file more than
+ * once, then the duplicates will be ignored.  The configuration file naming a
+ * particular provider need not be in the same jar file or other distribution
+ * unit as the provider itself.  The provider must be accessible from the same
+ * class loader that was initially queried to locate the configuration file;
+ * this is not necessarily the class loader that loaded the file. </p>
+ *
+ *
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ * @since 1.4
+ *
+ * @see java.nio.charset.Charset
+ */
+
+public abstract class CharsetProvider {
+
+    /**
+     * Initializes a new charset provider.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     *          {@link RuntimePermission}<tt>("charsetProvider")</tt>
+     */
+    protected CharsetProvider() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null)
+            sm.checkPermission(new RuntimePermission("charsetProvider"));
+    }
+
+    /**
+     * Creates an iterator that iterates over the charsets supported by this
+     * provider.  This method is used in the implementation of the {@link
+     * java.nio.charset.Charset#availableCharsets Charset.availableCharsets}
+     * method.
+     *
+     * @return  The new iterator
+     */
+    public abstract Iterator<Charset> charsets();
+
+    /**
+     * Retrieves a charset for the given charset name.
+     *
+     * @param  charsetName
+     *         The name of the requested charset; may be either
+     *         a canonical name or an alias
+     *
+     * @return  A charset object for the named charset,
+     *          or <tt>null</tt> if the named charset
+     *          is not supported by this provider
+     */
+    public abstract Charset charsetForName(String charsetName);
+
+}
diff --git a/java/nio/file/AccessDeniedException.java b/java/nio/file/AccessDeniedException.java
new file mode 100644
index 0000000..43b3862
--- /dev/null
+++ b/java/nio/file/AccessDeniedException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation is denied, typically
+ * due to a file permission or other access check.
+ *
+ * <p> This exception is not related to the {@link
+ * java.security.AccessControlException AccessControlException} or {@link
+ * SecurityException} thrown by access controllers or security managers when
+ * access to a file is denied.
+ *
+ * @since 1.7
+ */
+
+public class AccessDeniedException
+    extends FileSystemException
+{
+    private static final long serialVersionUID = 4943049599949219617L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     */
+    public AccessDeniedException(String file) {
+        super(file);
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     * @param   other
+     *          a string identifying the other file or {@code null} if not known
+     * @param   reason
+     *          a reason message with additional information or {@code null}
+     */
+    public AccessDeniedException(String file, String other, String reason) {
+        super(file, other, reason);
+    }
+}
diff --git a/java/nio/file/AccessMode.java b/java/nio/file/AccessMode.java
new file mode 100644
index 0000000..8816e9b
--- /dev/null
+++ b/java/nio/file/AccessMode.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+/**
+ * Defines access modes used to test the accessibility of a file.
+ *
+ * @since 1.7
+ */
+
+public enum AccessMode {
+    /**
+     * Test read access.
+     */
+    READ,
+    /**
+     * Test write access.
+     */
+    WRITE,
+    /**
+     * Test execute access.
+     */
+    EXECUTE;
+}
diff --git a/java/nio/file/AtomicMoveNotSupportedException.java b/java/nio/file/AtomicMoveNotSupportedException.java
new file mode 100644
index 0000000..27947c3
--- /dev/null
+++ b/java/nio/file/AtomicMoveNotSupportedException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Checked exception thrown when a file cannot be moved as an atomic file system
+ * operation.
+ *
+ * @since 1.7
+ */
+
+public class AtomicMoveNotSupportedException
+    extends FileSystemException
+{
+    static final long serialVersionUID = 5402760225333135579L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   source
+     *          a string identifying the source file or {@code null} if not known
+     * @param   target
+     *          a string identifying the target file or {@code null} if not known
+     * @param   reason
+     *          a reason message with additional information
+     */
+    public AtomicMoveNotSupportedException(String source,
+                                           String target,
+                                           String reason)
+    {
+        super(source, target, reason);
+    }
+}
diff --git a/java/nio/file/ClosedDirectoryStreamException.java b/java/nio/file/ClosedDirectoryStreamException.java
new file mode 100644
index 0000000..aa1e0ce
--- /dev/null
+++ b/java/nio/file/ClosedDirectoryStreamException.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an operation on
+ * a directory stream that is closed.
+ *
+ * @since 1.7
+ */
+
+public class ClosedDirectoryStreamException
+    extends IllegalStateException
+{
+    static final long serialVersionUID = 4228386650900895400L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ClosedDirectoryStreamException() {
+    }
+}
diff --git a/java/nio/file/ClosedFileSystemException.java b/java/nio/file/ClosedFileSystemException.java
new file mode 100644
index 0000000..82cf096
--- /dev/null
+++ b/java/nio/file/ClosedFileSystemException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an operation on
+ * a file and the file system is closed.
+ */
+
+public class ClosedFileSystemException
+    extends IllegalStateException
+{
+    static final long serialVersionUID = -8158336077256193488L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ClosedFileSystemException() {
+    }
+}
diff --git a/java/nio/file/ClosedWatchServiceException.java b/java/nio/file/ClosedWatchServiceException.java
new file mode 100644
index 0000000..3995b6d
--- /dev/null
+++ b/java/nio/file/ClosedWatchServiceException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke an operation on
+ * a watch service that is closed.
+ */
+
+public class ClosedWatchServiceException
+    extends IllegalStateException
+{
+    static final long serialVersionUID = 1853336266231677732L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ClosedWatchServiceException() {
+    }
+}
diff --git a/java/nio/file/CopyMoveHelper.java b/java/nio/file/CopyMoveHelper.java
new file mode 100644
index 0000000..ab92818
--- /dev/null
+++ b/java/nio/file/CopyMoveHelper.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+import java.nio.file.attribute.*;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * Helper class to support copying or moving files when the source and target
+ * are associated with different providers.
+ */
+
+class CopyMoveHelper {
+    private CopyMoveHelper() { }
+
+    /**
+     * Parses the arguments for a file copy operation.
+     */
+    private static class CopyOptions {
+        boolean replaceExisting = false;
+        boolean copyAttributes = false;
+        boolean followLinks = true;
+
+        private CopyOptions() { }
+
+        static CopyOptions parse(CopyOption... options) {
+            CopyOptions result = new CopyOptions();
+            for (CopyOption option: options) {
+                if (option == StandardCopyOption.REPLACE_EXISTING) {
+                    result.replaceExisting = true;
+                    continue;
+                }
+                if (option == LinkOption.NOFOLLOW_LINKS) {
+                    result.followLinks = false;
+                    continue;
+                }
+                if (option == StandardCopyOption.COPY_ATTRIBUTES) {
+                    result.copyAttributes = true;
+                    continue;
+                }
+                if (option == null)
+                    throw new NullPointerException();
+                throw new UnsupportedOperationException("'" + option +
+                    "' is not a recognized copy option");
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Converts the given array of options for moving a file to options suitable
+     * for copying the file when a move is implemented as copy + delete.
+     */
+    private static CopyOption[] convertMoveToCopyOptions(CopyOption... options)
+        throws AtomicMoveNotSupportedException
+    {
+        int len = options.length;
+        CopyOption[] newOptions = new CopyOption[len+2];
+        for (int i=0; i<len; i++) {
+            CopyOption option = options[i];
+            if (option == StandardCopyOption.ATOMIC_MOVE) {
+                throw new AtomicMoveNotSupportedException(null, null,
+                    "Atomic move between providers is not supported");
+            }
+            newOptions[i] = option;
+        }
+        newOptions[len] = LinkOption.NOFOLLOW_LINKS;
+        newOptions[len+1] = StandardCopyOption.COPY_ATTRIBUTES;
+        return newOptions;
+    }
+
+    /**
+     * Simple copy for use when source and target are associated with different
+     * providers
+     */
+    static void copyToForeignTarget(Path source, Path target,
+                                    CopyOption... options)
+        throws IOException
+    {
+        CopyOptions opts = CopyOptions.parse(options);
+        LinkOption[] linkOptions = (opts.followLinks) ? new LinkOption[0] :
+            new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
+
+        // attributes of source file
+        BasicFileAttributes attrs = Files.readAttributes(source,
+                                                         BasicFileAttributes.class,
+                                                         linkOptions);
+        if (attrs.isSymbolicLink())
+            throw new IOException("Copying of symbolic links not supported");
+
+        // delete target if it exists and REPLACE_EXISTING is specified
+        if (opts.replaceExisting) {
+            Files.deleteIfExists(target);
+        } else if (Files.exists(target))
+            throw new FileAlreadyExistsException(target.toString());
+
+        // create directory or copy file
+        if (attrs.isDirectory()) {
+            Files.createDirectory(target);
+        } else {
+            try (InputStream in = Files.newInputStream(source)) {
+                Files.copy(in, target);
+            }
+        }
+
+        // copy basic attributes to target
+        if (opts.copyAttributes) {
+            BasicFileAttributeView view =
+                Files.getFileAttributeView(target, BasicFileAttributeView.class);
+            try {
+                view.setTimes(attrs.lastModifiedTime(),
+                              attrs.lastAccessTime(),
+                              attrs.creationTime());
+            } catch (Throwable x) {
+                // rollback
+                try {
+                    Files.delete(target);
+                } catch (Throwable suppressed) {
+                    x.addSuppressed(suppressed);
+                }
+                throw x;
+            }
+        }
+    }
+
+    /**
+     * Simple move implements as copy+delete for use when source and target are
+     * associated with different providers
+     */
+    static void moveToForeignTarget(Path source, Path target,
+                                    CopyOption... options) throws IOException
+    {
+        copyToForeignTarget(source, target, convertMoveToCopyOptions(options));
+        Files.delete(source);
+    }
+}
diff --git a/java/nio/file/CopyOption.java b/java/nio/file/CopyOption.java
new file mode 100644
index 0000000..e70bf95
--- /dev/null
+++ b/java/nio/file/CopyOption.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+/**
+ * An object that configures how to copy or move a file.
+ *
+ * <p> Objects of this type may be used with the {@link
+ * Files#copy(Path,Path,CopyOption[]) Files.copy(Path,Path,CopyOption...)},
+ * {@link Files#copy(java.io.InputStream,Path,CopyOption[])
+ * Files.copy(InputStream,Path,CopyOption...)} and {@link Files#move
+ * Files.move(Path,Path,CopyOption...)} methods to configure how a file is
+ * copied or moved.
+ *
+ * <p> The {@link StandardCopyOption} enumeration type defines the
+ * <i>standard</i> options.
+ *
+ * @since 1.7
+ */
+
+public interface CopyOption {
+}
diff --git a/java/nio/file/DirectoryIteratorException.java b/java/nio/file/DirectoryIteratorException.java
new file mode 100644
index 0000000..4f5a551
--- /dev/null
+++ b/java/nio/file/DirectoryIteratorException.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+import java.util.ConcurrentModificationException;
+import java.util.Objects;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.InvalidObjectException;
+
+/**
+ * Runtime exception thrown if an I/O error is encountered when iterating over
+ * the entries in a directory. The I/O error is retrieved as an {@link
+ * IOException} using the {@link #getCause() getCause()} method.
+ *
+ * @since 1.7
+ * @see DirectoryStream
+ */
+
+public final class DirectoryIteratorException
+    extends ConcurrentModificationException
+{
+    private static final long serialVersionUID = -6012699886086212874L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   cause
+     *          the {@code IOException} that caused the directory iteration
+     *          to fail
+     *
+     * @throws  NullPointerException
+     *          if the cause is {@code null}
+     */
+    public DirectoryIteratorException(IOException cause) {
+        super(Objects.requireNonNull(cause));
+    }
+
+    /**
+     * Returns the cause of this exception.
+     *
+     * @return  the cause
+     */
+    @Override
+    public IOException getCause() {
+        return (IOException)super.getCause();
+    }
+
+    /**
+     * Called to read the object from a stream.
+     *
+     * @throws  InvalidObjectException
+     *          if the object is invalid or has a cause that is not
+     *          an {@code IOException}
+     */
+    private void readObject(ObjectInputStream s)
+        throws IOException, ClassNotFoundException
+    {
+        s.defaultReadObject();
+        Throwable cause = super.getCause();
+        if (!(cause instanceof IOException))
+            throw new InvalidObjectException("Cause must be an IOException");
+    }
+}
diff --git a/java/nio/file/DirectoryNotEmptyException.java b/java/nio/file/DirectoryNotEmptyException.java
new file mode 100644
index 0000000..7ae9080
--- /dev/null
+++ b/java/nio/file/DirectoryNotEmptyException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation fails because a
+ * directory is not empty.
+ *
+ * @since 1.7
+ */
+
+public class DirectoryNotEmptyException
+    extends FileSystemException
+{
+    static final long serialVersionUID = 3056667871802779003L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   dir
+     *          a string identifying the directory or {@code null} if not known
+     */
+    public DirectoryNotEmptyException(String dir) {
+        super(dir);
+    }
+}
diff --git a/java/nio/file/DirectoryStream.java b/java/nio/file/DirectoryStream.java
new file mode 100644
index 0000000..48da97e
--- /dev/null
+++ b/java/nio/file/DirectoryStream.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+import java.util.Iterator;
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * An object to iterate over the entries in a directory. A directory stream
+ * allows for the convenient use of the for-each construct to iterate over a
+ * directory.
+ *
+ * <p> <b> While {@code DirectoryStream} extends {@code Iterable}, it is not a
+ * general-purpose {@code Iterable} as it supports only a single {@code
+ * Iterator}; invoking the {@link #iterator iterator} method to obtain a second
+ * or subsequent iterator throws {@code IllegalStateException}. </b>
+ *
+ * <p> An important property of the directory stream's {@code Iterator} is that
+ * its {@link Iterator#hasNext() hasNext} method is guaranteed to read-ahead by
+ * at least one element. If {@code hasNext} method returns {@code true}, and is
+ * followed by a call to the {@code next} method, it is guaranteed that the
+ * {@code next} method will not throw an exception due to an I/O error, or
+ * because the stream has been {@link #close closed}. The {@code Iterator} does
+ * not support the {@link Iterator#remove remove} operation.
+ *
+ * <p> A {@code DirectoryStream} is opened upon creation and is closed by
+ * invoking the {@code close} method. Closing a directory stream releases any
+ * resources associated with the stream. Failure to close the stream may result
+ * in a resource leak. The try-with-resources statement provides a useful
+ * construct to ensure that the stream is closed:
+ * <pre>
+ *   Path dir = ...
+ *   try (DirectoryStream&lt;Path&gt; stream = Files.newDirectoryStream(dir)) {
+ *       for (Path entry: stream) {
+ *           ...
+ *       }
+ *   }
+ * </pre>
+ *
+ * <p> Once a directory stream is closed, then further access to the directory,
+ * using the {@code Iterator}, behaves as if the end of stream has been reached.
+ * Due to read-ahead, the {@code Iterator} may return one or more elements
+ * after the directory stream has been closed. Once these buffered elements
+ * have been read, then subsequent calls to the {@code hasNext} method returns
+ * {@code false}, and subsequent calls to the {@code next} method will throw
+ * {@code NoSuchElementException}.
+ *
+ * <p> A directory stream is not required to be <i>asynchronously closeable</i>.
+ * If a thread is blocked on the directory stream's iterator reading from the
+ * directory, and another thread invokes the {@code close} method, then the
+ * second thread may block until the read operation is complete.
+ *
+ * <p> If an I/O error is encountered when accessing the directory then it
+ * causes the {@code Iterator}'s {@code hasNext} or {@code next} methods to
+ * throw {@link DirectoryIteratorException} with the {@link IOException} as the
+ * cause. As stated above, the {@code hasNext} method is guaranteed to
+ * read-ahead by at least one element. This means that if {@code hasNext} method
+ * returns {@code true}, and is followed by a call to the {@code next} method,
+ * then it is guaranteed that the {@code next} method will not fail with a
+ * {@code DirectoryIteratorException}.
+ *
+ * <p> The elements returned by the iterator are in no specific order. Some file
+ * systems maintain special links to the directory itself and the directory's
+ * parent directory. Entries representing these links are not returned by the
+ * iterator.
+ *
+ * <p> The iterator is <i>weakly consistent</i>. It is thread safe but does not
+ * freeze the directory while iterating, so it may (or may not) reflect updates
+ * to the directory that occur after the {@code DirectoryStream} is created.
+ *
+ * <p> <b>Usage Examples:</b>
+ * Suppose we want a list of the source files in a directory. This example uses
+ * both the for-each and try-with-resources constructs.
+ * <pre>
+ *   List&lt;Path&gt; listSourceFiles(Path dir) throws IOException {
+ *       List&lt;Path&gt; result = new ArrayList&lt;&gt;();
+ *       try (DirectoryStream&lt;Path&gt; stream = Files.newDirectoryStream(dir, "*.{c,h,cpp,hpp,java}")) {
+ *           for (Path entry: stream) {
+ *               result.add(entry);
+ *           }
+ *       } catch (DirectoryIteratorException ex) {
+ *           // I/O error encounted during the iteration, the cause is an IOException
+ *           throw ex.getCause();
+ *       }
+ *       return result;
+ *   }
+ * </pre>
+ * @param   <T>     The type of element returned by the iterator
+ *
+ * @since 1.7
+ *
+ * @see Files#newDirectoryStream(Path)
+ */
+
+public interface DirectoryStream<T>
+    extends Closeable, Iterable<T> {
+    /**
+     * An interface that is implemented by objects that decide if a directory
+     * entry should be accepted or filtered. A {@code Filter} is passed as the
+     * parameter to the {@link Files#newDirectoryStream(Path,DirectoryStream.Filter)}
+     * method when opening a directory to iterate over the entries in the
+     * directory.
+     *
+     * @param   <T>     the type of the directory entry
+     *
+     * @since 1.7
+     */
+    @FunctionalInterface
+    public static interface Filter<T> {
+        /**
+         * Decides if the given directory entry should be accepted or filtered.
+         *
+         * @param   entry
+         *          the directory entry to be tested
+         *
+         * @return  {@code true} if the directory entry should be accepted
+         *
+         * @throws  IOException
+         *          If an I/O error occurs
+         */
+        boolean accept(T entry) throws IOException;
+    }
+
+    /**
+     * Returns the iterator associated with this {@code DirectoryStream}.
+     *
+     * @return  the iterator associated with this {@code DirectoryStream}
+     *
+     * @throws  IllegalStateException
+     *          if this directory stream is closed or the iterator has already
+     *          been returned
+     */
+    @Override
+    Iterator<T> iterator();
+}
diff --git a/java/nio/file/FileAlreadyExistsException.java b/java/nio/file/FileAlreadyExistsException.java
new file mode 100644
index 0000000..14496a1
--- /dev/null
+++ b/java/nio/file/FileAlreadyExistsException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Checked exception thrown when an attempt is made to create a file or
+ * directory and a file of that name already exists.
+ *
+ * @since 1.7
+ */
+
+public class FileAlreadyExistsException
+    extends FileSystemException
+{
+    static final long serialVersionUID = 7579540934498831181L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     */
+    public FileAlreadyExistsException(String file) {
+        super(file);
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     * @param   other
+     *          a string identifying the other file or {@code null} if not known
+     * @param   reason
+     *          a reason message with additional information or {@code null}
+     */
+    public FileAlreadyExistsException(String file, String other, String reason) {
+        super(file, other, reason);
+    }
+}
diff --git a/java/nio/file/FileStore.java b/java/nio/file/FileStore.java
new file mode 100644
index 0000000..2b14a4b
--- /dev/null
+++ b/java/nio/file/FileStore.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+import java.nio.file.attribute.*;
+import java.io.IOException;
+
+/**
+ * Storage for files. A {@code FileStore} represents a storage pool, device,
+ * partition, volume, concrete file system or other implementation specific means
+ * of file storage. The {@code FileStore} for where a file is stored is obtained
+ * by invoking the {@link Files#getFileStore getFileStore} method, or all file
+ * stores can be enumerated by invoking the {@link FileSystem#getFileStores
+ * getFileStores} method.
+ *
+ * <p> In addition to the methods defined by this class, a file store may support
+ * one or more {@link FileStoreAttributeView FileStoreAttributeView} classes
+ * that provide a read-only or updatable view of a set of file store attributes.
+ *
+ * @since 1.7
+ */
+
+public abstract class FileStore {
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected FileStore() {
+    }
+
+    /**
+     * Returns the name of this file store. The format of the name is highly
+     * implementation specific. It will typically be the name of the storage
+     * pool or volume.
+     *
+     * <p> The string returned by this method may differ from the string
+     * returned by the {@link Object#toString() toString} method.
+     *
+     * @return  the name of this file store
+     */
+    public abstract String name();
+
+    /**
+     * Returns the <em>type</em> of this file store. The format of the string
+     * returned by this method is highly implementation specific. It may
+     * indicate, for example, the format used or if the file store is local
+     * or remote.
+     *
+     * @return  a string representing the type of this file store
+     */
+    public abstract String type();
+
+    /**
+     * Tells whether this file store is read-only. A file store is read-only if
+     * it does not support write operations or other changes to files. Any
+     * attempt to create a file, open an existing file for writing etc. causes
+     * an {@code IOException} to be thrown.
+     *
+     * @return  {@code true} if, and only if, this file store is read-only
+     */
+    public abstract boolean isReadOnly();
+
+    /**
+     * Returns the size, in bytes, of the file store.
+     *
+     * @return  the size of the file store, in bytes
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    public abstract long getTotalSpace() throws IOException;
+
+    /**
+     * Returns the number of bytes available to this Java virtual machine on the
+     * file store.
+     *
+     * <p> The returned number of available bytes is a hint, but not a
+     * guarantee, that it is possible to use most or any of these bytes.  The
+     * number of usable bytes is most likely to be accurate immediately
+     * after the space attributes are obtained. It is likely to be made inaccurate
+     * by any external I/O operations including those made on the system outside
+     * of this Java virtual machine.
+     *
+     * @return  the number of bytes available
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    public abstract long getUsableSpace() throws IOException;
+
+    /**
+     * Returns the number of unallocated bytes in the file store.
+     *
+     * <p> The returned number of unallocated bytes is a hint, but not a
+     * guarantee, that it is possible to use most or any of these bytes.  The
+     * number of unallocated bytes is most likely to be accurate immediately
+     * after the space attributes are obtained. It is likely to be
+     * made inaccurate by any external I/O operations including those made on
+     * the system outside of this virtual machine.
+     *
+     * @return  the number of unallocated bytes
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    public abstract long getUnallocatedSpace() throws IOException;
+
+    /**
+     * Tells whether or not this file store supports the file attributes
+     * identified by the given file attribute view.
+     *
+     * <p> Invoking this method to test if the file store supports {@link
+     * BasicFileAttributeView} will always return {@code true}. In the case of
+     * the default provider, this method cannot guarantee to give the correct
+     * result when the file store is not a local storage device. The reasons for
+     * this are implementation specific and therefore unspecified.
+     *
+     * @param   type
+     *          the file attribute view type
+     *
+     * @return  {@code true} if, and only if, the file attribute view is
+     *          supported
+     */
+    public abstract boolean supportsFileAttributeView(Class<? extends FileAttributeView> type);
+
+    /**
+     * Tells whether or not this file store supports the file attributes
+     * identified by the given file attribute view.
+     *
+     * <p> Invoking this method to test if the file store supports {@link
+     * BasicFileAttributeView}, identified by the name "{@code basic}" will
+     * always return {@code true}. In the case of the default provider, this
+     * method cannot guarantee to give the correct result when the file store is
+     * not a local storage device. The reasons for this are implementation
+     * specific and therefore unspecified.
+     *
+     * @param   name
+     *          the {@link FileAttributeView#name name} of file attribute view
+     *
+     * @return  {@code true} if, and only if, the file attribute view is
+     *          supported
+     */
+    public abstract boolean supportsFileAttributeView(String name);
+
+    /**
+     * Returns a {@code FileStoreAttributeView} of the given type.
+     *
+     * <p> This method is intended to be used where the file store attribute
+     * view defines type-safe methods to read or update the file store attributes.
+     * The {@code type} parameter is the type of the attribute view required and
+     * the method returns an instance of that type if supported.
+     *
+     * @param   <V>
+     *          The {@code FileStoreAttributeView} type
+     * @param   type
+     *          the {@code Class} object corresponding to the attribute view
+     *
+     * @return  a file store attribute view of the specified type or
+     *          {@code null} if the attribute view is not available
+     */
+    public abstract <V extends FileStoreAttributeView> V
+        getFileStoreAttributeView(Class<V> type);
+
+    /**
+     * Reads the value of a file store attribute.
+     *
+     * <p> The {@code attribute} parameter identifies the attribute to be read
+     * and takes the form:
+     * <blockquote>
+     * <i>view-name</i><b>:</b><i>attribute-name</i>
+     * </blockquote>
+     * where the character {@code ':'} stands for itself.
+     *
+     * <p> <i>view-name</i> is the {@link FileStoreAttributeView#name name} of
+     * a {@link FileStore AttributeView} that identifies a set of file attributes.
+     * <i>attribute-name</i> is the name of the attribute.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to know if ZFS compression is enabled (assuming the "zfs"
+     * view is supported):
+     * <pre>
+     *    boolean compression = (Boolean)fs.getAttribute("zfs:compression");
+     * </pre>
+     *
+     * @param   attribute
+     *          the attribute to read
+
+     * @return  the attribute value; {@code null} may be a valid valid for some
+     *          attributes
+     *
+     * @throws  UnsupportedOperationException
+     *          if the attribute view is not available or it does not support
+     *          reading the attribute
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    public abstract Object getAttribute(String attribute) throws IOException;
+}
diff --git a/java/nio/file/FileSystem.java b/java/nio/file/FileSystem.java
new file mode 100644
index 0000000..755d64f
--- /dev/null
+++ b/java/nio/file/FileSystem.java
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.util.Set;
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * Provides an interface to a file system and is the factory for objects to
+ * access files and other objects in the file system.
+ *
+ * <p> The default file system, obtained by invoking the {@link FileSystems#getDefault
+ * FileSystems.getDefault} method, provides access to the file system that is
+ * accessible to the Java virtual machine. The {@link FileSystems} class defines
+ * methods to create file systems that provide access to other types of (custom)
+ * file systems.
+ *
+ * <p> A file system is the factory for several types of objects:
+ *
+ * <ul>
+ *   <li><p> The {@link #getPath getPath} method converts a system dependent
+ *     <em>path string</em>, returning a {@link Path} object that may be used
+ *     to locate and access a file. </p></li>
+ *   <li><p> The {@link #getPathMatcher  getPathMatcher} method is used
+ *     to create a {@link PathMatcher} that performs match operations on
+ *     paths. </p></li>
+ *   <li><p> The {@link #getFileStores getFileStores} method returns an iterator
+ *     over the underlying {@link FileStore file-stores}. </p></li>
+ *   <li><p> The {@link #getUserPrincipalLookupService getUserPrincipalLookupService}
+ *     method returns the {@link UserPrincipalLookupService} to lookup users or
+ *     groups by name. </p></li>
+ *   <li><p> The {@link #newWatchService newWatchService} method creates a
+ *     {@link WatchService} that may be used to watch objects for changes and
+ *     events. </p></li>
+ * </ul>
+ *
+ * <p> File systems vary greatly. In some cases the file system is a single
+ * hierarchy of files with one top-level root directory. In other cases it may
+ * have several distinct file hierarchies, each with its own top-level root
+ * directory. The {@link #getRootDirectories getRootDirectories} method may be
+ * used to iterate over the root directories in the file system. A file system
+ * is typically composed of one or more underlying {@link FileStore file-stores}
+ * that provide the storage for the files. Theses file stores can also vary in
+ * the features they support, and the file attributes or <em>meta-data</em> that
+ * they associate with files.
+ *
+ * <p> A file system is open upon creation and can be closed by invoking its
+ * {@link #close() close} method. Once closed, any further attempt to access
+ * objects in the file system cause {@link ClosedFileSystemException} to be
+ * thrown. File systems created by the default {@link FileSystemProvider provider}
+ * cannot be closed.
+ *
+ * <p> A {@code FileSystem} can provide read-only or read-write access to the
+ * file system. Whether or not a file system provides read-only access is
+ * established when the {@code FileSystem} is created and can be tested by invoking
+ * its {@link #isReadOnly() isReadOnly} method. Attempts to write to file stores
+ * by means of an object associated with a read-only file system throws {@link
+ * ReadOnlyFileSystemException}.
+ *
+ * <p> File systems are safe for use by multiple concurrent threads. The {@link
+ * #close close} method may be invoked at any time to close a file system but
+ * whether a file system is <i>asynchronously closeable</i> is provider specific
+ * and therefore unspecified. In other words, if a thread is accessing an
+ * object in a file system, and another thread invokes the {@code close} method
+ * then it may require to block until the first operation is complete. Closing
+ * a file system causes all open channels, watch services, and other {@link
+ * Closeable closeable} objects associated with the file system to be closed.
+ *
+ * @since 1.7
+ */
+
+public abstract class FileSystem
+    implements Closeable
+{
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected FileSystem() {
+    }
+
+    /**
+     * Returns the provider that created this file system.
+     *
+     * @return  The provider that created this file system.
+     */
+    public abstract FileSystemProvider provider();
+
+    /**
+     * Closes this file system.
+     *
+     * <p> After a file system is closed then all subsequent access to the file
+     * system, either by methods defined by this class or on objects associated
+     * with this file system, throw {@link ClosedFileSystemException}. If the
+     * file system is already closed then invoking this method has no effect.
+     *
+     * <p> Closing a file system will close all open {@link
+     * java.nio.channels.Channel channels}, {@link DirectoryStream directory-streams},
+     * {@link WatchService watch-service}, and other closeable objects associated
+     * with this file system. The {@link FileSystems#getDefault default} file
+     * system cannot be closed.
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  UnsupportedOperationException
+     *          Thrown in the case of the default file system
+     */
+    @Override
+    public abstract void close() throws IOException;
+
+    /**
+     * Tells whether or not this file system is open.
+     *
+     * <p> File systems created by the default provider are always open.
+     *
+     * @return  {@code true} if, and only if, this file system is open
+     */
+    public abstract boolean isOpen();
+
+    /**
+     * Tells whether or not this file system allows only read-only access to
+     * its file stores.
+     *
+     * @return  {@code true} if, and only if, this file system provides
+     *          read-only access
+     */
+    public abstract boolean isReadOnly();
+
+    /**
+     * Returns the name separator, represented as a string.
+     *
+     * <p> The name separator is used to separate names in a path string. An
+     * implementation may support multiple name separators in which case this
+     * method returns an implementation specific <em>default</em> name separator.
+     * This separator is used when creating path strings by invoking the {@link
+     * Path#toString() toString()} method.
+     *
+     * <p> In the case of the default provider, this method returns the same
+     * separator as {@link java.io.File#separator}.
+     *
+     * @return  The name separator
+     */
+    public abstract String getSeparator();
+
+    /**
+     * Returns an object to iterate over the paths of the root directories.
+     *
+     * <p> A file system provides access to a file store that may be composed
+     * of a number of distinct file hierarchies, each with its own top-level
+     * root directory. Unless denied by the security manager, each element in
+     * the returned iterator corresponds to the root directory of a distinct
+     * file hierarchy. The order of the elements is not defined. The file
+     * hierarchies may change during the lifetime of the Java virtual machine.
+     * For example, in some implementations, the insertion of removable media
+     * may result in the creation of a new file hierarchy with its own
+     * top-level directory.
+     *
+     * <p> When a security manager is installed, it is invoked to check access
+     * to the each root directory. If denied, the root directory is not returned
+     * by the iterator. In the case of the default provider, the {@link
+     * SecurityManager#checkRead(String)} method is invoked to check read access
+     * to each root directory. It is system dependent if the permission checks
+     * are done when the iterator is obtained or during iteration.
+     *
+     * @return  An object to iterate over the root directories
+     */
+    public abstract Iterable<Path> getRootDirectories();
+
+    /**
+     * Returns an object to iterate over the underlying file stores.
+     *
+     * <p> The elements of the returned iterator are the {@link
+     * FileStore FileStores} for this file system. The order of the elements is
+     * not defined and the file stores may change during the lifetime of the
+     * Java virtual machine. When an I/O error occurs, perhaps because a file
+     * store is not accessible, then it is not returned by the iterator.
+     *
+     * <p> In the case of the default provider, and a security manager is
+     * installed, the security manager is invoked to check {@link
+     * RuntimePermission}<tt>("getFileStoreAttributes")</tt>. If denied, then
+     * no file stores are returned by the iterator. In addition, the security
+     * manager's {@link SecurityManager#checkRead(String)} method is invoked to
+     * check read access to the file store's <em>top-most</em> directory. If
+     * denied, the file store is not returned by the iterator. It is system
+     * dependent if the permission checks are done when the iterator is obtained
+     * or during iteration.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to print the space usage for all file stores:
+     * <pre>
+     *     for (FileStore store: FileSystems.getDefault().getFileStores()) {
+     *         long total = store.getTotalSpace() / 1024;
+     *         long used = (store.getTotalSpace() - store.getUnallocatedSpace()) / 1024;
+     *         long avail = store.getUsableSpace() / 1024;
+     *         System.out.format("%-20s %12d %12d %12d%n", store, total, used, avail);
+     *     }
+     * </pre>
+     *
+     * @return  An object to iterate over the backing file stores
+     */
+    public abstract Iterable<FileStore> getFileStores();
+
+    /**
+     * Returns the set of the {@link FileAttributeView#name names} of the file
+     * attribute views supported by this {@code FileSystem}.
+     *
+     * <p> The {@link BasicFileAttributeView} is required to be supported and
+     * therefore the set contains at least one element, "basic".
+     *
+     * <p> The {@link FileStore#supportsFileAttributeView(String)
+     * supportsFileAttributeView(String)} method may be used to test if an
+     * underlying {@link FileStore} supports the file attributes identified by a
+     * file attribute view.
+     *
+     * @return  An unmodifiable set of the names of the supported file attribute
+     *          views
+     */
+    public abstract Set<String> supportedFileAttributeViews();
+
+    /**
+     * Converts a path string, or a sequence of strings that when joined form
+     * a path string, to a {@code Path}. If {@code more} does not specify any
+     * elements then the value of the {@code first} parameter is the path string
+     * to convert. If {@code more} specifies one or more elements then each
+     * non-empty string, including {@code first}, is considered to be a sequence
+     * of name elements (see {@link Path}) and is joined to form a path string.
+     * The details as to how the Strings are joined is provider specific but
+     * typically they will be joined using the {@link #getSeparator
+     * name-separator} as the separator. For example, if the name separator is
+     * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the
+     * path string {@code "/foo/bar/gus"} is converted to a {@code Path}.
+     * A {@code Path} representing an empty path is returned if {@code first}
+     * is the empty string and {@code more} does not contain any non-empty
+     * strings.
+     *
+     * <p> The parsing and conversion to a path object is inherently
+     * implementation dependent. In the simplest case, the path string is rejected,
+     * and {@link InvalidPathException} thrown, if the path string contains
+     * characters that cannot be converted to characters that are <em>legal</em>
+     * to the file store. For example, on UNIX systems, the NUL (&#92;u0000)
+     * character is not allowed to be present in a path. An implementation may
+     * choose to reject path strings that contain names that are longer than those
+     * allowed by any file store, and where an implementation supports a complex
+     * path syntax, it may choose to reject path strings that are <em>badly
+     * formed</em>.
+     *
+     * <p> In the case of the default provider, path strings are parsed based
+     * on the definition of paths at the platform or virtual file system level.
+     * For example, an operating system may not allow specific characters to be
+     * present in a file name, but a specific underlying file store may impose
+     * different or additional restrictions on the set of legal
+     * characters.
+     *
+     * <p> This method throws {@link InvalidPathException} when the path string
+     * cannot be converted to a path. Where possible, and where applicable,
+     * the exception is created with an {@link InvalidPathException#getIndex
+     * index} value indicating the first position in the {@code path} parameter
+     * that caused the path string to be rejected.
+     *
+     * @param   first
+     *          the path string or initial part of the path string
+     * @param   more
+     *          additional strings to be joined to form the path string
+     *
+     * @return  the resulting {@code Path}
+     *
+     * @throws  InvalidPathException
+     *          If the path string cannot be converted
+     */
+    public abstract Path getPath(String first, String... more);
+
+    // Android-changed: Removed javadoc references to UNIX and Windows.
+    /**
+     * Returns a {@code PathMatcher} that performs match operations on the
+     * {@code String} representation of {@link Path} objects by interpreting a
+     * given pattern.
+     *
+     * The {@code syntaxAndPattern} parameter identifies the syntax and the
+     * pattern and takes the form:
+     * <blockquote><pre>
+     * <i>syntax</i><b>:</b><i>pattern</i>
+     * </pre></blockquote>
+     * where {@code ':'} stands for itself.
+     *
+     * <p> A {@code FileSystem} implementation supports the "{@code glob}" and
+     * "{@code regex}" syntaxes, and may support others. The value of the syntax
+     * component is compared without regard to case.
+     *
+     * <p> When the syntax is "{@code glob}" then the {@code String}
+     * representation of the path is matched using a limited pattern language
+     * that resembles regular expressions but with a simpler syntax. For example:
+     *
+     * <blockquote>
+     * <table border="0" summary="Pattern Language">
+     * <tr>
+     *   <td>{@code *.java}</td>
+     *   <td>Matches a path that represents a file name ending in {@code .java}</td>
+     * </tr>
+     * <tr>
+     *   <td>{@code *.*}</td>
+     *   <td>Matches file names containing a dot</td>
+     * </tr>
+     * <tr>
+     *   <td>{@code *.{java,class}}</td>
+     *   <td>Matches file names ending with {@code .java} or {@code .class}</td>
+     * </tr>
+     * <tr>
+     *   <td>{@code foo.?}</td>
+     *   <td>Matches file names starting with {@code foo.} and a single
+     *   character extension</td>
+     * </tr>
+     * <tr>
+     *   <td><tt>&#47;home&#47;*&#47;*</tt>
+     *   <td>Matches <tt>&#47;home&#47;gus&#47;data</tt></td>
+     * </tr>
+     * <tr>
+     *   <td><tt>&#47;home&#47;**</tt>
+     *   <td>Matches <tt>&#47;home&#47;gus</tt> and
+     *   <tt>&#47;home&#47;gus&#47;data</tt></td>
+     * </tr>
+     *
+     * </table>
+     * </blockquote>
+     *
+     * <p> The following rules are used to interpret glob patterns:
+     *
+     * <ul>
+     *   <li><p> The {@code *} character matches zero or more {@link Character
+     *   characters} of a {@link Path#getName(int) name} component without
+     *   crossing directory boundaries. </p></li>
+     *
+     *   <li><p> The {@code **} characters matches zero or more {@link Character
+     *   characters} crossing directory boundaries. </p></li>
+     *
+     *   <li><p> The {@code ?} character matches exactly one character of a
+     *   name component.</p></li>
+     *
+     *   <li><p> The backslash character ({@code \}) is used to escape characters
+     *   that would otherwise be interpreted as special characters. The expression
+     *   {@code \\} matches a single backslash and "\{" matches a left brace
+     *   for example.  </p></li>
+     *
+     *   <li><p> The {@code [ ]} characters are a <i>bracket expression</i> that
+     *   match a single character of a name component out of a set of characters.
+     *   For example, {@code [abc]} matches {@code "a"}, {@code "b"}, or {@code "c"}.
+     *   The hyphen ({@code -}) may be used to specify a range so {@code [a-z]}
+     *   specifies a range that matches from {@code "a"} to {@code "z"} (inclusive).
+     *   These forms can be mixed so [abce-g] matches {@code "a"}, {@code "b"},
+     *   {@code "c"}, {@code "e"}, {@code "f"} or {@code "g"}. If the character
+     *   after the {@code [} is a {@code !} then it is used for negation so {@code
+     *   [!a-c]} matches any character except {@code "a"}, {@code "b"}, or {@code
+     *   "c"}.
+     *   <p> Within a bracket expression the {@code *}, {@code ?} and {@code \}
+     *   characters match themselves. The ({@code -}) character matches itself if
+     *   it is the first character within the brackets, or the first character
+     *   after the {@code !} if negating.</p></li>
+     *
+     *   <li><p> The {@code { }} characters are a group of subpatterns, where
+     *   the group matches if any subpattern in the group matches. The {@code ","}
+     *   character is used to separate the subpatterns. Groups cannot be nested.
+     *   </p></li>
+     *
+     *   <li><p> Leading period<tt>&#47;</tt>dot characters in file name are
+     *   treated as regular characters in match operations. For example,
+     *   the {@code "*"} glob pattern matches file name {@code ".login"}.
+     *   The {@link Files#isHidden} method may be used to test whether a file
+     *   is considered hidden.
+     *   </p></li>
+     *
+     *   <li><p> All other characters match themselves in an implementation
+     *   dependent manner. This includes characters representing any {@link
+     *   FileSystem#getSeparator name-separators}. </p></li>
+     *
+     *   <li><p> The matching of {@link Path#getRoot root} components is highly
+     *   implementation-dependent and is not specified. </p></li>
+     *
+     * </ul>
+     *
+     * <p> When the syntax is "{@code regex}" then the pattern component is a
+     * regular expression as defined by the {@link java.util.regex.Pattern}
+     * class.
+     *
+     * <p>  For both the glob and regex syntaxes, the matching details, such as
+     * whether the matching is case sensitive, are implementation-dependent
+     * and therefore not specified.
+     *
+     * @param   syntaxAndPattern
+     *          The syntax and pattern
+     *
+     * @return  A path matcher that may be used to match paths against the pattern
+     *
+     * @throws  IllegalArgumentException
+     *          If the parameter does not take the form: {@code syntax:pattern}
+     * @throws  java.util.regex.PatternSyntaxException
+     *          If the pattern is invalid
+     * @throws  UnsupportedOperationException
+     *          If the pattern syntax is not known to the implementation
+     *
+     * @see Files#newDirectoryStream(Path,String)
+     */
+    public abstract PathMatcher getPathMatcher(String syntaxAndPattern);
+
+    /**
+     * Returns the {@code UserPrincipalLookupService} for this file system
+     * <i>(optional operation)</i>. The resulting lookup service may be used to
+     * lookup user or group names.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to make "joe" the owner of a file:
+     * <pre>
+     *     UserPrincipalLookupService lookupService = FileSystems.getDefault().getUserPrincipalLookupService();
+     *     Files.setOwner(path, lookupService.lookupPrincipalByName("joe"));
+     * </pre>
+     *
+     * @throws  UnsupportedOperationException
+     *          If this {@code FileSystem} does not does have a lookup service
+     *
+     * @return  The {@code UserPrincipalLookupService} for this file system
+     */
+    public abstract UserPrincipalLookupService getUserPrincipalLookupService();
+
+    /**
+     * Constructs a new {@link WatchService} <i>(optional operation)</i>.
+     *
+     * <p> This method constructs a new watch service that may be used to watch
+     * registered objects for changes and events.
+     *
+     * @return  a new watch service
+     *
+     * @throws  UnsupportedOperationException
+     *          If this {@code FileSystem} does not support watching file system
+     *          objects for changes and events. This exception is not thrown
+     *          by {@code FileSystems} created by the default provider.
+     * @throws  IOException
+     *          If an I/O error occurs
+     */
+    public abstract WatchService newWatchService() throws IOException;
+}
diff --git a/java/nio/file/FileSystemAlreadyExistsException.java b/java/nio/file/FileSystemAlreadyExistsException.java
new file mode 100644
index 0000000..e305542
--- /dev/null
+++ b/java/nio/file/FileSystemAlreadyExistsException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Runtime exception thrown when an attempt is made to create a file system that
+ * already exists.
+ */
+
+public class FileSystemAlreadyExistsException
+    extends RuntimeException
+{
+    static final long serialVersionUID = -5438419127181131148L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public FileSystemAlreadyExistsException() {
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   msg
+     *          the detail message
+     */
+    public FileSystemAlreadyExistsException(String msg) {
+        super(msg);
+    }
+}
diff --git a/java/nio/file/FileSystemException.java b/java/nio/file/FileSystemException.java
new file mode 100644
index 0000000..b130584
--- /dev/null
+++ b/java/nio/file/FileSystemException.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+import java.io.IOException;
+
+/**
+ * Thrown when a file system operation fails on one or two files. This class is
+ * the general class for file system exceptions.
+ *
+ * @since 1.7
+ */
+
+public class FileSystemException
+    extends IOException
+{
+    static final long serialVersionUID = -3055425747967319812L;
+
+    private final String file;
+    private final String other;
+
+    /**
+     * Constructs an instance of this class. This constructor should be used
+     * when an operation involving one file fails and there isn't any additional
+     * information to explain the reason.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known.
+     */
+    public FileSystemException(String file) {
+        super((String)null);
+        this.file = file;
+        this.other = null;
+    }
+
+    /**
+     * Constructs an instance of this class. This constructor should be used
+     * when an operation involving two files fails, or there is additional
+     * information to explain the reason.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known.
+     * @param   other
+     *          a string identifying the other file or {@code null} if there
+     *          isn't another file or if not known
+     * @param   reason
+     *          a reason message with additional information or {@code null}
+     */
+    public FileSystemException(String file, String other, String reason) {
+        super(reason);
+        this.file = file;
+        this.other = other;
+    }
+
+    /**
+     * Returns the file used to create this exception.
+     *
+     * @return  the file (can be {@code null})
+     */
+    public String getFile() {
+        return file;
+    }
+
+    /**
+     * Returns the other file used to create this exception.
+     *
+     * @return  the other file (can be {@code null})
+     */
+    public String getOtherFile() {
+        return other;
+    }
+
+    /**
+     * Returns the string explaining why the file system operation failed.
+     *
+     * @return  the string explaining why the file system operation failed
+     */
+    public String getReason() {
+        return super.getMessage();
+    }
+
+    /**
+     * Returns the detail message string.
+     */
+    @Override
+    public String getMessage() {
+        if (file == null && other == null)
+            return getReason();
+        StringBuilder sb = new StringBuilder();
+        if (file != null)
+            sb.append(file);
+        if (other != null) {
+            sb.append(" -> ");
+            sb.append(other);
+        }
+        if (getReason() != null) {
+            sb.append(": ");
+            sb.append(getReason());
+        }
+        return sb.toString();
+    }
+}
diff --git a/java/nio/file/FileSystemLoopException.java b/java/nio/file/FileSystemLoopException.java
new file mode 100644
index 0000000..fe6beb5
--- /dev/null
+++ b/java/nio/file/FileSystemLoopException.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Checked exception thrown when a file system loop, or cycle, is encountered.
+ *
+ * @since 1.7
+ * @see Files#walkFileTree
+ */
+
+public class FileSystemLoopException
+    extends FileSystemException
+{
+    private static final long serialVersionUID = 4843039591949217617L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file causing the cycle or {@code null} if
+     *          not known
+     */
+    public FileSystemLoopException(String file) {
+        super(file);
+    }
+}
diff --git a/java/nio/file/FileSystemNotFoundException.java b/java/nio/file/FileSystemNotFoundException.java
new file mode 100644
index 0000000..1c0ee4c
--- /dev/null
+++ b/java/nio/file/FileSystemNotFoundException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Runtime exception thrown when a file system cannot be found.
+ */
+
+public class FileSystemNotFoundException
+    extends RuntimeException
+{
+    static final long serialVersionUID = 7999581764446402397L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public FileSystemNotFoundException() {
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   msg
+     *          the detail message
+     */
+    public FileSystemNotFoundException(String msg) {
+        super(msg);
+    }
+}
diff --git a/java/nio/file/FileSystems.java b/java/nio/file/FileSystems.java
new file mode 100644
index 0000000..a38aaae
--- /dev/null
+++ b/java/nio/file/FileSystems.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+import java.nio.file.spi.FileSystemProvider;
+import java.net.URI;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.*;
+import java.lang.reflect.Constructor;
+
+/**
+ * Factory methods for file systems. This class defines the {@link #getDefault
+ * getDefault} method to get the default file system and factory methods to
+ * construct other types of file systems.
+ *
+ * <p> The first invocation of any of the methods defined by this class causes
+ * the default {@link FileSystemProvider provider} to be loaded. The default
+ * provider, identified by the URI scheme "file", creates the {@link FileSystem}
+ * that provides access to the file systems accessible to the Java virtual
+ * machine. If the process of loading or initializing the default provider fails
+ * then an unspecified error is thrown.
+ *
+ * <p> The first invocation of the {@link FileSystemProvider#installedProviders
+ * installedProviders} method, by way of invoking any of the {@code
+ * newFileSystem} methods defined by this class, locates and loads all
+ * installed file system providers. Installed providers are loaded using the
+ * service-provider loading facility defined by the {@link ServiceLoader} class.
+ * Installed providers are loaded using the system class loader. If the
+ * system class loader cannot be found then the extension class loader is used;
+ * if there is no extension class loader then the bootstrap class loader is used.
+ * Providers are typically installed by placing them in a JAR file on the
+ * application class path or in the extension directory, the JAR file contains a
+ * provider-configuration file named {@code java.nio.file.spi.FileSystemProvider}
+ * in the resource directory {@code META-INF/services}, and the file lists one or
+ * more fully-qualified names of concrete subclass of {@link FileSystemProvider}
+ * that have a zero argument constructor.
+ * The ordering that installed providers are located is implementation specific.
+ * If a provider is instantiated and its {@link FileSystemProvider#getScheme()
+ * getScheme} returns the same URI scheme of a provider that was previously
+ * instantiated then the most recently instantiated duplicate is discarded. URI
+ * schemes are compared without regard to case. During construction a provider
+ * may safely access files associated with the default provider but care needs
+ * to be taken to avoid circular loading of other installed providers. If
+ * circular loading of installed providers is detected then an unspecified error
+ * is thrown.
+ *
+ * <p> This class also defines factory methods that allow a {@link ClassLoader}
+ * to be specified when locating a provider. As with installed providers, the
+ * provider classes are identified by placing the provider configuration file
+ * in the resource directory {@code META-INF/services}.
+ *
+ * <p> If a thread initiates the loading of the installed file system providers
+ * and another thread invokes a method that also attempts to load the providers
+ * then the method will block until the loading completes.
+ *
+ * @since 1.7
+ */
+
+public final class FileSystems {
+    private FileSystems() {
+    }
+
+    // lazy initialization of default file system
+    private static class DefaultFileSystemHolder {
+        static final FileSystem defaultFileSystem = defaultFileSystem();
+
+        // returns default file system
+        private static FileSystem defaultFileSystem() {
+            // load default provider
+            FileSystemProvider provider = AccessController
+                .doPrivileged(new PrivilegedAction<FileSystemProvider>() {
+                    public FileSystemProvider run() {
+                        return getDefaultProvider();
+                    }
+                });
+
+            // return file system
+            return provider.getFileSystem(URI.create("file:///"));
+        }
+
+        // returns default provider
+        private static FileSystemProvider getDefaultProvider() {
+            FileSystemProvider provider = sun.nio.fs.DefaultFileSystemProvider.create();
+
+            // if the property java.nio.file.spi.DefaultFileSystemProvider is
+            // set then its value is the name of the default provider (or a list)
+            String propValue = System
+                .getProperty("java.nio.file.spi.DefaultFileSystemProvider");
+            if (propValue != null) {
+                for (String cn: propValue.split(",")) {
+                    try {
+                        Class<?> c = Class
+                            .forName(cn, true, ClassLoader.getSystemClassLoader());
+                        Constructor<?> ctor = c
+                            .getDeclaredConstructor(FileSystemProvider.class);
+                        provider = (FileSystemProvider)ctor.newInstance(provider);
+
+                        // must be "file"
+                        if (!provider.getScheme().equals("file"))
+                            throw new Error("Default provider must use scheme 'file'");
+
+                    } catch (Exception x) {
+                        throw new Error(x);
+                    }
+                }
+            }
+            return provider;
+        }
+    }
+
+    /**
+     * Returns the default {@code FileSystem}. The default file system creates
+     * objects that provide access to the file systems accessible to the Java
+     * virtual machine. The <em>working directory</em> of the file system is
+     * the current user directory, named by the system property {@code user.dir}.
+     * This allows for interoperability with the {@link java.io.File java.io.File}
+     * class.
+     *
+     * <p> The first invocation of any of the methods defined by this class
+     * locates the default {@link FileSystemProvider provider} object. Where the
+     * system property {@code java.nio.file.spi.DefaultFileSystemProvider} is
+     * not defined then the default provider is a system-default provider that
+     * is invoked to create the default file system.
+     *
+     * <p> If the system property {@code java.nio.file.spi.DefaultFileSystemProvider}
+     * is defined then it is taken to be a list of one or more fully-qualified
+     * names of concrete provider classes identified by the URI scheme
+     * {@code "file"}. Where the property is a list of more than one name then
+     * the names are separated by a comma. Each class is loaded, using the system
+     * class loader, and instantiated by invoking a one argument constructor
+     * whose formal parameter type is {@code FileSystemProvider}. The providers
+     * are loaded and instantiated in the order they are listed in the property.
+     * If this process fails or a provider's scheme is not equal to {@code "file"}
+     * then an unspecified error is thrown. URI schemes are normally compared
+     * without regard to case but for the default provider, the scheme is
+     * required to be {@code "file"}. The first provider class is instantiated
+     * by invoking it with a reference to the system-default provider.
+     * The second provider class is instantiated by invoking it with a reference
+     * to the first provider instance. The third provider class is instantiated
+     * by invoking it with a reference to the second instance, and so on. The
+     * last provider to be instantiated becomes the default provider; its {@code
+     * getFileSystem} method is invoked with the URI {@code "file:///"} to
+     * get a reference to the default file system.
+     *
+     * <p> Subsequent invocations of this method return the file system that was
+     * returned by the first invocation.
+     *
+     * @return  the default file system
+     */
+    public static FileSystem getDefault() {
+        return DefaultFileSystemHolder.defaultFileSystem;
+    }
+
+    /**
+     * Returns a reference to an existing {@code FileSystem}.
+     *
+     * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+     * installed} providers to locate the provider that is identified by the URI
+     * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
+     * without regard to case. The exact form of the URI is highly provider
+     * dependent. If found, the provider's {@link FileSystemProvider#getFileSystem
+     * getFileSystem} method is invoked to obtain a reference to the {@code
+     * FileSystem}.
+     *
+     * <p> Once a file system created by this provider is {@link FileSystem#close
+     * closed} it is provider-dependent if this method returns a reference to
+     * the closed file system or throws {@link FileSystemNotFoundException}.
+     * If the provider allows a new file system to be created with the same URI
+     * as a file system it previously created then this method throws the
+     * exception if invoked after the file system is closed (and before a new
+     * instance is created by the {@link #newFileSystem newFileSystem} method).
+     *
+     * <p> If a security manager is installed then a provider implementation
+     * may require to check a permission before returning a reference to an
+     * existing file system. In the case of the {@link FileSystems#getDefault
+     * default} file system, no permission check is required.
+     *
+     * @param   uri  the URI to locate the file system
+     *
+     * @return  the reference to the file system
+     *
+     * @throws  IllegalArgumentException
+     *          if the pre-conditions for the {@code uri} parameter are not met
+     * @throws  FileSystemNotFoundException
+     *          if the file system, identified by the URI, does not exist
+     * @throws  ProviderNotFoundException
+     *          if a provider supporting the URI scheme is not installed
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission
+     */
+    public static FileSystem getFileSystem(URI uri) {
+        String scheme = uri.getScheme();
+        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            if (scheme.equalsIgnoreCase(provider.getScheme())) {
+                return provider.getFileSystem(uri);
+            }
+        }
+        throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");
+    }
+
+    /**
+     * Constructs a new file system that is identified by a {@link URI}
+     *
+     * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+     * installed} providers to locate the provider that is identified by the URI
+     * {@link URI#getScheme scheme} of the given URI. URI schemes are compared
+     * without regard to case. The exact form of the URI is highly provider
+     * dependent. If found, the provider's {@link FileSystemProvider#newFileSystem(URI,Map)
+     * newFileSystem(URI,Map)} method is invoked to construct the new file system.
+     *
+     * <p> Once a file system is {@link FileSystem#close closed} it is
+     * provider-dependent if the provider allows a new file system to be created
+     * with the same URI as a file system it previously created.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose there is a provider identified by the scheme {@code "memory"}
+     * installed:
+     * <pre>
+     *   Map&lt;String,String&gt; env = new HashMap&lt;&gt;();
+     *   env.put("capacity", "16G");
+     *   env.put("blockSize", "4k");
+     *   FileSystem fs = FileSystems.newFileSystem(URI.create("memory:///?name=logfs"), env);
+     * </pre>
+     *
+     * @param   uri
+     *          the URI identifying the file system
+     * @param   env
+     *          a map of provider specific properties to configure the file system;
+     *          may be empty
+     *
+     * @return  a new file system
+     *
+     * @throws  IllegalArgumentException
+     *          if the pre-conditions for the {@code uri} parameter are not met,
+     *          or the {@code env} parameter does not contain properties required
+     *          by the provider, or a property value is invalid
+     * @throws  FileSystemAlreadyExistsException
+     *          if the file system has already been created
+     * @throws  ProviderNotFoundException
+     *          if a provider supporting the URI scheme is not installed
+     * @throws  IOException
+     *          if an I/O error occurs creating the file system
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission required by the file system provider implementation
+     */
+    public static FileSystem newFileSystem(URI uri, Map<String,?> env)
+        throws IOException
+    {
+        return newFileSystem(uri, env, null);
+    }
+
+    /**
+     * Constructs a new file system that is identified by a {@link URI}
+     *
+     * <p> This method first attempts to locate an installed provider in exactly
+     * the same manner as the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
+     * method. If none of the installed providers support the URI scheme then an
+     * attempt is made to locate the provider using the given class loader. If a
+     * provider supporting the URI scheme is located then its {@link
+     * FileSystemProvider#newFileSystem(URI,Map) newFileSystem(URI,Map)} is
+     * invoked to construct the new file system.
+     *
+     * @param   uri
+     *          the URI identifying the file system
+     * @param   env
+     *          a map of provider specific properties to configure the file system;
+     *          may be empty
+     * @param   loader
+     *          the class loader to locate the provider or {@code null} to only
+     *          attempt to locate an installed provider
+     *
+     * @return  a new file system
+     *
+     * @throws  IllegalArgumentException
+     *          if the pre-conditions for the {@code uri} parameter are not met,
+     *          or the {@code env} parameter does not contain properties required
+     *          by the provider, or a property value is invalid
+     * @throws  FileSystemAlreadyExistsException
+     *          if the URI scheme identifies an installed provider and the file
+     *          system has already been created
+     * @throws  ProviderNotFoundException
+     *          if a provider supporting the URI scheme is not found
+     * @throws  ServiceConfigurationError
+     *          when an error occurs while loading a service provider
+     * @throws  IOException
+     *          an I/O error occurs creating the file system
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission required by the file system provider implementation
+     */
+    public static FileSystem newFileSystem(URI uri, Map<String,?> env, ClassLoader loader)
+        throws IOException
+    {
+        String scheme = uri.getScheme();
+
+        // check installed providers
+        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            if (scheme.equalsIgnoreCase(provider.getScheme())) {
+                return provider.newFileSystem(uri, env);
+            }
+        }
+
+        // if not found, use service-provider loading facility
+        if (loader != null) {
+            ServiceLoader<FileSystemProvider> sl = ServiceLoader
+                .load(FileSystemProvider.class, loader);
+            for (FileSystemProvider provider: sl) {
+                if (scheme.equalsIgnoreCase(provider.getScheme())) {
+                    return provider.newFileSystem(uri, env);
+                }
+            }
+        }
+
+        throw new ProviderNotFoundException("Provider \"" + scheme + "\" not found");
+    }
+
+    /**
+     * Constructs a new {@code FileSystem} to access the contents of a file as a
+     * file system.
+     *
+     * <p> This method makes use of specialized providers that create pseudo file
+     * systems where the contents of one or more files is treated as a file
+     * system.
+     *
+     * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+     * installed} providers. It invokes, in turn, each provider's {@link
+     * FileSystemProvider#newFileSystem(Path,Map) newFileSystem(Path,Map)} method
+     * with an empty map. If a provider returns a file system then the iteration
+     * terminates and the file system is returned. If none of the installed
+     * providers return a {@code FileSystem} then an attempt is made to locate
+     * the provider using the given class loader. If a provider returns a file
+     * system then the lookup terminates and the file system is returned.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   loader
+     *          the class loader to locate the provider or {@code null} to only
+     *          attempt to locate an installed provider
+     *
+     * @return  a new file system
+     *
+     * @throws  ProviderNotFoundException
+     *          if a provider supporting this file type cannot be located
+     * @throws  ServiceConfigurationError
+     *          when an error occurs while loading a service provider
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission
+     */
+    public static FileSystem newFileSystem(Path path,
+                                           ClassLoader loader)
+        throws IOException
+    {
+        if (path == null)
+            throw new NullPointerException();
+        Map<String,?> env = Collections.emptyMap();
+
+        // check installed providers
+        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            try {
+                return provider.newFileSystem(path, env);
+            } catch (UnsupportedOperationException uoe) {
+            }
+        }
+
+        // if not found, use service-provider loading facility
+        if (loader != null) {
+            ServiceLoader<FileSystemProvider> sl = ServiceLoader
+                .load(FileSystemProvider.class, loader);
+            for (FileSystemProvider provider: sl) {
+                try {
+                    return provider.newFileSystem(path, env);
+                } catch (UnsupportedOperationException uoe) {
+                }
+            }
+        }
+
+        throw new ProviderNotFoundException("Provider not found");
+    }
+}
diff --git a/java/nio/file/FileTreeIterator.java b/java/nio/file/FileTreeIterator.java
new file mode 100644
index 0000000..63b4dc7
--- /dev/null
+++ b/java/nio/file/FileTreeIterator.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.nio.file.FileTreeWalker.Event;
+
+/**
+ * An {@code Iterator to iterate over the nodes of a file tree.
+ *
+ * <pre>{@code
+ *     try (FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options)) {
+ *         while (iterator.hasNext()) {
+ *             Event ev = iterator.next();
+ *             Path path = ev.file();
+ *             BasicFileAttributes attrs = ev.attributes();
+ *         }
+ *     }
+ * }</pre>
+ */
+
+class FileTreeIterator implements Iterator<Event>, Closeable {
+    private final FileTreeWalker walker;
+    private Event next;
+
+    /**
+     * Creates a new iterator to walk the file tree starting at the given file.
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code maxDepth} is negative
+     * @throws  IOException
+     *          if an I/O errors occurs opening the starting file
+     * @throws  SecurityException
+     *          if the security manager denies access to the starting file
+     * @throws  NullPointerException
+     *          if {@code start} or {@code options} is {@ocde null} or
+     *          the options array contains a {@code null} element
+     */
+    FileTreeIterator(Path start, int maxDepth, FileVisitOption... options)
+        throws IOException
+    {
+        this.walker = new FileTreeWalker(Arrays.asList(options), maxDepth);
+        this.next = walker.walk(start);
+        assert next.type() == FileTreeWalker.EventType.ENTRY ||
+               next.type() == FileTreeWalker.EventType.START_DIRECTORY;
+
+        // IOException if there a problem accessing the starting file
+        IOException ioe = next.ioeException();
+        if (ioe != null)
+            throw ioe;
+    }
+
+    private void fetchNextIfNeeded() {
+        if (next == null) {
+            FileTreeWalker.Event ev = walker.next();
+            while (ev != null) {
+                IOException ioe = ev.ioeException();
+                if (ioe != null)
+                    throw new UncheckedIOException(ioe);
+
+                // END_DIRECTORY events are ignored
+                if (ev.type() != FileTreeWalker.EventType.END_DIRECTORY) {
+                    next = ev;
+                    return;
+                }
+                ev = walker.next();
+            }
+        }
+    }
+
+    @Override
+    public boolean hasNext() {
+        if (!walker.isOpen())
+            throw new IllegalStateException();
+        fetchNextIfNeeded();
+        return next != null;
+    }
+
+    @Override
+    public Event next() {
+        if (!walker.isOpen())
+            throw new IllegalStateException();
+        fetchNextIfNeeded();
+        if (next == null)
+            throw new NoSuchElementException();
+        Event result = next;
+        next = null;
+        return result;
+    }
+
+    @Override
+    public void close() {
+        walker.close();
+    }
+}
diff --git a/java/nio/file/FileTreeWalker.java b/java/nio/file/FileTreeWalker.java
new file mode 100644
index 0000000..b0cf0d3
--- /dev/null
+++ b/java/nio/file/FileTreeWalker.java
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Collection;
+import java.util.Iterator;
+import sun.nio.fs.BasicFileAttributesHolder;
+
+/**
+ * Walks a file tree, generating a sequence of events corresponding to the files
+ * in the tree.
+ *
+ * <pre>{@code
+ *     Path top = ...
+ *     Set<FileVisitOption> options = ...
+ *     int maxDepth = ...
+ *
+ *     try (FileTreeWalker walker = new FileTreeWalker(options, maxDepth)) {
+ *         FileTreeWalker.Event ev = walker.walk(top);
+ *         do {
+ *             process(ev);
+ *             ev = walker.next();
+ *         } while (ev != null);
+ *     }
+ * }</pre>
+ *
+ * @see Files#walkFileTree
+ */
+
+class FileTreeWalker implements Closeable {
+    private final boolean followLinks;
+    private final LinkOption[] linkOptions;
+    private final int maxDepth;
+    private final ArrayDeque<DirectoryNode> stack = new ArrayDeque<>();
+    private boolean closed;
+
+    /**
+     * The element on the walking stack corresponding to a directory node.
+     */
+    private static class DirectoryNode {
+        private final Path dir;
+        private final Object key;
+        private final DirectoryStream<Path> stream;
+        private final Iterator<Path> iterator;
+        private boolean skipped;
+
+        DirectoryNode(Path dir, Object key, DirectoryStream<Path> stream) {
+            this.dir = dir;
+            this.key = key;
+            this.stream = stream;
+            this.iterator = stream.iterator();
+        }
+
+        Path directory() {
+            return dir;
+        }
+
+        Object key() {
+            return key;
+        }
+
+        DirectoryStream<Path> stream() {
+            return stream;
+        }
+
+        Iterator<Path> iterator() {
+            return iterator;
+        }
+
+        void skip() {
+            skipped = true;
+        }
+
+        boolean skipped() {
+            return skipped;
+        }
+    }
+
+    /**
+     * The event types.
+     */
+    static enum EventType {
+        /**
+         * Start of a directory
+         */
+        START_DIRECTORY,
+        /**
+         * End of a directory
+         */
+        END_DIRECTORY,
+        /**
+         * An entry in a directory
+         */
+        ENTRY;
+    }
+
+    /**
+     * Events returned by the {@link #walk} and {@link #next} methods.
+     */
+    static class Event {
+        private final EventType type;
+        private final Path file;
+        private final BasicFileAttributes attrs;
+        private final IOException ioe;
+
+        private Event(EventType type, Path file, BasicFileAttributes attrs, IOException ioe) {
+            this.type = type;
+            this.file = file;
+            this.attrs = attrs;
+            this.ioe = ioe;
+        }
+
+        Event(EventType type, Path file, BasicFileAttributes attrs) {
+            this(type, file, attrs, null);
+        }
+
+        Event(EventType type, Path file, IOException ioe) {
+            this(type, file, null, ioe);
+        }
+
+        EventType type() {
+            return type;
+        }
+
+        Path file() {
+            return file;
+        }
+
+        BasicFileAttributes attributes() {
+            return attrs;
+        }
+
+        IOException ioeException() {
+            return ioe;
+        }
+    }
+
+    /**
+     * Creates a {@code FileTreeWalker}.
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code maxDepth} is negative
+     * @throws  ClassCastException
+     *          if (@code options} contains an element that is not a
+     *          {@code FileVisitOption}
+     * @throws  NullPointerException
+     *          if {@code options} is {@ocde null} or the options
+     *          array contains a {@code null} element
+     */
+    FileTreeWalker(Collection<FileVisitOption> options, int maxDepth) {
+        boolean fl = false;
+        for (FileVisitOption option: options) {
+            // will throw NPE if options contains null
+            switch (option) {
+                case FOLLOW_LINKS : fl = true; break;
+                default:
+                    throw new AssertionError("Should not get here");
+            }
+        }
+        if (maxDepth < 0)
+            throw new IllegalArgumentException("'maxDepth' is negative");
+
+        this.followLinks = fl;
+        this.linkOptions = (fl) ? new LinkOption[0] :
+            new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
+        this.maxDepth = maxDepth;
+    }
+
+    /**
+     * Returns the attributes of the given file, taking into account whether
+     * the walk is following sym links is not. The {@code canUseCached}
+     * argument determines whether this method can use cached attributes.
+     */
+    private BasicFileAttributes getAttributes(Path file, boolean canUseCached)
+        throws IOException
+    {
+        // if attributes are cached then use them if possible
+        if (canUseCached &&
+            (file instanceof BasicFileAttributesHolder) &&
+            (System.getSecurityManager() == null))
+        {
+            BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
+            if (cached != null && (!followLinks || !cached.isSymbolicLink())) {
+                return cached;
+            }
+        }
+
+        // attempt to get attributes of file. If fails and we are following
+        // links then a link target might not exist so get attributes of link
+        BasicFileAttributes attrs;
+        try {
+            attrs = Files.readAttributes(file, BasicFileAttributes.class, linkOptions);
+        } catch (IOException ioe) {
+            if (!followLinks)
+                throw ioe;
+
+            // attempt to get attrmptes without following links
+            attrs = Files.readAttributes(file,
+                                         BasicFileAttributes.class,
+                                         LinkOption.NOFOLLOW_LINKS);
+        }
+        return attrs;
+    }
+
+    /**
+     * Returns true if walking into the given directory would result in a
+     * file system loop/cycle.
+     */
+    private boolean wouldLoop(Path dir, Object key) {
+        // if this directory and ancestor has a file key then we compare
+        // them; otherwise we use less efficient isSameFile test.
+        for (DirectoryNode ancestor: stack) {
+            Object ancestorKey = ancestor.key();
+            if (key != null && ancestorKey != null) {
+                if (key.equals(ancestorKey)) {
+                    // cycle detected
+                    return true;
+                }
+            } else {
+                try {
+                    if (Files.isSameFile(dir, ancestor.directory())) {
+                        // cycle detected
+                        return true;
+                    }
+                } catch (IOException | SecurityException x) {
+                    // ignore
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Visits the given file, returning the {@code Event} corresponding to that
+     * visit.
+     *
+     * The {@code ignoreSecurityException} parameter determines whether
+     * any SecurityException should be ignored or not. If a SecurityException
+     * is thrown, and is ignored, then this method returns {@code null} to
+     * mean that there is no event corresponding to a visit to the file.
+     *
+     * The {@code canUseCached} parameter determines whether cached attributes
+     * for the file can be used or not.
+     */
+    private Event visit(Path entry, boolean ignoreSecurityException, boolean canUseCached) {
+        // need the file attributes
+        BasicFileAttributes attrs;
+        try {
+            attrs = getAttributes(entry, canUseCached);
+        } catch (IOException ioe) {
+            return new Event(EventType.ENTRY, entry, ioe);
+        } catch (SecurityException se) {
+            if (ignoreSecurityException)
+                return null;
+            throw se;
+        }
+
+        // at maximum depth or file is not a directory
+        int depth = stack.size();
+        if (depth >= maxDepth || !attrs.isDirectory()) {
+            return new Event(EventType.ENTRY, entry, attrs);
+        }
+
+        // check for cycles when following links
+        if (followLinks && wouldLoop(entry, attrs.fileKey())) {
+            return new Event(EventType.ENTRY, entry,
+                             new FileSystemLoopException(entry.toString()));
+        }
+
+        // file is a directory, attempt to open it
+        DirectoryStream<Path> stream = null;
+        try {
+            stream = Files.newDirectoryStream(entry);
+        } catch (IOException ioe) {
+            return new Event(EventType.ENTRY, entry, ioe);
+        } catch (SecurityException se) {
+            if (ignoreSecurityException)
+                return null;
+            throw se;
+        }
+
+        // push a directory node to the stack and return an event
+        stack.push(new DirectoryNode(entry, attrs.fileKey(), stream));
+        return new Event(EventType.START_DIRECTORY, entry, attrs);
+    }
+
+
+    /**
+     * Start walking from the given file.
+     */
+    Event walk(Path file) {
+        if (closed)
+            throw new IllegalStateException("Closed");
+
+        Event ev = visit(file,
+                         false,   // ignoreSecurityException
+                         false);  // canUseCached
+        assert ev != null;
+        return ev;
+    }
+
+    /**
+     * Returns the next Event or {@code null} if there are no more events or
+     * the walker is closed.
+     */
+    Event next() {
+        DirectoryNode top = stack.peek();
+        if (top == null)
+            return null;      // stack is empty, we are done
+
+        // continue iteration of the directory at the top of the stack
+        Event ev;
+        do {
+            Path entry = null;
+            IOException ioe = null;
+
+            // get next entry in the directory
+            if (!top.skipped()) {
+                Iterator<Path> iterator = top.iterator();
+                try {
+                    if (iterator.hasNext()) {
+                        entry = iterator.next();
+                    }
+                } catch (DirectoryIteratorException x) {
+                    ioe = x.getCause();
+                }
+            }
+
+            // no next entry so close and pop directory, creating corresponding event
+            if (entry == null) {
+                try {
+                    top.stream().close();
+                } catch (IOException e) {
+                    if (ioe != null) {
+                        ioe = e;
+                    } else {
+                        ioe.addSuppressed(e);
+                    }
+                }
+                stack.pop();
+                return new Event(EventType.END_DIRECTORY, top.directory(), ioe);
+            }
+
+            // visit the entry
+            ev = visit(entry,
+                       true,   // ignoreSecurityException
+                       true);  // canUseCached
+
+        } while (ev == null);
+
+        return ev;
+    }
+
+    /**
+     * Pops the directory node that is the current top of the stack so that
+     * there are no more events for the directory (including no END_DIRECTORY)
+     * event. This method is a no-op if the stack is empty or the walker is
+     * closed.
+     */
+    void pop() {
+        if (!stack.isEmpty()) {
+            DirectoryNode node = stack.pop();
+            try {
+                node.stream().close();
+            } catch (IOException ignore) { }
+        }
+    }
+
+    /**
+     * Skips the remaining entries in the directory at the top of the stack.
+     * This method is a no-op if the stack is empty or the walker is closed.
+     */
+    void skipRemainingSiblings() {
+        if (!stack.isEmpty()) {
+            stack.peek().skip();
+        }
+    }
+
+    /**
+     * Returns {@code true} if the walker is open.
+     */
+    boolean isOpen() {
+        return !closed;
+    }
+
+    /**
+     * Closes/pops all directories on the stack.
+     */
+    @Override
+    public void close() {
+        if (!closed) {
+            while (!stack.isEmpty()) {
+                pop();
+            }
+            closed = true;
+        }
+    }
+}
diff --git a/java/nio/file/FileVisitOption.java b/java/nio/file/FileVisitOption.java
new file mode 100644
index 0000000..c6c00e5
--- /dev/null
+++ b/java/nio/file/FileVisitOption.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.nio.file;
+
+/**
+ * Defines the file tree traversal options.
+ *
+ * @since 1.7
+ *
+ * @see Files#walkFileTree
+ */
+
+public enum FileVisitOption {
+    /**
+     * Follow symbolic links.
+     */
+    FOLLOW_LINKS;
+}
diff --git a/java/nio/file/FileVisitResult.java b/java/nio/file/FileVisitResult.java
new file mode 100644
index 0000000..36bd5c9
--- /dev/null
+++ b/java/nio/file/FileVisitResult.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * The result type of a {@link FileVisitor FileVisitor}.
+ *
+ * @since 1.7
+ *
+ * @see Files#walkFileTree
+ */
+
+public enum FileVisitResult {
+    /**
+     * Continue. When returned from a {@link FileVisitor#preVisitDirectory
+     * preVisitDirectory} method then the entries in the directory should also
+     * be visited.
+     */
+    CONTINUE,
+    /**
+     * Terminate.
+     */
+    TERMINATE,
+    /**
+     * Continue without visiting the entries in this directory. This result
+     * is only meaningful when returned from the {@link
+     * FileVisitor#preVisitDirectory preVisitDirectory} method; otherwise
+     * this result type is the same as returning {@link #CONTINUE}.
+     */
+    SKIP_SUBTREE,
+    /**
+     * Continue without visiting the <em>siblings</em> of this file or directory.
+     * If returned from the {@link FileVisitor#preVisitDirectory
+     * preVisitDirectory} method then the entries in the directory are also
+     * skipped and the {@link FileVisitor#postVisitDirectory postVisitDirectory}
+     * method is not invoked.
+     */
+    SKIP_SIBLINGS;
+}
diff --git a/java/nio/file/FileVisitor.java b/java/nio/file/FileVisitor.java
new file mode 100644
index 0000000..5c555ae
--- /dev/null
+++ b/java/nio/file/FileVisitor.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+
+/**
+ * A visitor of files. An implementation of this interface is provided to the
+ * {@link Files#walkFileTree Files.walkFileTree} methods to visit each file in
+ * a file tree.
+ *
+ * <p> <b>Usage Examples:</b>
+ * Suppose we want to delete a file tree. In that case, each directory should
+ * be deleted after the entries in the directory are deleted.
+ * <pre>
+ *     Path start = ...
+ *     Files.walkFileTree(start, new SimpleFileVisitor&lt;Path&gt;() {
+ *         &#64;Override
+ *         public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ *             throws IOException
+ *         {
+ *             Files.delete(file);
+ *             return FileVisitResult.CONTINUE;
+ *         }
+ *         &#64;Override
+ *         public FileVisitResult postVisitDirectory(Path dir, IOException e)
+ *             throws IOException
+ *         {
+ *             if (e == null) {
+ *                 Files.delete(dir);
+ *                 return FileVisitResult.CONTINUE;
+ *             } else {
+ *                 // directory iteration failed
+ *                 throw e;
+ *             }
+ *         }
+ *     });
+ * </pre>
+ * <p> Furthermore, suppose we want to copy a file tree to a target location.
+ * In that case, symbolic links should be followed and the target directory
+ * should be created before the entries in the directory are copied.
+ * <pre>
+ *     final Path source = ...
+ *     final Path target = ...
+ *
+ *     Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE,
+ *         new SimpleFileVisitor&lt;Path&gt;() {
+ *             &#64;Override
+ *             public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
+ *                 throws IOException
+ *             {
+ *                 Path targetdir = target.resolve(source.relativize(dir));
+ *                 try {
+ *                     Files.copy(dir, targetdir);
+ *                 } catch (FileAlreadyExistsException e) {
+ *                      if (!Files.isDirectory(targetdir))
+ *                          throw e;
+ *                 }
+ *                 return CONTINUE;
+ *             }
+ *             &#64;Override
+ *             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ *                 throws IOException
+ *             {
+ *                 Files.copy(file, target.resolve(source.relativize(file)));
+ *                 return CONTINUE;
+ *             }
+ *         });
+ * </pre>
+ *
+ * @since 1.7
+ */
+
+public interface FileVisitor<T> {
+
+    /**
+     * Invoked for a directory before entries in the directory are visited.
+     *
+     * <p> If this method returns {@link FileVisitResult#CONTINUE CONTINUE},
+     * then entries in the directory are visited. If this method returns {@link
+     * FileVisitResult#SKIP_SUBTREE SKIP_SUBTREE} or {@link
+     * FileVisitResult#SKIP_SIBLINGS SKIP_SIBLINGS} then entries in the
+     * directory (and any descendants) will not be visited.
+     *
+     * @param   dir
+     *          a reference to the directory
+     * @param   attrs
+     *          the directory's basic attributes
+     *
+     * @return  the visit result
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
+        throws IOException;
+
+    /**
+     * Invoked for a file in a directory.
+     *
+     * @param   file
+     *          a reference to the file
+     * @param   attrs
+     *          the file's basic attributes
+     *
+     * @return  the visit result
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    FileVisitResult visitFile(T file, BasicFileAttributes attrs)
+        throws IOException;
+
+    /**
+     * Invoked for a file that could not be visited. This method is invoked
+     * if the file's attributes could not be read, the file is a directory
+     * that could not be opened, and other reasons.
+     *
+     * @param   file
+     *          a reference to the file
+     * @param   exc
+     *          the I/O exception that prevented the file from being visited
+     *
+     * @return  the visit result
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    FileVisitResult visitFileFailed(T file, IOException exc)
+        throws IOException;
+
+    /**
+     * Invoked for a directory after entries in the directory, and all of their
+     * descendants, have been visited. This method is also invoked when iteration
+     * of the directory completes prematurely (by a {@link #visitFile visitFile}
+     * method returning {@link FileVisitResult#SKIP_SIBLINGS SKIP_SIBLINGS},
+     * or an I/O error when iterating over the directory).
+     *
+     * @param   dir
+     *          a reference to the directory
+     * @param   exc
+     *          {@code null} if the iteration of the directory completes without
+     *          an error; otherwise the I/O exception that caused the iteration
+     *          of the directory to complete prematurely
+     *
+     * @return  the visit result
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    FileVisitResult postVisitDirectory(T dir, IOException exc)
+        throws IOException;
+}
diff --git a/java/nio/file/Files.java b/java/nio/file/Files.java
new file mode 100644
index 0000000..012118c
--- /dev/null
+++ b/java/nio/file/Files.java
@@ -0,0 +1,3787 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.UncheckedIOException;
+import java.io.Writer;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.DosFileAttributes;   // javadoc
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileOwnerAttributeView;
+import java.nio.file.attribute.FileStoreAttributeView;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.PosixFileAttributeView;
+import java.nio.file.attribute.PosixFileAttributes;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.UserPrincipal;
+import java.nio.file.spi.FileSystemProvider;
+import java.nio.file.spi.FileTypeDetector;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.Spliterators;
+import java.util.function.BiPredicate;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+/**
+ * This class consists exclusively of static methods that operate on files,
+ * directories, or other types of files.
+ *
+ * <p> In most cases, the methods defined here will delegate to the associated
+ * file system provider to perform the file operations.
+ *
+ * @since 1.7
+ */
+
+public final class Files {
+    private Files() { }
+
+    /**
+     * Returns the {@code FileSystemProvider} to delegate to.
+     */
+    private static FileSystemProvider provider(Path path) {
+        return path.getFileSystem().provider();
+    }
+
+    /**
+     * Convert a Closeable to a Runnable by converting checked IOException
+     * to UncheckedIOException
+     */
+    private static Runnable asUncheckedRunnable(Closeable c) {
+        return () -> {
+            try {
+                c.close();
+            } catch (IOException e) {
+                throw new UncheckedIOException(e);
+            }
+        };
+    }
+
+    // -- File contents --
+
+    /**
+     * Opens a file, returning an input stream to read from the file. The stream
+     * will not be buffered, and is not required to support the {@link
+     * InputStream#mark mark} or {@link InputStream#reset reset} methods. The
+     * stream will be safe for access by multiple concurrent threads. Reading
+     * commences at the beginning of the file. Whether the returned stream is
+     * <i>asynchronously closeable</i> and/or <i>interruptible</i> is highly
+     * file system provider specific and therefore not specified.
+     *
+     * <p> The {@code options} parameter determines how the file is opened.
+     * If no options are present then it is equivalent to opening the file with
+     * the {@link StandardOpenOption#READ READ} option. In addition to the {@code
+     * READ} option, an implementation may also support additional implementation
+     * specific options.
+     *
+     * @param   path
+     *          the path to the file to open
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new input stream
+     *
+     * @throws  IllegalArgumentException
+     *          if an invalid combination of options is specified
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    public static InputStream newInputStream(Path path, OpenOption... options)
+        throws IOException
+    {
+        return provider(path).newInputStream(path, options);
+    }
+
+    /**
+     * Opens or creates a file, returning an output stream that may be used to
+     * write bytes to the file. The resulting stream will not be buffered. The
+     * stream will be safe for access by multiple concurrent threads. Whether
+     * the returned stream is <i>asynchronously closeable</i> and/or
+     * <i>interruptible</i> is highly file system provider specific and
+     * therefore not specified.
+     *
+     * <p> This method opens or creates a file in exactly the manner specified
+     * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
+     * method with the exception that the {@link StandardOpenOption#READ READ}
+     * option may not be present in the array of options. If no options are
+     * present then this method works as if the {@link StandardOpenOption#CREATE
+     * CREATE}, {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING},
+     * and {@link StandardOpenOption#WRITE WRITE} options are present. In other
+     * words, it opens the file for writing, creating the file if it doesn't
+     * exist, or initially truncating an existing {@link #isRegularFile
+     * regular-file} to a size of {@code 0} if it exists.
+     *
+     * <p> <b>Usage Examples:</b>
+     * <pre>
+     *     Path path = ...
+     *
+     *     // truncate and overwrite an existing file, or create the file if
+     *     // it doesn't initially exist
+     *     OutputStream out = Files.newOutputStream(path);
+     *
+     *     // append to an existing file, fail if the file does not exist
+     *     out = Files.newOutputStream(path, APPEND);
+     *
+     *     // append to an existing file, create file if it doesn't initially exist
+     *     out = Files.newOutputStream(path, CREATE, APPEND);
+     *
+     *     // always create new file, failing if it already exists
+     *     out = Files.newOutputStream(path, CREATE_NEW);
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new output stream
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code options} contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file. The {@link
+     *          SecurityManager#checkDelete(String) checkDelete} method is
+     *          invoked to check delete access if the file is opened with the
+     *          {@code DELETE_ON_CLOSE} option.
+     */
+    public static OutputStream newOutputStream(Path path, OpenOption... options)
+        throws IOException
+    {
+        return provider(path).newOutputStream(path, options);
+    }
+
+    /**
+     * Opens or creates a file, returning a seekable byte channel to access the
+     * file.
+     *
+     * <p> The {@code options} parameter determines how the file is opened.
+     * The {@link StandardOpenOption#READ READ} and {@link
+     * StandardOpenOption#WRITE WRITE} options determine if the file should be
+     * opened for reading and/or writing. If neither option (or the {@link
+     * StandardOpenOption#APPEND APPEND} option) is present then the file is
+     * opened for reading. By default reading or writing commence at the
+     * beginning of the file.
+     *
+     * <p> In the addition to {@code READ} and {@code WRITE}, the following
+     * options may be present:
+     *
+     * <table border=1 cellpadding=5 summary="Options">
+     * <tr> <th>Option</th> <th>Description</th> </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#APPEND APPEND} </td>
+     *   <td> If this option is present then the file is opened for writing and
+     *     each invocation of the channel's {@code write} method first advances
+     *     the position to the end of the file and then writes the requested
+     *     data. Whether the advancement of the position and the writing of the
+     *     data are done in a single atomic operation is system-dependent and
+     *     therefore unspecified. This option may not be used in conjunction
+     *     with the {@code READ} or {@code TRUNCATE_EXISTING} options. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING} </td>
+     *   <td> If this option is present then the existing file is truncated to
+     *   a size of 0 bytes. This option is ignored when the file is opened only
+     *   for reading. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#CREATE_NEW CREATE_NEW} </td>
+     *   <td> If this option is present then a new file is created, failing if
+     *   the file already exists or is a symbolic link. When creating a file the
+     *   check for the existence of the file and the creation of the file if it
+     *   does not exist is atomic with respect to other file system operations.
+     *   This option is ignored when the file is opened only for reading. </td>
+     * </tr>
+     * <tr>
+     *   <td > {@link StandardOpenOption#CREATE CREATE} </td>
+     *   <td> If this option is present then an existing file is opened if it
+     *   exists, otherwise a new file is created. This option is ignored if the
+     *   {@code CREATE_NEW} option is also present or the file is opened only
+     *   for reading. </td>
+     * </tr>
+     * <tr>
+     *   <td > {@link StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} </td>
+     *   <td> When this option is present then the implementation makes a
+     *   <em>best effort</em> attempt to delete the file when closed by the
+     *   {@link SeekableByteChannel#close close} method. If the {@code close}
+     *   method is not invoked then a <em>best effort</em> attempt is made to
+     *   delete the file when the Java virtual machine terminates. </td>
+     * </tr>
+     * <tr>
+     *   <td>{@link StandardOpenOption#SPARSE SPARSE} </td>
+     *   <td> When creating a new file this option is a <em>hint</em> that the
+     *   new file will be sparse. This option is ignored when not creating
+     *   a new file. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#SYNC SYNC} </td>
+     *   <td> Requires that every update to the file's content or metadata be
+     *   written synchronously to the underlying storage device. (see <a
+     *   href="package-summary.html#integrity"> Synchronized I/O file
+     *   integrity</a>). </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardOpenOption#DSYNC DSYNC} </td>
+     *   <td> Requires that every update to the file's content be written
+     *   synchronously to the underlying storage device. (see <a
+     *   href="package-summary.html#integrity"> Synchronized I/O file
+     *   integrity</a>). </td>
+     * </tr>
+     * </table>
+     *
+     * <p> An implementation may also support additional implementation specific
+     * options.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when a new file is created.
+     *
+     * <p> In the case of the default provider, the returned seekable byte channel
+     * is a {@link java.nio.channels.FileChannel}.
+     *
+     * <p> <b>Usage Examples:</b>
+     * <pre>
+     *     Path path = ...
+     *
+     *     // open file for reading
+     *     ReadableByteChannel rbc = Files.newByteChannel(path, EnumSet.of(READ)));
+     *
+     *     // open file for writing to the end of an existing file, creating
+     *     // the file if it doesn't already exist
+     *     WritableByteChannel wbc = Files.newByteChannel(path, EnumSet.of(CREATE,APPEND));
+     *
+     *     // create file with initial permissions, opening it for both reading and writing
+     *     {@code FileAttribute<Set<PosixFilePermission>> perms = ...}
+     *     SeekableByteChannel sbc = Files.newByteChannel(path, EnumSet.of(CREATE_NEW,READ,WRITE), perms);
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  a new seekable byte channel
+     *
+     * @throws  IllegalArgumentException
+     *          if the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported open option is specified or the array contains
+     *          attributes that cannot be set atomically when creating the file
+     * @throws  FileAlreadyExistsException
+     *          if a file of that name already exists and the {@link
+     *          StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the path if the file is
+     *          opened for reading. The {@link SecurityManager#checkWrite(String)
+     *          checkWrite} method is invoked to check write access to the path
+     *          if the file is opened for writing. The {@link
+     *          SecurityManager#checkDelete(String) checkDelete} method is
+     *          invoked to check delete access if the file is opened with the
+     *          {@code DELETE_ON_CLOSE} option.
+     *
+     * @see java.nio.channels.FileChannel#open(Path,Set,FileAttribute[])
+     */
+    public static SeekableByteChannel newByteChannel(Path path,
+                                                     Set<? extends OpenOption> options,
+                                                     FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return provider(path).newByteChannel(path, options, attrs);
+    }
+
+    /**
+     * Opens or creates a file, returning a seekable byte channel to access the
+     * file.
+     *
+     * <p> This method opens or creates a file in exactly the manner specified
+     * by the {@link #newByteChannel(Path,Set,FileAttribute[]) newByteChannel}
+     * method.
+     *
+     * @param   path
+     *          the path to the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new seekable byte channel
+     *
+     * @throws  IllegalArgumentException
+     *          if the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported open option is specified
+     * @throws  FileAlreadyExistsException
+     *          if a file of that name already exists and the {@link
+     *          StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the path if the file is
+     *          opened for reading. The {@link SecurityManager#checkWrite(String)
+     *          checkWrite} method is invoked to check write access to the path
+     *          if the file is opened for writing. The {@link
+     *          SecurityManager#checkDelete(String) checkDelete} method is
+     *          invoked to check delete access if the file is opened with the
+     *          {@code DELETE_ON_CLOSE} option.
+     *
+     * @see java.nio.channels.FileChannel#open(Path,OpenOption[])
+     */
+    public static SeekableByteChannel newByteChannel(Path path, OpenOption... options)
+        throws IOException
+    {
+        Set<OpenOption> set = new HashSet<OpenOption>(options.length);
+        Collections.addAll(set, options);
+        return newByteChannel(path, set);
+    }
+
+    // -- Directories --
+
+    private static class AcceptAllFilter
+        implements DirectoryStream.Filter<Path>
+    {
+        private AcceptAllFilter() { }
+
+        @Override
+        public boolean accept(Path entry) { return true; }
+
+        static final AcceptAllFilter FILTER = new AcceptAllFilter();
+    }
+
+    /**
+     * Opens a directory, returning a {@link DirectoryStream} to iterate over
+     * all entries in the directory. The elements returned by the directory
+     * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+     * Path}, each one representing an entry in the directory. The {@code Path}
+     * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+     * name of the directory entry against {@code dir}.
+     *
+     * <p> When not using the try-with-resources construct, then directory
+     * stream's {@code close} method should be invoked after iteration is
+     * completed so as to free any resources held for the open directory.
+     *
+     * <p> When an implementation supports operations on entries in the
+     * directory that execute in a race-free manner then the returned directory
+     * stream is a {@link SecureDirectoryStream}.
+     *
+     * @param   dir
+     *          the path to the directory
+     *
+     * @return  a new and open {@code DirectoryStream} object
+     *
+     * @throws  NotDirectoryException
+     *          if the file could not otherwise be opened because it is not
+     *          a directory <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the directory.
+     */
+    public static DirectoryStream<Path> newDirectoryStream(Path dir)
+        throws IOException
+    {
+        return provider(dir).newDirectoryStream(dir, AcceptAllFilter.FILTER);
+    }
+
+    /**
+     * Opens a directory, returning a {@link DirectoryStream} to iterate over
+     * the entries in the directory. The elements returned by the directory
+     * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+     * Path}, each one representing an entry in the directory. The {@code Path}
+     * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+     * name of the directory entry against {@code dir}. The entries returned by
+     * the iterator are filtered by matching the {@code String} representation
+     * of their file names against the given <em>globbing</em> pattern.
+     *
+     * <p> For example, suppose we want to iterate over the files ending with
+     * ".java" in a directory:
+     * <pre>
+     *     Path dir = ...
+     *     try (DirectoryStream&lt;Path&gt; stream = Files.newDirectoryStream(dir, "*.java")) {
+     *         :
+     *     }
+     * </pre>
+     *
+     * <p> The globbing pattern is specified by the {@link
+     * FileSystem#getPathMatcher getPathMatcher} method.
+     *
+     * <p> When not using the try-with-resources construct, then directory
+     * stream's {@code close} method should be invoked after iteration is
+     * completed so as to free any resources held for the open directory.
+     *
+     * <p> When an implementation supports operations on entries in the
+     * directory that execute in a race-free manner then the returned directory
+     * stream is a {@link SecureDirectoryStream}.
+     *
+     * @param   dir
+     *          the path to the directory
+     * @param   glob
+     *          the glob pattern
+     *
+     * @return  a new and open {@code DirectoryStream} object
+     *
+     * @throws  java.util.regex.PatternSyntaxException
+     *          if the pattern is invalid
+     * @throws  NotDirectoryException
+     *          if the file could not otherwise be opened because it is not
+     *          a directory <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the directory.
+     */
+    public static DirectoryStream<Path> newDirectoryStream(Path dir, String glob)
+        throws IOException
+    {
+        // avoid creating a matcher if all entries are required.
+        if (glob.equals("*"))
+            return newDirectoryStream(dir);
+
+        // create a matcher and return a filter that uses it.
+        FileSystem fs = dir.getFileSystem();
+        final PathMatcher matcher = fs.getPathMatcher("glob:" + glob);
+        DirectoryStream.Filter<Path> filter = new DirectoryStream.Filter<Path>() {
+            @Override
+            public boolean accept(Path entry)  {
+                return matcher.matches(entry.getFileName());
+            }
+        };
+        return fs.provider().newDirectoryStream(dir, filter);
+    }
+
+    /**
+     * Opens a directory, returning a {@link DirectoryStream} to iterate over
+     * the entries in the directory. The elements returned by the directory
+     * stream's {@link DirectoryStream#iterator iterator} are of type {@code
+     * Path}, each one representing an entry in the directory. The {@code Path}
+     * objects are obtained as if by {@link Path#resolve(Path) resolving} the
+     * name of the directory entry against {@code dir}. The entries returned by
+     * the iterator are filtered by the given {@link DirectoryStream.Filter
+     * filter}.
+     *
+     * <p> When not using the try-with-resources construct, then directory
+     * stream's {@code close} method should be invoked after iteration is
+     * completed so as to free any resources held for the open directory.
+     *
+     * <p> Where the filter terminates due to an uncaught error or runtime
+     * exception then it is propagated to the {@link Iterator#hasNext()
+     * hasNext} or {@link Iterator#next() next} method. Where an {@code
+     * IOException} is thrown, it results in the {@code hasNext} or {@code
+     * next} method throwing a {@link DirectoryIteratorException} with the
+     * {@code IOException} as the cause.
+     *
+     * <p> When an implementation supports operations on entries in the
+     * directory that execute in a race-free manner then the returned directory
+     * stream is a {@link SecureDirectoryStream}.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to iterate over the files in a directory that are
+     * larger than 8K.
+     * <pre>
+     *     DirectoryStream.Filter&lt;Path&gt; filter = new DirectoryStream.Filter&lt;Path&gt;() {
+     *         public boolean accept(Path file) throws IOException {
+     *             return (Files.size(file) &gt; 8192L);
+     *         }
+     *     };
+     *     Path dir = ...
+     *     try (DirectoryStream&lt;Path&gt; stream = Files.newDirectoryStream(dir, filter)) {
+     *         :
+     *     }
+     * </pre>
+     *
+     * @param   dir
+     *          the path to the directory
+     * @param   filter
+     *          the directory stream filter
+     *
+     * @return  a new and open {@code DirectoryStream} object
+     *
+     * @throws  NotDirectoryException
+     *          if the file could not otherwise be opened because it is not
+     *          a directory <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the directory.
+     */
+    public static DirectoryStream<Path> newDirectoryStream(Path dir,
+                                                           DirectoryStream.Filter<? super Path> filter)
+        throws IOException
+    {
+        return provider(dir).newDirectoryStream(dir, filter);
+    }
+
+    // -- Creation and deletion --
+
+    /**
+     * Creates a new and empty file, failing if the file already exists. The
+     * check for the existence of the file and the creation of the new file if
+     * it does not exist are a single operation that is atomic with respect to
+     * all other filesystem activities that might affect the directory.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when creating the file. Each attribute
+     * is identified by its {@link FileAttribute#name name}. If more than one
+     * attribute of the same name is included in the array then all but the last
+     * occurrence is ignored.
+     *
+     * @param   path
+     *          the path to the file to create
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  the file
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the file
+     * @throws  FileAlreadyExistsException
+     *          if a file of that name already exists
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs or the parent directory does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the new file.
+     */
+    public static Path createFile(Path path, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        EnumSet<StandardOpenOption> options =
+            EnumSet.<StandardOpenOption>of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE);
+        newByteChannel(path, options, attrs).close();
+        return path;
+    }
+
+    /**
+     * Creates a new directory. The check for the existence of the file and the
+     * creation of the directory if it does not exist are a single operation
+     * that is atomic with respect to all other filesystem activities that might
+     * affect the directory. The {@link #createDirectories createDirectories}
+     * method should be used where it is required to create all nonexistent
+     * parent directories first.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when creating the directory. Each
+     * attribute is identified by its {@link FileAttribute#name name}. If more
+     * than one attribute of the same name is included in the array then all but
+     * the last occurrence is ignored.
+     *
+     * @param   dir
+     *          the directory to create
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the directory
+     *
+     * @return  the directory
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  FileAlreadyExistsException
+     *          if a directory could not otherwise be created because a file of
+     *          that name already exists <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs or the parent directory does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the new directory.
+     */
+    public static Path createDirectory(Path dir, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        provider(dir).createDirectory(dir, attrs);
+        return dir;
+    }
+
+    /**
+     * Creates a directory by creating all nonexistent parent directories first.
+     * Unlike the {@link #createDirectory createDirectory} method, an exception
+     * is not thrown if the directory could not be created because it already
+     * exists.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when creating the nonexistent
+     * directories. Each file attribute is identified by its {@link
+     * FileAttribute#name name}. If more than one attribute of the same name is
+     * included in the array then all but the last occurrence is ignored.
+     *
+     * <p> If this method fails, then it may do so after creating some, but not
+     * all, of the parent directories.
+     *
+     * @param   dir
+     *          the directory to create
+     *
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the directory
+     *
+     * @return  the directory
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  FileAlreadyExistsException
+     *          if {@code dir} exists but is not a directory <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          in the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked prior to attempting to create a directory and
+     *          its {@link SecurityManager#checkRead(String) checkRead} is
+     *          invoked for each parent directory that is checked. If {@code
+     *          dir} is not an absolute path then its {@link Path#toAbsolutePath
+     *          toAbsolutePath} may need to be invoked to get its absolute path.
+     *          This may invoke the security manager's {@link
+     *          SecurityManager#checkPropertyAccess(String) checkPropertyAccess}
+     *          method to check access to the system property {@code user.dir}
+     */
+    public static Path createDirectories(Path dir, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        // attempt to create the directory
+        try {
+            createAndCheckIsDirectory(dir, attrs);
+            return dir;
+        } catch (FileAlreadyExistsException x) {
+            // file exists and is not a directory
+            throw x;
+        } catch (IOException x) {
+            // parent may not exist or other reason
+        }
+        SecurityException se = null;
+        try {
+            dir = dir.toAbsolutePath();
+        } catch (SecurityException x) {
+            // don't have permission to get absolute path
+            se = x;
+        }
+        // find a decendent that exists
+        Path parent = dir.getParent();
+        while (parent != null) {
+            try {
+                provider(parent).checkAccess(parent);
+                break;
+            } catch (NoSuchFileException x) {
+                // does not exist
+            }
+            parent = parent.getParent();
+        }
+        if (parent == null) {
+            // unable to find existing parent
+            if (se == null) {
+                throw new FileSystemException(dir.toString(), null,
+                    "Unable to determine if root directory exists");
+            } else {
+                throw se;
+            }
+        }
+
+        // create directories
+        Path child = parent;
+        for (Path name: parent.relativize(dir)) {
+            child = child.resolve(name);
+            createAndCheckIsDirectory(child, attrs);
+        }
+        return dir;
+    }
+
+    /**
+     * Used by createDirectories to attempt to create a directory. A no-op
+     * if the directory already exists.
+     */
+    private static void createAndCheckIsDirectory(Path dir,
+                                                  FileAttribute<?>... attrs)
+        throws IOException
+    {
+        try {
+            createDirectory(dir, attrs);
+        } catch (FileAlreadyExistsException x) {
+            if (!isDirectory(dir, LinkOption.NOFOLLOW_LINKS))
+                throw x;
+        }
+    }
+
+    /**
+     * Creates a new empty file in the specified directory, using the given
+     * prefix and suffix strings to generate its name. The resulting
+     * {@code Path} is associated with the same {@code FileSystem} as the given
+     * directory.
+     *
+     * <p> The details as to how the name of the file is constructed is
+     * implementation dependent and therefore not specified. Where possible
+     * the {@code prefix} and {@code suffix} are used to construct candidate
+     * names in the same manner as the {@link
+     * java.io.File#createTempFile(String,String,File)} method.
+     *
+     * <p> As with the {@code File.createTempFile} methods, this method is only
+     * part of a temporary-file facility. Where used as a <em>work files</em>,
+     * the resulting file may be opened using the {@link
+     * StandardOpenOption#DELETE_ON_CLOSE DELETE_ON_CLOSE} option so that the
+     * file is deleted when the appropriate {@code close} method is invoked.
+     * Alternatively, a {@link Runtime#addShutdownHook shutdown-hook}, or the
+     * {@link java.io.File#deleteOnExit} mechanism may be used to delete the
+     * file automatically.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when creating the file. Each attribute
+     * is identified by its {@link FileAttribute#name name}. If more than one
+     * attribute of the same name is included in the array then all but the last
+     * occurrence is ignored. When no file attributes are specified, then the
+     * resulting file may have more restrictive access permissions to files
+     * created by the {@link java.io.File#createTempFile(String,String,File)}
+     * method.
+     *
+     * @param   dir
+     *          the path to directory in which to create the file
+     * @param   prefix
+     *          the prefix string to be used in generating the file's name;
+     *          may be {@code null}
+     * @param   suffix
+     *          the suffix string to be used in generating the file's name;
+     *          may be {@code null}, in which case "{@code .tmp}" is used
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  the path to the newly created file that did not exist before
+     *          this method was invoked
+     *
+     * @throws  IllegalArgumentException
+     *          if the prefix or suffix parameters cannot be used to generate
+     *          a candidate file name
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  IOException
+     *          if an I/O error occurs or {@code dir} does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     */
+    public static Path createTempFile(Path dir,
+                                      String prefix,
+                                      String suffix,
+                                      FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return TempFileHelper.createTempFile(Objects.requireNonNull(dir),
+                                             prefix, suffix, attrs);
+    }
+
+    /**
+     * Creates an empty file in the default temporary-file directory, using
+     * the given prefix and suffix to generate its name. The resulting {@code
+     * Path} is associated with the default {@code FileSystem}.
+     *
+     * <p> This method works in exactly the manner specified by the
+     * {@link #createTempFile(Path,String,String,FileAttribute[])} method for
+     * the case that the {@code dir} parameter is the temporary-file directory.
+     *
+     * @param   prefix
+     *          the prefix string to be used in generating the file's name;
+     *          may be {@code null}
+     * @param   suffix
+     *          the suffix string to be used in generating the file's name;
+     *          may be {@code null}, in which case "{@code .tmp}" is used
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  the path to the newly created file that did not exist before
+     *          this method was invoked
+     *
+     * @throws  IllegalArgumentException
+     *          if the prefix or suffix parameters cannot be used to generate
+     *          a candidate file name
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  IOException
+     *          if an I/O error occurs or the temporary-file directory does not
+     *          exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     */
+    public static Path createTempFile(String prefix,
+                                      String suffix,
+                                      FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return TempFileHelper.createTempFile(null, prefix, suffix, attrs);
+    }
+
+    /**
+     * Creates a new directory in the specified directory, using the given
+     * prefix to generate its name.  The resulting {@code Path} is associated
+     * with the same {@code FileSystem} as the given directory.
+     *
+     * <p> The details as to how the name of the directory is constructed is
+     * implementation dependent and therefore not specified. Where possible
+     * the {@code prefix} is used to construct candidate names.
+     *
+     * <p> As with the {@code createTempFile} methods, this method is only
+     * part of a temporary-file facility. A {@link Runtime#addShutdownHook
+     * shutdown-hook}, or the {@link java.io.File#deleteOnExit} mechanism may be
+     * used to delete the directory automatically.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * file-attributes} to set atomically when creating the directory. Each
+     * attribute is identified by its {@link FileAttribute#name name}. If more
+     * than one attribute of the same name is included in the array then all but
+     * the last occurrence is ignored.
+     *
+     * @param   dir
+     *          the path to directory in which to create the directory
+     * @param   prefix
+     *          the prefix string to be used in generating the directory's name;
+     *          may be {@code null}
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the directory
+     *
+     * @return  the path to the newly created directory that did not exist before
+     *          this method was invoked
+     *
+     * @throws  IllegalArgumentException
+     *          if the prefix cannot be used to generate a candidate directory name
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  IOException
+     *          if an I/O error occurs or {@code dir} does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access when creating the
+     *          directory.
+     */
+    public static Path createTempDirectory(Path dir,
+                                           String prefix,
+                                           FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return TempFileHelper.createTempDirectory(Objects.requireNonNull(dir),
+                                                  prefix, attrs);
+    }
+
+    /**
+     * Creates a new directory in the default temporary-file directory, using
+     * the given prefix to generate its name. The resulting {@code Path} is
+     * associated with the default {@code FileSystem}.
+     *
+     * <p> This method works in exactly the manner specified by {@link
+     * #createTempDirectory(Path,String,FileAttribute[])} method for the case
+     * that the {@code dir} parameter is the temporary-file directory.
+     *
+     * @param   prefix
+     *          the prefix string to be used in generating the directory's name;
+     *          may be {@code null}
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the directory
+     *
+     * @return  the path to the newly created directory that did not exist before
+     *          this method was invoked
+     *
+     * @throws  IllegalArgumentException
+     *          if the prefix cannot be used to generate a candidate directory name
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  IOException
+     *          if an I/O error occurs or the temporary-file directory does not
+     *          exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access when creating the
+     *          directory.
+     */
+    public static Path createTempDirectory(String prefix,
+                                           FileAttribute<?>... attrs)
+        throws IOException
+    {
+        return TempFileHelper.createTempDirectory(null, prefix, attrs);
+    }
+
+    /**
+     * Creates a symbolic link to a target <i>(optional operation)</i>.
+     *
+     * <p> The {@code target} parameter is the target of the link. It may be an
+     * {@link Path#isAbsolute absolute} or relative path and may not exist. When
+     * the target is a relative path then file system operations on the resulting
+     * link are relative to the path of the link.
+     *
+     * <p> The {@code attrs} parameter is optional {@link FileAttribute
+     * attributes} to set atomically when creating the link. Each attribute is
+     * identified by its {@link FileAttribute#name name}. If more than one attribute
+     * of the same name is included in the array then all but the last occurrence
+     * is ignored.
+     *
+     * <p> Where symbolic links are supported, but the underlying {@link FileStore}
+     * does not support symbolic links, then this may fail with an {@link
+     * IOException}. Additionally, some operating systems may require that the
+     * Java virtual machine be started with implementation specific privileges to
+     * create symbolic links, in which case this method may throw {@code IOException}.
+     *
+     * @param   link
+     *          the path of the symbolic link to create
+     * @param   target
+     *          the target of the symbolic link
+     * @param   attrs
+     *          the array of attributes to set atomically when creating the
+     *          symbolic link
+     *
+     * @return  the path to the symbolic link
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support symbolic links or the
+     *          array contains an attribute that cannot be set atomically when
+     *          creating the symbolic link
+     * @throws  FileAlreadyExistsException
+     *          if a file with the name already exists <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it denies {@link LinkPermission}<tt>("symbolic")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the path of the symbolic link.
+     */
+    public static Path createSymbolicLink(Path link, Path target,
+                                          FileAttribute<?>... attrs)
+        throws IOException
+    {
+        provider(link).createSymbolicLink(link, target, attrs);
+        return link;
+    }
+
+    /**
+     * Creates a new link (directory entry) for an existing file <i>(optional
+     * operation)</i>.
+     *
+     * <p> The {@code link} parameter locates the directory entry to create.
+     * The {@code existing} parameter is the path to an existing file. This
+     * method creates a new directory entry for the file so that it can be
+     * accessed using {@code link} as the path. On some file systems this is
+     * known as creating a "hard link". Whether the file attributes are
+     * maintained for the file or for each directory entry is file system
+     * specific and therefore not specified. Typically, a file system requires
+     * that all links (directory entries) for a file be on the same file system.
+     * Furthermore, on some platforms, the Java virtual machine may require to
+     * be started with implementation specific privileges to create hard links
+     * or to create links to directories.
+     *
+     * @param   link
+     *          the link (directory entry) to create
+     * @param   existing
+     *          a path to an existing file
+     *
+     * @return  the path to the link (directory entry)
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support adding an existing file
+     *          to a directory
+     * @throws  FileAlreadyExistsException
+     *          if the entry could not otherwise be created because a file of
+     *          that name already exists <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it denies {@link LinkPermission}<tt>("hard")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to either the link or the
+     *          existing file.
+     */
+    public static Path createLink(Path link, Path existing) throws IOException {
+        provider(link).createLink(link, existing);
+        return link;
+    }
+
+    /**
+     * Deletes a file.
+     *
+     * <p> An implementation may require to examine the file to determine if the
+     * file is a directory. Consequently this method may not be atomic with respect
+     * to other file system operations.  If the file is a symbolic link then the
+     * symbolic link itself, not the final target of the link, is deleted.
+     *
+     * <p> If the file is a directory then the directory must be empty. In some
+     * implementations a directory has entries for special files or links that
+     * are created when the directory is created. In such implementations a
+     * directory is considered empty when only the special entries exist.
+     * This method can be used with the {@link #walkFileTree walkFileTree}
+     * method to delete a directory and all entries in the directory, or an
+     * entire <i>file-tree</i> where required.
+     *
+     * <p> On some operating systems it may not be possible to remove a file when
+     * it is open and in use by this Java virtual machine or other programs.
+     *
+     * @param   path
+     *          the path to the file to delete
+     *
+     * @throws  NoSuchFileException
+     *          if the file does not exist <i>(optional specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          if the file is a directory and could not otherwise be deleted
+     *          because the directory is not empty <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkDelete(String)} method
+     *          is invoked to check delete access to the file
+     */
+    public static void delete(Path path) throws IOException {
+        provider(path).delete(path);
+    }
+
+    /**
+     * Deletes a file if it exists.
+     *
+     * <p> As with the {@link #delete(Path) delete(Path)} method, an
+     * implementation may need to examine the file to determine if the file is a
+     * directory. Consequently this method may not be atomic with respect to
+     * other file system operations.  If the file is a symbolic link, then the
+     * symbolic link itself, not the final target of the link, is deleted.
+     *
+     * <p> If the file is a directory then the directory must be empty. In some
+     * implementations a directory has entries for special files or links that
+     * are created when the directory is created. In such implementations a
+     * directory is considered empty when only the special entries exist.
+     *
+     * <p> On some operating systems it may not be possible to remove a file when
+     * it is open and in use by this Java virtual machine or other programs.
+     *
+     * @param   path
+     *          the path to the file to delete
+     *
+     * @return  {@code true} if the file was deleted by this method; {@code
+     *          false} if the file could not be deleted because it did not
+     *          exist
+     *
+     * @throws  DirectoryNotEmptyException
+     *          if the file is a directory and could not otherwise be deleted
+     *          because the directory is not empty <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkDelete(String)} method
+     *          is invoked to check delete access to the file.
+     */
+    public static boolean deleteIfExists(Path path) throws IOException {
+        return provider(path).deleteIfExists(path);
+    }
+
+    // -- Copying and moving files --
+
+    /**
+     * Copy a file to a target file.
+     *
+     * <p> This method copies a file to the target file with the {@code
+     * options} parameter specifying how the copy is performed. By default, the
+     * copy fails if the target file already exists or is a symbolic link,
+     * except if the source and target are the {@link #isSameFile same} file, in
+     * which case the method completes without copying the file. File attributes
+     * are not required to be copied to the target file. If symbolic links are
+     * supported, and the file is a symbolic link, then the final target of the
+     * link is copied. If the file is a directory then it creates an empty
+     * directory in the target location (entries in the directory are not
+     * copied). This method can be used with the {@link #walkFileTree
+     * walkFileTree} method to copy a directory and all entries in the directory,
+     * or an entire <i>file-tree</i> where required.
+     *
+     * <p> The {@code options} parameter may include any of the following:
+     *
+     * <table border=1 cellpadding=5 summary="">
+     * <tr> <th>Option</th> <th>Description</th> </tr>
+     * <tr>
+     *   <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
+     *   <td> If the target file exists, then the target file is replaced if it
+     *     is not a non-empty directory. If the target file exists and is a
+     *     symbolic link, then the symbolic link itself, not the target of
+     *     the link, is replaced. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardCopyOption#COPY_ATTRIBUTES COPY_ATTRIBUTES} </td>
+     *   <td> Attempts to copy the file attributes associated with this file to
+     *     the target file. The exact file attributes that are copied is platform
+     *     and file system dependent and therefore unspecified. Minimally, the
+     *     {@link BasicFileAttributes#lastModifiedTime last-modified-time} is
+     *     copied to the target file if supported by both the source and target
+     *     file stores. Copying of file timestamps may result in precision
+     *     loss. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} </td>
+     *   <td> Symbolic links are not followed. If the file is a symbolic link,
+     *     then the symbolic link itself, not the target of the link, is copied.
+     *     It is implementation specific if file attributes can be copied to the
+     *     new link. In other words, the {@code COPY_ATTRIBUTES} option may be
+     *     ignored when copying a symbolic link. </td>
+     * </tr>
+     * </table>
+     *
+     * <p> An implementation of this interface may support additional
+     * implementation specific options.
+     *
+     * <p> Copying a file is not an atomic operation. If an {@link IOException}
+     * is thrown, then it is possible that the target file is incomplete or some
+     * of its file attributes have not been copied from the source file. When
+     * the {@code REPLACE_EXISTING} option is specified and the target file
+     * exists, then the target file is replaced. The check for the existence of
+     * the file and the creation of the new file may not be atomic with respect
+     * to other file system activities.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to copy a file into a directory, giving it the same file
+     * name as the source file:
+     * <pre>
+     *     Path source = ...
+     *     Path newdir = ...
+     *     Files.copy(source, newdir.resolve(source.getFileName());
+     * </pre>
+     *
+     * @param   source
+     *          the path to the file to copy
+     * @param   target
+     *          the path to the target file (may be associated with a different
+     *          provider to the source path)
+     * @param   options
+     *          options specifying how the copy should be done
+     *
+     * @return  the path to the target file
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains a copy option that is not supported
+     * @throws  FileAlreadyExistsException
+     *          if the target file exists but cannot be replaced because the
+     *          {@code REPLACE_EXISTING} option is not specified <i>(optional
+     *          specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          the {@code REPLACE_EXISTING} option is specified but the file
+     *          cannot be replaced because it is a non-empty directory
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the source file, the
+     *          {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+     *          to check write access to the target file. If a symbolic link is
+     *          copied the security manager is invoked to check {@link
+     *          LinkPermission}{@code ("symbolic")}.
+     */
+    public static Path copy(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        FileSystemProvider provider = provider(source);
+        if (provider(target) == provider) {
+            // same provider
+            provider.copy(source, target, options);
+        } else {
+            // different providers
+            CopyMoveHelper.copyToForeignTarget(source, target, options);
+        }
+        return target;
+    }
+
+    /**
+     * Move or rename a file to a target file.
+     *
+     * <p> By default, this method attempts to move the file to the target
+     * file, failing if the target file exists except if the source and
+     * target are the {@link #isSameFile same} file, in which case this method
+     * has no effect. If the file is a symbolic link then the symbolic link
+     * itself, not the target of the link, is moved. This method may be
+     * invoked to move an empty directory. In some implementations a directory
+     * has entries for special files or links that are created when the
+     * directory is created. In such implementations a directory is considered
+     * empty when only the special entries exist. When invoked to move a
+     * directory that is not empty then the directory is moved if it does not
+     * require moving the entries in the directory.  For example, renaming a
+     * directory on the same {@link FileStore} will usually not require moving
+     * the entries in the directory. When moving a directory requires that its
+     * entries be moved then this method fails (by throwing an {@code
+     * IOException}). To move a <i>file tree</i> may involve copying rather
+     * than moving directories and this can be done using the {@link
+     * #copy copy} method in conjunction with the {@link
+     * #walkFileTree Files.walkFileTree} utility method.
+     *
+     * <p> The {@code options} parameter may include any of the following:
+     *
+     * <table border=1 cellpadding=5 summary="">
+     * <tr> <th>Option</th> <th>Description</th> </tr>
+     * <tr>
+     *   <td> {@link StandardCopyOption#REPLACE_EXISTING REPLACE_EXISTING} </td>
+     *   <td> If the target file exists, then the target file is replaced if it
+     *     is not a non-empty directory. If the target file exists and is a
+     *     symbolic link, then the symbolic link itself, not the target of
+     *     the link, is replaced. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} </td>
+     *   <td> The move is performed as an atomic file system operation and all
+     *     other options are ignored. If the target file exists then it is
+     *     implementation specific if the existing file is replaced or this method
+     *     fails by throwing an {@link IOException}. If the move cannot be
+     *     performed as an atomic file system operation then {@link
+     *     AtomicMoveNotSupportedException} is thrown. This can arise, for
+     *     example, when the target location is on a different {@code FileStore}
+     *     and would require that the file be copied, or target location is
+     *     associated with a different provider to this object. </td>
+     * </table>
+     *
+     * <p> An implementation of this interface may support additional
+     * implementation specific options.
+     *
+     * <p> Moving a file will copy the {@link
+     * BasicFileAttributes#lastModifiedTime last-modified-time} to the target
+     * file if supported by both source and target file stores. Copying of file
+     * timestamps may result in precision loss. An implementation may also
+     * attempt to copy other file attributes but is not required to fail if the
+     * file attributes cannot be copied. When the move is performed as
+     * a non-atomic operation, and an {@code IOException} is thrown, then the
+     * state of the files is not defined. The original file and the target file
+     * may both exist, the target file may be incomplete or some of its file
+     * attributes may not been copied from the original file.
+     *
+     * <p> <b>Usage Examples:</b>
+     * Suppose we want to rename a file to "newname", keeping the file in the
+     * same directory:
+     * <pre>
+     *     Path source = ...
+     *     Files.move(source, source.resolveSibling("newname"));
+     * </pre>
+     * Alternatively, suppose we want to move a file to new directory, keeping
+     * the same file name, and replacing any existing file of that name in the
+     * directory:
+     * <pre>
+     *     Path source = ...
+     *     Path newdir = ...
+     *     Files.move(source, newdir.resolve(source.getFileName()), REPLACE_EXISTING);
+     * </pre>
+     *
+     * @param   source
+     *          the path to the file to move
+     * @param   target
+     *          the path to the target file (may be associated with a different
+     *          provider to the source path)
+     * @param   options
+     *          options specifying how the move should be done
+     *
+     * @return  the path to the target file
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains a copy option that is not supported
+     * @throws  FileAlreadyExistsException
+     *          if the target file exists but cannot be replaced because the
+     *          {@code REPLACE_EXISTING} option is not specified <i>(optional
+     *          specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          the {@code REPLACE_EXISTING} option is specified but the file
+     *          cannot be replaced because it is a non-empty directory
+     *          <i>(optional specific exception)</i>
+     * @throws  AtomicMoveNotSupportedException
+     *          if the options array contains the {@code ATOMIC_MOVE} option but
+     *          the file cannot be moved as an atomic file system operation.
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to both the source and
+     *          target file.
+     */
+    public static Path move(Path source, Path target, CopyOption... options)
+        throws IOException
+    {
+        FileSystemProvider provider = provider(source);
+        if (provider(target) == provider) {
+            // same provider
+            provider.move(source, target, options);
+        } else {
+            // different providers
+            CopyMoveHelper.moveToForeignTarget(source, target, options);
+        }
+        return target;
+    }
+
+    // -- Miscellenous --
+
+    /**
+     * Reads the target of a symbolic link <i>(optional operation)</i>.
+     *
+     * <p> If the file system supports <a href="package-summary.html#links">symbolic
+     * links</a> then this method is used to read the target of the link, failing
+     * if the file is not a symbolic link. The target of the link need not exist.
+     * The returned {@code Path} object will be associated with the same file
+     * system as {@code link}.
+     *
+     * @param   link
+     *          the path to the symbolic link
+     *
+     * @return  a {@code Path} object representing the target of the link
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support symbolic links
+     * @throws  NotLinkException
+     *          if the target could otherwise not be read because the file
+     *          is not a symbolic link <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it checks that {@code FilePermission} has been
+     *          granted with the "{@code readlink}" action to read the link.
+     */
+    public static Path readSymbolicLink(Path link) throws IOException {
+        return provider(link).readSymbolicLink(link);
+    }
+
+    /**
+     * Returns the {@link FileStore} representing the file store where a file
+     * is located.
+     *
+     * <p> Once a reference to the {@code FileStore} is obtained it is
+     * implementation specific if operations on the returned {@code FileStore},
+     * or {@link FileStoreAttributeView} objects obtained from it, continue
+     * to depend on the existence of the file. In particular the behavior is not
+     * defined for the case that the file is deleted or moved to a different
+     * file store.
+     *
+     * @param   path
+     *          the path to the file
+     *
+     * @return  the file store where the file is stored
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file, and in
+     *          addition it checks {@link RuntimePermission}<tt>
+     *          ("getFileStoreAttributes")</tt>
+     */
+    public static FileStore getFileStore(Path path) throws IOException {
+        return provider(path).getFileStore(path);
+    }
+
+    /**
+     * Tests if two paths locate the same file.
+     *
+     * <p> If both {@code Path} objects are {@link Path#equals(Object) equal}
+     * then this method returns {@code true} without checking if the file exists.
+     * If the two {@code Path} objects are associated with different providers
+     * then this method returns {@code false}. Otherwise, this method checks if
+     * both {@code Path} objects locate the same file, and depending on the
+     * implementation, may require to open or access both files.
+     *
+     * <p> If the file system and files remain static, then this method implements
+     * an equivalence relation for non-null {@code Paths}.
+     * <ul>
+     * <li>It is <i>reflexive</i>: for {@code Path} {@code f},
+     *     {@code isSameFile(f,f)} should return {@code true}.
+     * <li>It is <i>symmetric</i>: for two {@code Paths} {@code f} and {@code g},
+     *     {@code isSameFile(f,g)} will equal {@code isSameFile(g,f)}.
+     * <li>It is <i>transitive</i>: for three {@code Paths}
+     *     {@code f}, {@code g}, and {@code h}, if {@code isSameFile(f,g)} returns
+     *     {@code true} and {@code isSameFile(g,h)} returns {@code true}, then
+     *     {@code isSameFile(f,h)} will return return {@code true}.
+     * </ul>
+     *
+     * @param   path
+     *          one path to the file
+     * @param   path2
+     *          the other path
+     *
+     * @return  {@code true} if, and only if, the two paths locate the same file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to both files.
+     *
+     * @see java.nio.file.attribute.BasicFileAttributes#fileKey
+     */
+    public static boolean isSameFile(Path path, Path path2) throws IOException {
+        return provider(path).isSameFile(path, path2);
+    }
+
+    /**
+     * Tells whether or not a file is considered <em>hidden</em>. The exact
+     * definition of hidden is platform or provider dependent. On UNIX for
+     * example a file is considered to be hidden if its name begins with a
+     * period character ('.'). On Windows a file is considered hidden if it
+     * isn't a directory and the DOS {@link DosFileAttributes#isHidden hidden}
+     * attribute is set.
+     *
+     * <p> Depending on the implementation this method may require to access
+     * the file system to determine if the file is considered hidden.
+     *
+     * @param   path
+     *          the path to the file to test
+     *
+     * @return  {@code true} if the file is considered hidden
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    public static boolean isHidden(Path path) throws IOException {
+        return provider(path).isHidden(path);
+    }
+
+    // lazy loading of default and installed file type detectors
+    private static class FileTypeDetectors{
+        static final FileTypeDetector defaultFileTypeDetector =
+            createDefaultFileTypeDetector();
+        static final List<FileTypeDetector> installeDetectors =
+            loadInstalledDetectors();
+
+        // creates the default file type detector
+        private static FileTypeDetector createDefaultFileTypeDetector() {
+            return AccessController
+                .doPrivileged(new PrivilegedAction<FileTypeDetector>() {
+                    @Override public FileTypeDetector run() {
+                        return sun.nio.fs.DefaultFileTypeDetector.create();
+                }});
+        }
+
+        // loads all installed file type detectors
+        private static List<FileTypeDetector> loadInstalledDetectors() {
+            return AccessController
+                .doPrivileged(new PrivilegedAction<List<FileTypeDetector>>() {
+                    @Override public List<FileTypeDetector> run() {
+                        List<FileTypeDetector> list = new ArrayList<>();
+                        ServiceLoader<FileTypeDetector> loader = ServiceLoader
+                            .load(FileTypeDetector.class, ClassLoader.getSystemClassLoader());
+                        for (FileTypeDetector detector: loader) {
+                            list.add(detector);
+                        }
+                        return list;
+                }});
+        }
+    }
+
+    /**
+     * Probes the content type of a file.
+     *
+     * <p> This method uses the installed {@link FileTypeDetector} implementations
+     * to probe the given file to determine its content type. Each file type
+     * detector's {@link FileTypeDetector#probeContentType probeContentType} is
+     * invoked, in turn, to probe the file type. If the file is recognized then
+     * the content type is returned. If the file is not recognized by any of the
+     * installed file type detectors then a system-default file type detector is
+     * invoked to guess the content type.
+     *
+     * <p> A given invocation of the Java virtual machine maintains a system-wide
+     * list of file type detectors. Installed file type detectors are loaded
+     * using the service-provider loading facility defined by the {@link ServiceLoader}
+     * class. Installed file type detectors are loaded using the system class
+     * loader. If the system class loader cannot be found then the extension class
+     * loader is used; If the extension class loader cannot be found then the
+     * bootstrap class loader is used. File type detectors are typically installed
+     * by placing them in a JAR file on the application class path or in the
+     * extension directory, the JAR file contains a provider-configuration file
+     * named {@code java.nio.file.spi.FileTypeDetector} in the resource directory
+     * {@code META-INF/services}, and the file lists one or more fully-qualified
+     * names of concrete subclass of {@code FileTypeDetector } that have a zero
+     * argument constructor. If the process of locating or instantiating the
+     * installed file type detectors fails then an unspecified error is thrown.
+     * The ordering that installed providers are located is implementation
+     * specific.
+     *
+     * <p> The return value of this method is the string form of the value of a
+     * Multipurpose Internet Mail Extension (MIME) content type as
+     * defined by <a href="http://www.ietf.org/rfc/rfc2045.txt"><i>RFC&nbsp;2045:
+     * Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet
+     * Message Bodies</i></a>. The string is guaranteed to be parsable according
+     * to the grammar in the RFC.
+     *
+     * @param   path
+     *          the path to the file to probe
+     *
+     * @return  The content type of the file, or {@code null} if the content
+     *          type cannot be determined
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an unspecified
+     *          permission required by a file type detector implementation.
+     */
+    public static String probeContentType(Path path)
+        throws IOException
+    {
+        // try installed file type detectors
+        for (FileTypeDetector detector: FileTypeDetectors.installeDetectors) {
+            String result = detector.probeContentType(path);
+            if (result != null)
+                return result;
+        }
+
+        // fallback to default
+        return FileTypeDetectors.defaultFileTypeDetector.probeContentType(path);
+    }
+
+    // -- File Attributes --
+
+    /**
+     * Returns a file attribute view of a given type.
+     *
+     * <p> A file attribute view provides a read-only or updatable view of a
+     * set of file attributes. This method is intended to be used where the file
+     * attribute view defines type-safe methods to read or update the file
+     * attributes. The {@code type} parameter is the type of the attribute view
+     * required and the method returns an instance of that type if supported.
+     * The {@link BasicFileAttributeView} type supports access to the basic
+     * attributes of a file. Invoking this method to select a file attribute
+     * view of that type will always return an instance of that class.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled by the resulting file attribute view for the case that the
+     * file is a symbolic link. By default, symbolic links are followed. If the
+     * option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is present then
+     * symbolic links are not followed. This option is ignored by implementations
+     * that do not support symbolic links.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want read or set a file's ACL, if supported:
+     * <pre>
+     *     Path path = ...
+     *     AclFileAttributeView view = Files.getFileAttributeView(path, AclFileAttributeView.class);
+     *     if (view != null) {
+     *         List&lt;AclEntry&gt; acl = view.getAcl();
+     *         :
+     *     }
+     * </pre>
+     *
+     * @param   <V>
+     *          The {@code FileAttributeView} type
+     * @param   path
+     *          the path to the file
+     * @param   type
+     *          the {@code Class} object corresponding to the file attribute view
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a file attribute view of the specified type, or {@code null} if
+     *          the attribute view type is not available
+     */
+    public static <V extends FileAttributeView> V getFileAttributeView(Path path,
+                                                                       Class<V> type,
+                                                                       LinkOption... options)
+    {
+        return provider(path).getFileAttributeView(path, type, options);
+    }
+
+    /**
+     * Reads a file's attributes as a bulk operation.
+     *
+     * <p> The {@code type} parameter is the type of the attributes required
+     * and this method returns an instance of that type if supported. All
+     * implementations support a basic set of file attributes and so invoking
+     * this method with a  {@code type} parameter of {@code
+     * BasicFileAttributes.class} will not throw {@code
+     * UnsupportedOperationException}.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> It is implementation specific if all file attributes are read as an
+     * atomic operation with respect to other file system operations.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to read a file's attributes in bulk:
+     * <pre>
+     *    Path path = ...
+     *    BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
+     * </pre>
+     * Alternatively, suppose we want to read file's POSIX attributes without
+     * following symbolic links:
+     * <pre>
+     *    PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class, NOFOLLOW_LINKS);
+     * </pre>
+     *
+     * @param   <A>
+     *          The {@code BasicFileAttributes} type
+     * @param   path
+     *          the path to the file
+     * @param   type
+     *          the {@code Class} of the file attributes required
+     *          to read
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  the file attributes
+     *
+     * @throws  UnsupportedOperationException
+     *          if an attributes of the given type are not supported
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file. If this
+     *          method is invoked to read security sensitive attributes then the
+     *          security manager may be invoke to check for additional permissions.
+     */
+    public static <A extends BasicFileAttributes> A readAttributes(Path path,
+                                                                   Class<A> type,
+                                                                   LinkOption... options)
+        throws IOException
+    {
+        return provider(path).readAttributes(path, type, options);
+    }
+
+    /**
+     * Sets the value of a file attribute.
+     *
+     * <p> The {@code attribute} parameter identifies the attribute to be set
+     * and takes the form:
+     * <blockquote>
+     * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
+     * </blockquote>
+     * where square brackets [...] delineate an optional component and the
+     * character {@code ':'} stands for itself.
+     *
+     * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+     * FileAttributeView} that identifies a set of file attributes. If not
+     * specified then it defaults to {@code "basic"}, the name of the file
+     * attribute view that identifies the basic set of file attributes common to
+     * many file systems. <i>attribute-name</i> is the name of the attribute
+     * within the set.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is set. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to set the DOS "hidden" attribute:
+     * <pre>
+     *    Path path = ...
+     *    Files.setAttribute(path, "dos:hidden", true);
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file
+     * @param   attribute
+     *          the attribute to set
+     * @param   value
+     *          the attribute value
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  the {@code path} parameter
+     *
+     * @throws  UnsupportedOperationException
+     *          if the attribute view is not available
+     * @throws  IllegalArgumentException
+     *          if the attribute name is not specified, or is not recognized, or
+     *          the attribute value is of the correct type but has an
+     *          inappropriate value
+     * @throws  ClassCastException
+     *          if the attribute value is not of the expected type or is a
+     *          collection containing elements that are not of the expected
+     *          type
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file. If this method is invoked
+     *          to set security sensitive attributes then the security manager
+     *          may be invoked to check for additional permissions.
+     */
+    public static Path setAttribute(Path path, String attribute, Object value,
+                                    LinkOption... options)
+        throws IOException
+    {
+        provider(path).setAttribute(path, attribute, value, options);
+        return path;
+    }
+
+    /**
+     * Reads the value of a file attribute.
+     *
+     * <p> The {@code attribute} parameter identifies the attribute to be read
+     * and takes the form:
+     * <blockquote>
+     * [<i>view-name</i><b>:</b>]<i>attribute-name</i>
+     * </blockquote>
+     * where square brackets [...] delineate an optional component and the
+     * character {@code ':'} stands for itself.
+     *
+     * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+     * FileAttributeView} that identifies a set of file attributes. If not
+     * specified then it defaults to {@code "basic"}, the name of the file
+     * attribute view that identifies the basic set of file attributes common to
+     * many file systems. <i>attribute-name</i> is the name of the attribute.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we require the user ID of the file owner on a system that
+     * supports a "{@code unix}" view:
+     * <pre>
+     *    Path path = ...
+     *    int uid = (Integer)Files.getAttribute(path, "unix:uid");
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file
+     * @param   attribute
+     *          the attribute to read
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  the attribute value
+     *
+     * @throws  UnsupportedOperationException
+     *          if the attribute view is not available
+     * @throws  IllegalArgumentException
+     *          if the attribute name is not specified or is not recognized
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file. If this method is invoked
+     *          to read security sensitive attributes then the security manager
+     *          may be invoked to check for additional permissions.
+     */
+    public static Object getAttribute(Path path, String attribute,
+                                      LinkOption... options)
+        throws IOException
+    {
+        // only one attribute should be read
+        if (attribute.indexOf('*') >= 0 || attribute.indexOf(',') >= 0)
+            throw new IllegalArgumentException(attribute);
+        Map<String,Object> map = readAttributes(path, attribute, options);
+        assert map.size() == 1;
+        String name;
+        int pos = attribute.indexOf(':');
+        if (pos == -1) {
+            name = attribute;
+        } else {
+            name = (pos == attribute.length()) ? "" : attribute.substring(pos+1);
+        }
+        return map.get(name);
+    }
+
+    /**
+     * Reads a set of file attributes as a bulk operation.
+     *
+     * <p> The {@code attributes} parameter identifies the attributes to be read
+     * and takes the form:
+     * <blockquote>
+     * [<i>view-name</i><b>:</b>]<i>attribute-list</i>
+     * </blockquote>
+     * where square brackets [...] delineate an optional component and the
+     * character {@code ':'} stands for itself.
+     *
+     * <p> <i>view-name</i> is the {@link FileAttributeView#name name} of a {@link
+     * FileAttributeView} that identifies a set of file attributes. If not
+     * specified then it defaults to {@code "basic"}, the name of the file
+     * attribute view that identifies the basic set of file attributes common to
+     * many file systems.
+     *
+     * <p> The <i>attribute-list</i> component is a comma separated list of
+     * zero or more names of attributes to read. If the list contains the value
+     * {@code "*"} then all attributes are read. Attributes that are not supported
+     * are ignored and will not be present in the returned map. It is
+     * implementation specific if all attributes are read as an atomic operation
+     * with respect to other file system operations.
+     *
+     * <p> The following examples demonstrate possible values for the {@code
+     * attributes} parameter:
+     *
+     * <blockquote>
+     * <table border="0" summary="Possible values">
+     * <tr>
+     *   <td> {@code "*"} </td>
+     *   <td> Read all {@link BasicFileAttributes basic-file-attributes}. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@code "size,lastModifiedTime,lastAccessTime"} </td>
+     *   <td> Reads the file size, last modified time, and last access time
+     *     attributes. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@code "posix:*"} </td>
+     *   <td> Read all {@link PosixFileAttributes POSIX-file-attributes}. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@code "posix:permissions,owner,size"} </td>
+     *   <td> Reads the POSX file permissions, owner, and file size. </td>
+     * </tr>
+     * </table>
+     * </blockquote>
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   attributes
+     *          the attributes to read
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a map of the attributes returned; The map's keys are the
+     *          attribute names, its values are the attribute values
+     *
+     * @throws  UnsupportedOperationException
+     *          if the attribute view is not available
+     * @throws  IllegalArgumentException
+     *          if no attributes are specified or an unrecognized attributes is
+     *          specified
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file. If this method is invoked
+     *          to read security sensitive attributes then the security manager
+     *          may be invoke to check for additional permissions.
+     */
+    public static Map<String,Object> readAttributes(Path path, String attributes,
+                                                    LinkOption... options)
+        throws IOException
+    {
+        return provider(path).readAttributes(path, attributes, options);
+    }
+
+    /**
+     * Returns a file's POSIX file permissions.
+     *
+     * <p> The {@code path} parameter is associated with a {@code FileSystem}
+     * that supports the {@link PosixFileAttributeView}. This attribute view
+     * provides access to file attributes commonly associated with files on file
+     * systems used by operating systems that implement the Portable Operating
+     * System Interface (POSIX) family of standards.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  the file permissions
+     *
+     * @throws  UnsupportedOperationException
+     *          if the associated file system does not support the {@code
+     *          PosixFileAttributeView}
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     */
+    public static Set<PosixFilePermission> getPosixFilePermissions(Path path,
+                                                                   LinkOption... options)
+        throws IOException
+    {
+        return readAttributes(path, PosixFileAttributes.class, options).permissions();
+    }
+
+    /**
+     * Sets a file's POSIX permissions.
+     *
+     * <p> The {@code path} parameter is associated with a {@code FileSystem}
+     * that supports the {@link PosixFileAttributeView}. This attribute view
+     * provides access to file attributes commonly associated with files on file
+     * systems used by operating systems that implement the Portable Operating
+     * System Interface (POSIX) family of standards.
+     *
+     * @param   path
+     *          The path to the file
+     * @param   perms
+     *          The new set of permissions
+     *
+     * @return  The path
+     *
+     * @throws  UnsupportedOperationException
+     *          if the associated file system does not support the {@code
+     *          PosixFileAttributeView}
+     * @throws  ClassCastException
+     *          if the sets contains elements that are not of type {@code
+     *          PosixFilePermission}
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     */
+    public static Path setPosixFilePermissions(Path path,
+                                               Set<PosixFilePermission> perms)
+        throws IOException
+    {
+        PosixFileAttributeView view =
+            getFileAttributeView(path, PosixFileAttributeView.class);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        view.setPermissions(perms);
+        return path;
+    }
+
+    /**
+     * Returns the owner of a file.
+     *
+     * <p> The {@code path} parameter is associated with a file system that
+     * supports {@link FileOwnerAttributeView}. This file attribute view provides
+     * access to a file attribute that is the owner of the file.
+     *
+     * @param   path
+     *          The path to the file
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  A user principal representing the owner of the file
+     *
+     * @throws  UnsupportedOperationException
+     *          if the associated file system does not support the {@code
+     *          FileOwnerAttributeView}
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     */
+    public static UserPrincipal getOwner(Path path, LinkOption... options) throws IOException {
+        FileOwnerAttributeView view =
+            getFileAttributeView(path, FileOwnerAttributeView.class, options);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        return view.getOwner();
+    }
+
+    /**
+     * Updates the file owner.
+     *
+     * <p> The {@code path} parameter is associated with a file system that
+     * supports {@link FileOwnerAttributeView}. This file attribute view provides
+     * access to a file attribute that is the owner of the file.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to make "joe" the owner of a file:
+     * <pre>
+     *     Path path = ...
+     *     UserPrincipalLookupService lookupService =
+     *         provider(path).getUserPrincipalLookupService();
+     *     UserPrincipal joe = lookupService.lookupPrincipalByName("joe");
+     *     Files.setOwner(path, joe);
+     * </pre>
+     *
+     * @param   path
+     *          The path to the file
+     * @param   owner
+     *          The new file owner
+     *
+     * @return  The path
+     *
+     * @throws  UnsupportedOperationException
+     *          if the associated file system does not support the {@code
+     *          FileOwnerAttributeView}
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     *
+     * @see FileSystem#getUserPrincipalLookupService
+     * @see java.nio.file.attribute.UserPrincipalLookupService
+     */
+    public static Path setOwner(Path path, UserPrincipal owner)
+        throws IOException
+    {
+        FileOwnerAttributeView view =
+            getFileAttributeView(path, FileOwnerAttributeView.class);
+        if (view == null)
+            throw new UnsupportedOperationException();
+        view.setOwner(owner);
+        return path;
+    }
+
+    /**
+     * Tests whether a file is a symbolic link.
+     *
+     * <p> Where it is required to distinguish an I/O exception from the case
+     * that the file is not a symbolic link then the file attributes can be
+     * read with the {@link #readAttributes(Path,Class,LinkOption[])
+     * readAttributes} method and the file type tested with the {@link
+     * BasicFileAttributes#isSymbolicLink} method.
+     *
+     * @param   path  The path to the file
+     *
+     * @return  {@code true} if the file is a symbolic link; {@code false} if
+     *          the file does not exist, is not a symbolic link, or it cannot
+     *          be determined if the file is a symbolic link or not.
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file.
+     */
+    public static boolean isSymbolicLink(Path path) {
+        try {
+            return readAttributes(path,
+                                  BasicFileAttributes.class,
+                                  LinkOption.NOFOLLOW_LINKS).isSymbolicLink();
+        } catch (IOException ioe) {
+            return false;
+        }
+    }
+
+    /**
+     * Tests whether a file is a directory.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> Where it is required to distinguish an I/O exception from the case
+     * that the file is not a directory then the file attributes can be
+     * read with the {@link #readAttributes(Path,Class,LinkOption[])
+     * readAttributes} method and the file type tested with the {@link
+     * BasicFileAttributes#isDirectory} method.
+     *
+     * @param   path
+     *          the path to the file to test
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  {@code true} if the file is a directory; {@code false} if
+     *          the file does not exist, is not a directory, or it cannot
+     *          be determined if the file is a directory or not.
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file.
+     */
+    public static boolean isDirectory(Path path, LinkOption... options) {
+        try {
+            return readAttributes(path, BasicFileAttributes.class, options).isDirectory();
+        } catch (IOException ioe) {
+            return false;
+        }
+    }
+
+    /**
+     * Tests whether a file is a regular file with opaque content.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> Where it is required to distinguish an I/O exception from the case
+     * that the file is not a regular file then the file attributes can be
+     * read with the {@link #readAttributes(Path,Class,LinkOption[])
+     * readAttributes} method and the file type tested with the {@link
+     * BasicFileAttributes#isRegularFile} method.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  {@code true} if the file is a regular file; {@code false} if
+     *          the file does not exist, is not a regular file, or it
+     *          cannot be determined if the file is a regular file or not.
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file.
+     */
+    public static boolean isRegularFile(Path path, LinkOption... options) {
+        try {
+            return readAttributes(path, BasicFileAttributes.class, options).isRegularFile();
+        } catch (IOException ioe) {
+            return false;
+        }
+    }
+
+    /**
+     * Returns a file's last modified time.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed and the file attribute of the final target
+     * of the link is read. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a {@code FileTime} representing the time the file was last
+     *          modified, or an implementation specific default when a time
+     *          stamp to indicate the time of last modification is not supported
+     *          by the file system
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file.
+     *
+     * @see BasicFileAttributes#lastModifiedTime
+     */
+    public static FileTime getLastModifiedTime(Path path, LinkOption... options)
+        throws IOException
+    {
+        return readAttributes(path, BasicFileAttributes.class, options).lastModifiedTime();
+    }
+
+    /**
+     * Updates a file's last modified time attribute. The file time is converted
+     * to the epoch and precision supported by the file system. Converting from
+     * finer to coarser granularities result in precision loss. The behavior of
+     * this method when attempting to set the last modified time when it is not
+     * supported by the file system or is outside the range supported by the
+     * underlying file store is not defined. It may or not fail by throwing an
+     * {@code IOException}.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to set the last modified time to the current time:
+     * <pre>
+     *    Path path = ...
+     *    FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+     *    Files.setLastModifiedTime(path, now);
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file
+     * @param   time
+     *          the new last modified time
+     *
+     * @return  the path
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, the security manager's {@link
+     *          SecurityManager#checkWrite(String) checkWrite} method is invoked
+     *          to check write access to file
+     *
+     * @see BasicFileAttributeView#setTimes
+     */
+    public static Path setLastModifiedTime(Path path, FileTime time)
+        throws IOException
+    {
+        getFileAttributeView(path, BasicFileAttributeView.class)
+            .setTimes(time, null, null);
+        return path;
+    }
+
+    /**
+     * Returns the size of a file (in bytes). The size may differ from the
+     * actual size on the file system due to compression, support for sparse
+     * files, or other reasons. The size of files that are not {@link
+     * #isRegularFile regular} files is implementation specific and
+     * therefore unspecified.
+     *
+     * @param   path
+     *          the path to the file
+     *
+     * @return  the file size, in bytes
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file.
+     *
+     * @see BasicFileAttributes#size
+     */
+    public static long size(Path path) throws IOException {
+        return readAttributes(path, BasicFileAttributes.class).size();
+    }
+
+    // -- Accessibility --
+
+    /**
+     * Returns {@code false} if NOFOLLOW_LINKS is present.
+     */
+    private static boolean followLinks(LinkOption... options) {
+        boolean followLinks = true;
+        for (LinkOption opt: options) {
+            if (opt == LinkOption.NOFOLLOW_LINKS) {
+                followLinks = false;
+                continue;
+            }
+            if (opt == null)
+                throw new NullPointerException();
+            throw new AssertionError("Should not get here");
+        }
+        return followLinks;
+    }
+
+    /**
+     * Tests whether a file exists.
+     *
+     * <p> The {@code options} parameter may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> Note that the result of this method is immediately outdated. If this
+     * method indicates the file exists then there is no guarantee that a
+     * subsequence access will succeed. Care should be taken when using this
+     * method in security sensitive applications.
+     *
+     * @param   path
+     *          the path to the file to test
+     * @param   options
+     *          options indicating how symbolic links are handled
+     * .
+     * @return  {@code true} if the file exists; {@code false} if the file does
+     *          not exist or its existence cannot be determined.
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} is invoked to check
+     *          read access to the file.
+     *
+     * @see #notExists
+     */
+    public static boolean exists(Path path, LinkOption... options) {
+        try {
+            if (followLinks(options)) {
+                provider(path).checkAccess(path);
+            } else {
+                // attempt to read attributes without following links
+                readAttributes(path, BasicFileAttributes.class,
+                               LinkOption.NOFOLLOW_LINKS);
+            }
+            // file exists
+            return true;
+        } catch (IOException x) {
+            // does not exist or unable to determine if file exists
+            return false;
+        }
+
+    }
+
+    /**
+     * Tests whether the file located by this path does not exist. This method
+     * is intended for cases where it is required to take action when it can be
+     * confirmed that a file does not exist.
+     *
+     * <p> The {@code options} parameter may be used to indicate how symbolic links
+     * are handled for the case that the file is a symbolic link. By default,
+     * symbolic links are followed. If the option {@link LinkOption#NOFOLLOW_LINKS
+     * NOFOLLOW_LINKS} is present then symbolic links are not followed.
+     *
+     * <p> Note that this method is not the complement of the {@link #exists
+     * exists} method. Where it is not possible to determine if a file exists
+     * or not then both methods return {@code false}. As with the {@code exists}
+     * method, the result of this method is immediately outdated. If this
+     * method indicates the file does exist then there is no guarantee that a
+     * subsequence attempt to create the file will succeed. Care should be taken
+     * when using this method in security sensitive applications.
+     *
+     * @param   path
+     *          the path to the file to test
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  {@code true} if the file does not exist; {@code false} if the
+     *          file exists or its existence cannot be determined
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String)} is invoked to check
+     *          read access to the file.
+     */
+    public static boolean notExists(Path path, LinkOption... options) {
+        try {
+            if (followLinks(options)) {
+                provider(path).checkAccess(path);
+            } else {
+                // attempt to read attributes without following links
+                readAttributes(path, BasicFileAttributes.class,
+                               LinkOption.NOFOLLOW_LINKS);
+            }
+            // file exists
+            return false;
+        } catch (NoSuchFileException x) {
+            // file confirmed not to exist
+            return true;
+        } catch (IOException x) {
+            return false;
+        }
+    }
+
+    /**
+     * Used by isReadbale, isWritable, isExecutable to test access to a file.
+     */
+    private static boolean isAccessible(Path path, AccessMode... modes) {
+        try {
+            provider(path).checkAccess(path, modes);
+            return true;
+        } catch (IOException x) {
+            return false;
+        }
+    }
+
+    /**
+     * Tests whether a file is readable. This method checks that a file exists
+     * and that this Java virtual machine has appropriate privileges that would
+     * allow it open the file for reading. Depending on the implementation, this
+     * method may require to read file permissions, access control lists, or
+     * other file attributes in order to check the effective access to the file.
+     * Consequently, this method may not be atomic with respect to other file
+     * system operations.
+     *
+     * <p> Note that the result of this method is immediately outdated, there is
+     * no guarantee that a subsequent attempt to open the file for reading will
+     * succeed (or even that it will access the same file). Care should be taken
+     * when using this method in security sensitive applications.
+     *
+     * @param   path
+     *          the path to the file to check
+     *
+     * @return  {@code true} if the file exists and is readable; {@code false}
+     *          if the file does not exist, read access would be denied because
+     *          the Java virtual machine has insufficient privileges, or access
+     *          cannot be determined
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          is invoked to check read access to the file.
+     */
+    public static boolean isReadable(Path path) {
+        return isAccessible(path, AccessMode.READ);
+    }
+
+    /**
+     * Tests whether a file is writable. This method checks that a file exists
+     * and that this Java virtual machine has appropriate privileges that would
+     * allow it open the file for writing. Depending on the implementation, this
+     * method may require to read file permissions, access control lists, or
+     * other file attributes in order to check the effective access to the file.
+     * Consequently, this method may not be atomic with respect to other file
+     * system operations.
+     *
+     * <p> Note that result of this method is immediately outdated, there is no
+     * guarantee that a subsequent attempt to open the file for writing will
+     * succeed (or even that it will access the same file). Care should be taken
+     * when using this method in security sensitive applications.
+     *
+     * @param   path
+     *          the path to the file to check
+     *
+     * @return  {@code true} if the file exists and is writable; {@code false}
+     *          if the file does not exist, write access would be denied because
+     *          the Java virtual machine has insufficient privileges, or access
+     *          cannot be determined
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          is invoked to check write access to the file.
+     */
+    public static boolean isWritable(Path path) {
+        return isAccessible(path, AccessMode.WRITE);
+    }
+
+    /**
+     * Tests whether a file is executable. This method checks that a file exists
+     * and that this Java virtual machine has appropriate privileges to {@link
+     * Runtime#exec execute} the file. The semantics may differ when checking
+     * access to a directory. For example, on UNIX systems, checking for
+     * execute access checks that the Java virtual machine has permission to
+     * search the directory in order to access file or subdirectories.
+     *
+     * <p> Depending on the implementation, this method may require to read file
+     * permissions, access control lists, or other file attributes in order to
+     * check the effective access to the file. Consequently, this method may not
+     * be atomic with respect to other file system operations.
+     *
+     * <p> Note that the result of this method is immediately outdated, there is
+     * no guarantee that a subsequent attempt to execute the file will succeed
+     * (or even that it will access the same file). Care should be taken when
+     * using this method in security sensitive applications.
+     *
+     * @param   path
+     *          the path to the file to check
+     *
+     * @return  {@code true} if the file exists and is executable; {@code false}
+     *          if the file does not exist, execute access would be denied because
+     *          the Java virtual machine has insufficient privileges, or access
+     *          cannot be determined
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkExec(String)
+     *          checkExec} is invoked to check execute access to the file.
+     */
+    public static boolean isExecutable(Path path) {
+        return isAccessible(path, AccessMode.EXECUTE);
+    }
+
+    // -- Recursive operations --
+
+    /**
+     * Walks a file tree.
+     *
+     * <p> This method walks a file tree rooted at a given starting file. The
+     * file tree traversal is <em>depth-first</em> with the given {@link
+     * FileVisitor} invoked for each file encountered. File tree traversal
+     * completes when all accessible files in the tree have been visited, or a
+     * visit method returns a result of {@link FileVisitResult#TERMINATE
+     * TERMINATE}. Where a visit method terminates due an {@code IOException},
+     * an uncaught error, or runtime exception, then the traversal is terminated
+     * and the error or exception is propagated to the caller of this method.
+     *
+     * <p> For each file encountered this method attempts to read its {@link
+     * java.nio.file.attribute.BasicFileAttributes}. If the file is not a
+     * directory then the {@link FileVisitor#visitFile visitFile} method is
+     * invoked with the file attributes. If the file attributes cannot be read,
+     * due to an I/O exception, then the {@link FileVisitor#visitFileFailed
+     * visitFileFailed} method is invoked with the I/O exception.
+     *
+     * <p> Where the file is a directory, and the directory could not be opened,
+     * then the {@code visitFileFailed} method is invoked with the I/O exception,
+     * after which, the file tree walk continues, by default, at the next
+     * <em>sibling</em> of the directory.
+     *
+     * <p> Where the directory is opened successfully, then the entries in the
+     * directory, and their <em>descendants</em> are visited. When all entries
+     * have been visited, or an I/O error occurs during iteration of the
+     * directory, then the directory is closed and the visitor's {@link
+     * FileVisitor#postVisitDirectory postVisitDirectory} method is invoked.
+     * The file tree walk then continues, by default, at the next <em>sibling</em>
+     * of the directory.
+     *
+     * <p> By default, symbolic links are not automatically followed by this
+     * method. If the {@code options} parameter contains the {@link
+     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then symbolic links are
+     * followed. When following links, and the attributes of the target cannot
+     * be read, then this method attempts to get the {@code BasicFileAttributes}
+     * of the link. If they can be read then the {@code visitFile} method is
+     * invoked with the attributes of the link (otherwise the {@code visitFileFailed}
+     * method is invoked as specified above).
+     *
+     * <p> If the {@code options} parameter contains the {@link
+     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then this method keeps
+     * track of directories visited so that cycles can be detected. A cycle
+     * arises when there is an entry in a directory that is an ancestor of the
+     * directory. Cycle detection is done by recording the {@link
+     * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
+     * or if file keys are not available, by invoking the {@link #isSameFile
+     * isSameFile} method to test if a directory is the same file as an
+     * ancestor. When a cycle is detected it is treated as an I/O error, and the
+     * {@link FileVisitor#visitFileFailed visitFileFailed} method is invoked with
+     * an instance of {@link FileSystemLoopException}.
+     *
+     * <p> The {@code maxDepth} parameter is the maximum number of levels of
+     * directories to visit. A value of {@code 0} means that only the starting
+     * file is visited, unless denied by the security manager. A value of
+     * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
+     * levels should be visited. The {@code visitFile} method is invoked for all
+     * files, including directories, encountered at {@code maxDepth}, unless the
+     * basic file attributes cannot be read, in which case the {@code
+     * visitFileFailed} method is invoked.
+     *
+     * <p> If a visitor returns a result of {@code null} then {@code
+     * NullPointerException} is thrown.
+     *
+     * <p> When a security manager is installed and it denies access to a file
+     * (or directory), then it is ignored and the visitor is not invoked for
+     * that file (or directory).
+     *
+     * @param   start
+     *          the starting file
+     * @param   options
+     *          options to configure the traversal
+     * @param   maxDepth
+     *          the maximum number of directory levels to visit
+     * @param   visitor
+     *          the file visitor to invoke for each file
+     *
+     * @return  the starting file
+     *
+     * @throws  IllegalArgumentException
+     *          if the {@code maxDepth} parameter is negative
+     * @throws  SecurityException
+     *          If the security manager denies access to the starting file.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String) checkRead} method is invoked
+     *          to check read access to the directory.
+     * @throws  IOException
+     *          if an I/O error is thrown by a visitor method
+     */
+    public static Path walkFileTree(Path start,
+                                    Set<FileVisitOption> options,
+                                    int maxDepth,
+                                    FileVisitor<? super Path> visitor)
+        throws IOException
+    {
+        /**
+         * Create a FileTreeWalker to walk the file tree, invoking the visitor
+         * for each event.
+         */
+        try (FileTreeWalker walker = new FileTreeWalker(options, maxDepth)) {
+            FileTreeWalker.Event ev = walker.walk(start);
+            do {
+                FileVisitResult result;
+                switch (ev.type()) {
+                    case ENTRY :
+                        IOException ioe = ev.ioeException();
+                        if (ioe == null) {
+                            assert ev.attributes() != null;
+                            result = visitor.visitFile(ev.file(), ev.attributes());
+                        } else {
+                            result = visitor.visitFileFailed(ev.file(), ioe);
+                        }
+                        break;
+
+                    case START_DIRECTORY :
+                        result = visitor.preVisitDirectory(ev.file(), ev.attributes());
+
+                        // if SKIP_SIBLINGS and SKIP_SUBTREE is returned then
+                        // there shouldn't be any more events for the current
+                        // directory.
+                        if (result == FileVisitResult.SKIP_SUBTREE ||
+                            result == FileVisitResult.SKIP_SIBLINGS)
+                            walker.pop();
+                        break;
+
+                    case END_DIRECTORY :
+                        result = visitor.postVisitDirectory(ev.file(), ev.ioeException());
+
+                        // SKIP_SIBLINGS is a no-op for postVisitDirectory
+                        if (result == FileVisitResult.SKIP_SIBLINGS)
+                            result = FileVisitResult.CONTINUE;
+                        break;
+
+                    default :
+                        throw new AssertionError("Should not get here");
+                }
+
+                if (Objects.requireNonNull(result) != FileVisitResult.CONTINUE) {
+                    if (result == FileVisitResult.TERMINATE) {
+                        break;
+                    } else if (result == FileVisitResult.SKIP_SIBLINGS) {
+                        walker.skipRemainingSiblings();
+                    }
+                }
+                ev = walker.next();
+            } while (ev != null);
+        }
+
+        return start;
+    }
+
+    /**
+     * Walks a file tree.
+     *
+     * <p> This method works as if invoking it were equivalent to evaluating the
+     * expression:
+     * <blockquote><pre>
+     * walkFileTree(start, EnumSet.noneOf(FileVisitOption.class), Integer.MAX_VALUE, visitor)
+     * </pre></blockquote>
+     * In other words, it does not follow symbolic links, and visits all levels
+     * of the file tree.
+     *
+     * @param   start
+     *          the starting file
+     * @param   visitor
+     *          the file visitor to invoke for each file
+     *
+     * @return  the starting file
+     *
+     * @throws  SecurityException
+     *          If the security manager denies access to the starting file.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String) checkRead} method is invoked
+     *          to check read access to the directory.
+     * @throws  IOException
+     *          if an I/O error is thrown by a visitor method
+     */
+    public static Path walkFileTree(Path start, FileVisitor<? super Path> visitor)
+        throws IOException
+    {
+        return walkFileTree(start,
+                            EnumSet.noneOf(FileVisitOption.class),
+                            Integer.MAX_VALUE,
+                            visitor);
+    }
+
+
+    // -- Utility methods for simple usages --
+
+    // buffer size used for reading and writing
+    private static final int BUFFER_SIZE = 8192;
+
+    /**
+     * Opens a file for reading, returning a {@code BufferedReader} that may be
+     * used to read text from the file in an efficient manner. Bytes from the
+     * file are decoded into characters using the specified charset. Reading
+     * commences at the beginning of the file.
+     *
+     * <p> The {@code Reader} methods that read from the file throw {@code
+     * IOException} if a malformed or unmappable byte sequence is read.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   cs
+     *          the charset to use for decoding
+     *
+     * @return  a new buffered reader, with default buffer size, to read text
+     *          from the file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs opening the file
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     *
+     * @see #readAllLines
+     */
+    public static BufferedReader newBufferedReader(Path path, Charset cs)
+        throws IOException
+    {
+        CharsetDecoder decoder = cs.newDecoder();
+        Reader reader = new InputStreamReader(newInputStream(path), decoder);
+        return new BufferedReader(reader);
+    }
+
+    /**
+     * Opens a file for reading, returning a {@code BufferedReader} to read text
+     * from the file in an efficient manner. Bytes from the file are decoded into
+     * characters using the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset
+     * charset}.
+     *
+     * <p> This method works as if invoking it were equivalent to evaluating the
+     * expression:
+     * <pre>{@code
+     * Files.newBufferedReader(path, StandardCharsets.UTF_8)
+     * }</pre>
+     *
+     * @param   path
+     *          the path to the file
+     *
+     * @return  a new buffered reader, with default buffer size, to read text
+     *          from the file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs opening the file
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     *
+     * @since 1.8
+     */
+    public static BufferedReader newBufferedReader(Path path) throws IOException {
+        return newBufferedReader(path, StandardCharsets.UTF_8);
+    }
+
+    /**
+     * Opens or creates a file for writing, returning a {@code BufferedWriter}
+     * that may be used to write text to the file in an efficient manner.
+     * The {@code options} parameter specifies how the the file is created or
+     * opened. If no options are present then this method works as if the {@link
+     * StandardOpenOption#CREATE CREATE}, {@link
+     * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+     * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+     * opens the file for writing, creating the file if it doesn't exist, or
+     * initially truncating an existing {@link #isRegularFile regular-file} to
+     * a size of {@code 0} if it exists.
+     *
+     * <p> The {@code Writer} methods to write text throw {@code IOException}
+     * if the text cannot be encoded using the specified charset.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   cs
+     *          the charset to use for encoding
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new buffered writer, with default buffer size, to write text
+     *          to the file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs opening or creating the file
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     *
+     * @see #write(Path,Iterable,Charset,OpenOption[])
+     */
+    public static BufferedWriter newBufferedWriter(Path path, Charset cs,
+                                                   OpenOption... options)
+        throws IOException
+    {
+        CharsetEncoder encoder = cs.newEncoder();
+        Writer writer = new OutputStreamWriter(newOutputStream(path, options), encoder);
+        return new BufferedWriter(writer);
+    }
+
+    /**
+     * Opens or creates a file for writing, returning a {@code BufferedWriter}
+     * to write text to the file in an efficient manner. The text is encoded
+     * into bytes for writing using the {@link StandardCharsets#UTF_8 UTF-8}
+     * {@link Charset charset}.
+     *
+     * <p> This method works as if invoking it were equivalent to evaluating the
+     * expression:
+     * <pre>{@code
+     * Files.newBufferedWriter(path, StandardCharsets.UTF_8, options)
+     * }</pre>
+     *
+     * @param   path
+     *          the path to the file
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new buffered writer, with default buffer size, to write text
+     *          to the file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs opening or creating the file
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     *
+     * @since 1.8
+     */
+    public static BufferedWriter newBufferedWriter(Path path, OpenOption... options) throws IOException {
+        return newBufferedWriter(path, StandardCharsets.UTF_8, options);
+    }
+
+    /**
+     * Reads all bytes from an input stream and writes them to an output stream.
+     */
+    private static long copy(InputStream source, OutputStream sink)
+        throws IOException
+    {
+        long nread = 0L;
+        byte[] buf = new byte[BUFFER_SIZE];
+        int n;
+        while ((n = source.read(buf)) > 0) {
+            sink.write(buf, 0, n);
+            nread += n;
+        }
+        return nread;
+    }
+
+    /**
+     * Copies all bytes from an input stream to a file. On return, the input
+     * stream will be at end of stream.
+     *
+     * <p> By default, the copy fails if the target file already exists or is a
+     * symbolic link. If the {@link StandardCopyOption#REPLACE_EXISTING
+     * REPLACE_EXISTING} option is specified, and the target file already exists,
+     * then it is replaced if it is not a non-empty directory. If the target
+     * file exists and is a symbolic link, then the symbolic link is replaced.
+     * In this release, the {@code REPLACE_EXISTING} option is the only option
+     * required to be supported by this method. Additional options may be
+     * supported in future releases.
+     *
+     * <p>  If an I/O error occurs reading from the input stream or writing to
+     * the file, then it may do so after the target file has been created and
+     * after some bytes have been read or written. Consequently the input
+     * stream may not be at end of stream and may be in an inconsistent state.
+     * It is strongly recommended that the input stream be promptly closed if an
+     * I/O error occurs.
+     *
+     * <p> This method may block indefinitely reading from the input stream (or
+     * writing to the file). The behavior for the case that the input stream is
+     * <i>asynchronously closed</i> or the thread interrupted during the copy is
+     * highly input stream and file system provider specific and therefore not
+     * specified.
+     *
+     * <p> <b>Usage example</b>: Suppose we want to capture a web page and save
+     * it to a file:
+     * <pre>
+     *     Path path = ...
+     *     URI u = URI.create("http://java.sun.com/");
+     *     try (InputStream in = u.toURL().openStream()) {
+     *         Files.copy(in, path);
+     *     }
+     * </pre>
+     *
+     * @param   in
+     *          the input stream to read from
+     * @param   target
+     *          the path to the file
+     * @param   options
+     *          options specifying how the copy should be done
+     *
+     * @return  the number of bytes read or written
+     *
+     * @throws  IOException
+     *          if an I/O error occurs when reading or writing
+     * @throws  FileAlreadyExistsException
+     *          if the target file exists but cannot be replaced because the
+     *          {@code REPLACE_EXISTING} option is not specified <i>(optional
+     *          specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          the {@code REPLACE_EXISTING} option is specified but the file
+     *          cannot be replaced because it is a non-empty directory
+     *          <i>(optional specific exception)</i>     *
+     * @throws  UnsupportedOperationException
+     *          if {@code options} contains a copy option that is not supported
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file. Where the
+     *          {@code REPLACE_EXISTING} option is specified, the security
+     *          manager's {@link SecurityManager#checkDelete(String) checkDelete}
+     *          method is invoked to check that an existing file can be deleted.
+     */
+    public static long copy(InputStream in, Path target, CopyOption... options)
+        throws IOException
+    {
+        // ensure not null before opening file
+        Objects.requireNonNull(in);
+
+        // check for REPLACE_EXISTING
+        boolean replaceExisting = false;
+        for (CopyOption opt: options) {
+            if (opt == StandardCopyOption.REPLACE_EXISTING) {
+                replaceExisting = true;
+            } else {
+                if (opt == null) {
+                    throw new NullPointerException("options contains 'null'");
+                }  else {
+                    throw new UnsupportedOperationException(opt + " not supported");
+                }
+            }
+        }
+
+        // attempt to delete an existing file
+        SecurityException se = null;
+        if (replaceExisting) {
+            try {
+                deleteIfExists(target);
+            } catch (SecurityException x) {
+                se = x;
+            }
+        }
+
+        // attempt to create target file. If it fails with
+        // FileAlreadyExistsException then it may be because the security
+        // manager prevented us from deleting the file, in which case we just
+        // throw the SecurityException.
+        OutputStream ostream;
+        try {
+            ostream = newOutputStream(target, StandardOpenOption.CREATE_NEW,
+                                              StandardOpenOption.WRITE);
+        } catch (FileAlreadyExistsException x) {
+            if (se != null)
+                throw se;
+            // someone else won the race and created the file
+            throw x;
+        }
+
+        // do the copy
+        try (OutputStream out = ostream) {
+            return copy(in, out);
+        }
+    }
+
+    /**
+     * Copies all bytes from a file to an output stream.
+     *
+     * <p> If an I/O error occurs reading from the file or writing to the output
+     * stream, then it may do so after some bytes have been read or written.
+     * Consequently the output stream may be in an inconsistent state. It is
+     * strongly recommended that the output stream be promptly closed if an I/O
+     * error occurs.
+     *
+     * <p> This method may block indefinitely writing to the output stream (or
+     * reading from the file). The behavior for the case that the output stream
+     * is <i>asynchronously closed</i> or the thread interrupted during the copy
+     * is highly output stream and file system provider specific and therefore
+     * not specified.
+     *
+     * <p> Note that if the given output stream is {@link java.io.Flushable}
+     * then its {@link java.io.Flushable#flush flush} method may need to invoked
+     * after this method completes so as to flush any buffered output.
+     *
+     * @param   source
+     *          the  path to the file
+     * @param   out
+     *          the output stream to write to
+     *
+     * @return  the number of bytes read or written
+     *
+     * @throws  IOException
+     *          if an I/O error occurs when reading or writing
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    public static long copy(Path source, OutputStream out) throws IOException {
+        // ensure not null before opening file
+        Objects.requireNonNull(out);
+
+        try (InputStream in = newInputStream(source)) {
+            return copy(in, out);
+        }
+    }
+
+    /**
+     * The maximum size of array to allocate.
+     * Some VMs reserve some header words in an array.
+     * Attempts to allocate larger arrays may result in
+     * OutOfMemoryError: Requested array size exceeds VM limit
+     */
+    private static final int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
+
+    /**
+     * Reads all the bytes from an input stream. Uses {@code initialSize} as a hint
+     * about how many bytes the stream will have.
+     *
+     * @param   source
+     *          the input stream to read from
+     * @param   initialSize
+     *          the initial size of the byte array to allocate
+     *
+     * @return  a byte array containing the bytes read from the file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs reading from the stream
+     * @throws  OutOfMemoryError
+     *          if an array of the required size cannot be allocated
+     */
+    private static byte[] read(InputStream source, int initialSize) throws IOException {
+        int capacity = initialSize;
+        byte[] buf = new byte[capacity];
+        int nread = 0;
+        int n;
+        for (;;) {
+            // read to EOF which may read more or less than initialSize (eg: file
+            // is truncated while we are reading)
+            while ((n = source.read(buf, nread, capacity - nread)) > 0)
+                nread += n;
+
+            // if last call to source.read() returned -1, we are done
+            // otherwise, try to read one more byte; if that failed we're done too
+            if (n < 0 || (n = source.read()) < 0)
+                break;
+
+            // one more byte was read; need to allocate a larger buffer
+            if (capacity <= MAX_BUFFER_SIZE - capacity) {
+                capacity = Math.max(capacity << 1, BUFFER_SIZE);
+            } else {
+                if (capacity == MAX_BUFFER_SIZE)
+                    throw new OutOfMemoryError("Required array size too large");
+                capacity = MAX_BUFFER_SIZE;
+            }
+            buf = Arrays.copyOf(buf, capacity);
+            buf[nread++] = (byte)n;
+        }
+        return (capacity == nread) ? buf : Arrays.copyOf(buf, nread);
+    }
+
+    /**
+     * Reads all the bytes from a file. The method ensures that the file is
+     * closed when all bytes have been read or an I/O error, or other runtime
+     * exception, is thrown.
+     *
+     * <p> Note that this method is intended for simple cases where it is
+     * convenient to read all bytes into a byte array. It is not intended for
+     * reading in large files.
+     *
+     * @param   path
+     *          the path to the file
+     *
+     * @return  a byte array containing the bytes read from the file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs reading from the stream
+     * @throws  OutOfMemoryError
+     *          if an array of the required size cannot be allocated, for
+     *          example the file is larger that {@code 2GB}
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    public static byte[] readAllBytes(Path path) throws IOException {
+        try (SeekableByteChannel sbc = Files.newByteChannel(path);
+             InputStream in = Channels.newInputStream(sbc)) {
+            long size = sbc.size();
+            if (size > (long)MAX_BUFFER_SIZE)
+                throw new OutOfMemoryError("Required array size too large");
+
+            return read(in, (int)size);
+        }
+    }
+
+    /**
+     * Read all lines from a file. This method ensures that the file is
+     * closed when all bytes have been read or an I/O error, or other runtime
+     * exception, is thrown. Bytes from the file are decoded into characters
+     * using the specified charset.
+     *
+     * <p> This method recognizes the following as line terminators:
+     * <ul>
+     *   <li> <code>&#92;u000D</code> followed by <code>&#92;u000A</code>,
+     *     CARRIAGE RETURN followed by LINE FEED </li>
+     *   <li> <code>&#92;u000A</code>, LINE FEED </li>
+     *   <li> <code>&#92;u000D</code>, CARRIAGE RETURN </li>
+     * </ul>
+     * <p> Additional Unicode line terminators may be recognized in future
+     * releases.
+     *
+     * <p> Note that this method is intended for simple cases where it is
+     * convenient to read all lines in a single operation. It is not intended
+     * for reading in large files.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   cs
+     *          the charset to use for decoding
+     *
+     * @return  the lines from the file as a {@code List}; whether the {@code
+     *          List} is modifiable or not is implementation dependent and
+     *          therefore not specified
+     *
+     * @throws  IOException
+     *          if an I/O error occurs reading from the file or a malformed or
+     *          unmappable byte sequence is read
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     *
+     * @see #newBufferedReader
+     */
+    public static List<String> readAllLines(Path path, Charset cs) throws IOException {
+        try (BufferedReader reader = newBufferedReader(path, cs)) {
+            List<String> result = new ArrayList<>();
+            for (;;) {
+                String line = reader.readLine();
+                if (line == null)
+                    break;
+                result.add(line);
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Read all lines from a file. Bytes from the file are decoded into characters
+     * using the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset charset}.
+     *
+     * <p> This method works as if invoking it were equivalent to evaluating the
+     * expression:
+     * <pre>{@code
+     * Files.readAllLines(path, StandardCharsets.UTF_8)
+     * }</pre>
+     *
+     * @param   path
+     *          the path to the file
+     *
+     * @return  the lines from the file as a {@code List}; whether the {@code
+     *          List} is modifiable or not is implementation dependent and
+     *          therefore not specified
+     *
+     * @throws  IOException
+     *          if an I/O error occurs reading from the file or a malformed or
+     *          unmappable byte sequence is read
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     *
+     * @since 1.8
+     */
+    public static List<String> readAllLines(Path path) throws IOException {
+        return readAllLines(path, StandardCharsets.UTF_8);
+    }
+
+    /**
+     * Writes bytes to a file. The {@code options} parameter specifies how the
+     * the file is created or opened. If no options are present then this method
+     * works as if the {@link StandardOpenOption#CREATE CREATE}, {@link
+     * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+     * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+     * opens the file for writing, creating the file if it doesn't exist, or
+     * initially truncating an existing {@link #isRegularFile regular-file} to
+     * a size of {@code 0}. All bytes in the byte array are written to the file.
+     * The method ensures that the file is closed when all bytes have been
+     * written (or an I/O error or other runtime exception is thrown). If an I/O
+     * error occurs then it may do so after the file has created or truncated,
+     * or after some bytes have been written to the file.
+     *
+     * <p> <b>Usage example</b>: By default the method creates a new file or
+     * overwrites an existing file. Suppose you instead want to append bytes
+     * to an existing file:
+     * <pre>
+     *     Path path = ...
+     *     byte[] bytes = ...
+     *     Files.write(path, bytes, StandardOpenOption.APPEND);
+     * </pre>
+     *
+     * @param   path
+     *          the path to the file
+     * @param   bytes
+     *          the byte array with the bytes to write
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  the path
+     *
+     * @throws  IOException
+     *          if an I/O error occurs writing to or creating the file
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     */
+    public static Path write(Path path, byte[] bytes, OpenOption... options)
+        throws IOException
+    {
+        // ensure bytes is not null before opening file
+        Objects.requireNonNull(bytes);
+
+        try (OutputStream out = Files.newOutputStream(path, options)) {
+            int len = bytes.length;
+            int rem = len;
+            while (rem > 0) {
+                int n = Math.min(rem, BUFFER_SIZE);
+                out.write(bytes, (len-rem), n);
+                rem -= n;
+            }
+        }
+        return path;
+    }
+
+    /**
+     * Write lines of text to a file. Each line is a char sequence and is
+     * written to the file in sequence with each line terminated by the
+     * platform's line separator, as defined by the system property {@code
+     * line.separator}. Characters are encoded into bytes using the specified
+     * charset.
+     *
+     * <p> The {@code options} parameter specifies how the the file is created
+     * or opened. If no options are present then this method works as if the
+     * {@link StandardOpenOption#CREATE CREATE}, {@link
+     * StandardOpenOption#TRUNCATE_EXISTING TRUNCATE_EXISTING}, and {@link
+     * StandardOpenOption#WRITE WRITE} options are present. In other words, it
+     * opens the file for writing, creating the file if it doesn't exist, or
+     * initially truncating an existing {@link #isRegularFile regular-file} to
+     * a size of {@code 0}. The method ensures that the file is closed when all
+     * lines have been written (or an I/O error or other runtime exception is
+     * thrown). If an I/O error occurs then it may do so after the file has
+     * created or truncated, or after some bytes have been written to the file.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   lines
+     *          an object to iterate over the char sequences
+     * @param   cs
+     *          the charset to use for encoding
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  the path
+     *
+     * @throws  IOException
+     *          if an I/O error occurs writing to or creating the file, or the
+     *          text cannot be encoded using the specified charset
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     */
+    public static Path write(Path path, Iterable<? extends CharSequence> lines,
+                             Charset cs, OpenOption... options)
+        throws IOException
+    {
+        // ensure lines is not null before opening file
+        Objects.requireNonNull(lines);
+        CharsetEncoder encoder = cs.newEncoder();
+        OutputStream out = newOutputStream(path, options);
+        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
+            for (CharSequence line: lines) {
+                writer.append(line);
+                writer.newLine();
+            }
+        }
+        return path;
+    }
+
+    /**
+     * Write lines of text to a file. Characters are encoded into bytes using
+     * the {@link StandardCharsets#UTF_8 UTF-8} {@link Charset charset}.
+     *
+     * <p> This method works as if invoking it were equivalent to evaluating the
+     * expression:
+     * <pre>{@code
+     * Files.write(path, lines, StandardCharsets.UTF_8, options);
+     * }</pre>
+     *
+     * @param   path
+     *          the path to the file
+     * @param   lines
+     *          an object to iterate over the char sequences
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  the path
+     *
+     * @throws  IOException
+     *          if an I/O error occurs writing to or creating the file, or the
+     *          text cannot be encoded as {@code UTF-8}
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file.
+     *
+     * @since 1.8
+     */
+    public static Path write(Path path,
+                             Iterable<? extends CharSequence> lines,
+                             OpenOption... options)
+        throws IOException
+    {
+        return write(path, lines, StandardCharsets.UTF_8, options);
+    }
+
+    // -- Stream APIs --
+
+    /**
+     * Return a lazily populated {@code Stream}, the elements of
+     * which are the entries in the directory.  The listing is not recursive.
+     *
+     * <p> The elements of the stream are {@link Path} objects that are
+     * obtained as if by {@link Path#resolve(Path) resolving} the name of the
+     * directory entry against {@code dir}. Some file systems maintain special
+     * links to the directory itself and the directory's parent directory.
+     * Entries representing these links are not included.
+     *
+     * <p> The stream is <i>weakly consistent</i>. It is thread safe but does
+     * not freeze the directory while iterating, so it may (or may not)
+     * reflect updates to the directory that occur after returning from this
+     * method.
+     *
+     * <p> The returned stream encapsulates a {@link DirectoryStream}.
+     * If timely disposal of file system resources is required, the
+     * {@code try}-with-resources construct should be used to ensure that the
+     * stream's {@link Stream#close close} method is invoked after the stream
+     * operations are completed.
+     *
+     * <p> Operating on a closed stream behaves as if the end of stream
+     * has been reached. Due to read-ahead, one or more elements may be
+     * returned after the stream has been closed.
+     *
+     * <p> If an {@link IOException} is thrown when accessing the directory
+     * after this method has returned, it is wrapped in an {@link
+     * UncheckedIOException} which will be thrown from the method that caused
+     * the access to take place.
+     *
+     * @param   dir  The path to the directory
+     *
+     * @return  The {@code Stream} describing the content of the
+     *          directory
+     *
+     * @throws  NotDirectoryException
+     *          if the file could not otherwise be opened because it is not
+     *          a directory <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs when opening the directory
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the directory.
+     *
+     * @see     #newDirectoryStream(Path)
+     * @since   1.8
+     */
+    public static Stream<Path> list(Path dir) throws IOException {
+        DirectoryStream<Path> ds = Files.newDirectoryStream(dir);
+        try {
+            final Iterator<Path> delegate = ds.iterator();
+
+            // Re-wrap DirectoryIteratorException to UncheckedIOException
+            Iterator<Path> it = new Iterator<Path>() {
+                @Override
+                public boolean hasNext() {
+                    try {
+                        return delegate.hasNext();
+                    } catch (DirectoryIteratorException e) {
+                        throw new UncheckedIOException(e.getCause());
+                    }
+                }
+                @Override
+                public Path next() {
+                    try {
+                        return delegate.next();
+                    } catch (DirectoryIteratorException e) {
+                        throw new UncheckedIOException(e.getCause());
+                    }
+                }
+            };
+
+            return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false)
+                                .onClose(asUncheckedRunnable(ds));
+        } catch (Error|RuntimeException e) {
+            try {
+                ds.close();
+            } catch (IOException ex) {
+                try {
+                    e.addSuppressed(ex);
+                } catch (Throwable ignore) {}
+            }
+            throw e;
+        }
+    }
+
+    /**
+     * Return a {@code Stream} that is lazily populated with {@code
+     * Path} by walking the file tree rooted at a given starting file.  The
+     * file tree is traversed <em>depth-first</em>, the elements in the stream
+     * are {@link Path} objects that are obtained as if by {@link
+     * Path#resolve(Path) resolving} the relative path against {@code start}.
+     *
+     * <p> The {@code stream} walks the file tree as elements are consumed.
+     * The {@code Stream} returned is guaranteed to have at least one
+     * element, the starting file itself. For each file visited, the stream
+     * attempts to read its {@link BasicFileAttributes}. If the file is a
+     * directory and can be opened successfully, entries in the directory, and
+     * their <em>descendants</em> will follow the directory in the stream as
+     * they are encountered. When all entries have been visited, then the
+     * directory is closed. The file tree walk then continues at the next
+     * <em>sibling</em> of the directory.
+     *
+     * <p> The stream is <i>weakly consistent</i>. It does not freeze the
+     * file tree while iterating, so it may (or may not) reflect updates to
+     * the file tree that occur after returned from this method.
+     *
+     * <p> By default, symbolic links are not automatically followed by this
+     * method. If the {@code options} parameter contains the {@link
+     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then symbolic links are
+     * followed. When following links, and the attributes of the target cannot
+     * be read, then this method attempts to get the {@code BasicFileAttributes}
+     * of the link.
+     *
+     * <p> If the {@code options} parameter contains the {@link
+     * FileVisitOption#FOLLOW_LINKS FOLLOW_LINKS} option then the stream keeps
+     * track of directories visited so that cycles can be detected. A cycle
+     * arises when there is an entry in a directory that is an ancestor of the
+     * directory. Cycle detection is done by recording the {@link
+     * java.nio.file.attribute.BasicFileAttributes#fileKey file-key} of directories,
+     * or if file keys are not available, by invoking the {@link #isSameFile
+     * isSameFile} method to test if a directory is the same file as an
+     * ancestor. When a cycle is detected it is treated as an I/O error with
+     * an instance of {@link FileSystemLoopException}.
+     *
+     * <p> The {@code maxDepth} parameter is the maximum number of levels of
+     * directories to visit. A value of {@code 0} means that only the starting
+     * file is visited, unless denied by the security manager. A value of
+     * {@link Integer#MAX_VALUE MAX_VALUE} may be used to indicate that all
+     * levels should be visited.
+     *
+     * <p> When a security manager is installed and it denies access to a file
+     * (or directory), then it is ignored and not included in the stream.
+     *
+     * <p> The returned stream encapsulates one or more {@link DirectoryStream}s.
+     * If timely disposal of file system resources is required, the
+     * {@code try}-with-resources construct should be used to ensure that the
+     * stream's {@link Stream#close close} method is invoked after the stream
+     * operations are completed.  Operating on a closed stream will result in an
+     * {@link java.lang.IllegalStateException}.
+     *
+     * <p> If an {@link IOException} is thrown when accessing the directory
+     * after this method has returned, it is wrapped in an {@link
+     * UncheckedIOException} which will be thrown from the method that caused
+     * the access to take place.
+     *
+     * @param   start
+     *          the starting file
+     * @param   maxDepth
+     *          the maximum number of directory levels to visit
+     * @param   options
+     *          options to configure the traversal
+     *
+     * @return  the {@link Stream} of {@link Path}
+     *
+     * @throws  IllegalArgumentException
+     *          if the {@code maxDepth} parameter is negative
+     * @throws  SecurityException
+     *          If the security manager denies access to the starting file.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String) checkRead} method is invoked
+     *          to check read access to the directory.
+     * @throws  IOException
+     *          if an I/O error is thrown when accessing the starting file.
+     * @since   1.8
+     */
+    public static Stream<Path> walk(Path start,
+                                    int maxDepth,
+                                    FileVisitOption... options)
+        throws IOException
+    {
+        FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
+        try {
+            return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
+                                .onClose(iterator::close)
+                                .map(entry -> entry.file());
+        } catch (Error|RuntimeException e) {
+            iterator.close();
+            throw e;
+        }
+    }
+
+    /**
+     * Return a {@code Stream} that is lazily populated with {@code
+     * Path} by walking the file tree rooted at a given starting file.  The
+     * file tree is traversed <em>depth-first</em>, the elements in the stream
+     * are {@link Path} objects that are obtained as if by {@link
+     * Path#resolve(Path) resolving} the relative path against {@code start}.
+     *
+     * <p> This method works as if invoking it were equivalent to evaluating the
+     * expression:
+     * <blockquote><pre>
+     * walk(start, Integer.MAX_VALUE, options)
+     * </pre></blockquote>
+     * In other words, it visits all levels of the file tree.
+     *
+     * <p> The returned stream encapsulates one or more {@link DirectoryStream}s.
+     * If timely disposal of file system resources is required, the
+     * {@code try}-with-resources construct should be used to ensure that the
+     * stream's {@link Stream#close close} method is invoked after the stream
+     * operations are completed.  Operating on a closed stream will result in an
+     * {@link java.lang.IllegalStateException}.
+     *
+     * @param   start
+     *          the starting file
+     * @param   options
+     *          options to configure the traversal
+     *
+     * @return  the {@link Stream} of {@link Path}
+     *
+     * @throws  SecurityException
+     *          If the security manager denies access to the starting file.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String) checkRead} method is invoked
+     *          to check read access to the directory.
+     * @throws  IOException
+     *          if an I/O error is thrown when accessing the starting file.
+     *
+     * @see     #walk(Path, int, FileVisitOption...)
+     * @since   1.8
+     */
+    public static Stream<Path> walk(Path start, FileVisitOption... options) throws IOException {
+        return walk(start, Integer.MAX_VALUE, options);
+    }
+
+    /**
+     * Return a {@code Stream} that is lazily populated with {@code
+     * Path} by searching for files in a file tree rooted at a given starting
+     * file.
+     *
+     * <p> This method walks the file tree in exactly the manner specified by
+     * the {@link #walk walk} method. For each file encountered, the given
+     * {@link BiPredicate} is invoked with its {@link Path} and {@link
+     * BasicFileAttributes}. The {@code Path} object is obtained as if by
+     * {@link Path#resolve(Path) resolving} the relative path against {@code
+     * start} and is only included in the returned {@link Stream} if
+     * the {@code BiPredicate} returns true. Compare to calling {@link
+     * java.util.stream.Stream#filter filter} on the {@code Stream}
+     * returned by {@code walk} method, this method may be more efficient by
+     * avoiding redundant retrieval of the {@code BasicFileAttributes}.
+     *
+     * <p> The returned stream encapsulates one or more {@link DirectoryStream}s.
+     * If timely disposal of file system resources is required, the
+     * {@code try}-with-resources construct should be used to ensure that the
+     * stream's {@link Stream#close close} method is invoked after the stream
+     * operations are completed.  Operating on a closed stream will result in an
+     * {@link java.lang.IllegalStateException}.
+     *
+     * <p> If an {@link IOException} is thrown when accessing the directory
+     * after returned from this method, it is wrapped in an {@link
+     * UncheckedIOException} which will be thrown from the method that caused
+     * the access to take place.
+     *
+     * @param   start
+     *          the starting file
+     * @param   maxDepth
+     *          the maximum number of directory levels to search
+     * @param   matcher
+     *          the function used to decide whether a file should be included
+     *          in the returned stream
+     * @param   options
+     *          options to configure the traversal
+     *
+     * @return  the {@link Stream} of {@link Path}
+     *
+     * @throws  IllegalArgumentException
+     *          if the {@code maxDepth} parameter is negative
+     * @throws  SecurityException
+     *          If the security manager denies access to the starting file.
+     *          In the case of the default provider, the {@link
+     *          SecurityManager#checkRead(String) checkRead} method is invoked
+     *          to check read access to the directory.
+     * @throws  IOException
+     *          if an I/O error is thrown when accessing the starting file.
+     *
+     * @see     #walk(Path, int, FileVisitOption...)
+     * @since   1.8
+     */
+    public static Stream<Path> find(Path start,
+                                    int maxDepth,
+                                    BiPredicate<Path, BasicFileAttributes> matcher,
+                                    FileVisitOption... options)
+        throws IOException
+    {
+        FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options);
+        try {
+            return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false)
+                                .onClose(iterator::close)
+                                .filter(entry -> matcher.test(entry.file(), entry.attributes()))
+                                .map(entry -> entry.file());
+        } catch (Error|RuntimeException e) {
+            iterator.close();
+            throw e;
+        }
+    }
+
+    /**
+     * Read all lines from a file as a {@code Stream}. Unlike {@link
+     * #readAllLines(Path, Charset) readAllLines}, this method does not read
+     * all lines into a {@code List}, but instead populates lazily as the stream
+     * is consumed.
+     *
+     * <p> Bytes from the file are decoded into characters using the specified
+     * charset and the same line terminators as specified by {@code
+     * readAllLines} are supported.
+     *
+     * <p> After this method returns, then any subsequent I/O exception that
+     * occurs while reading from the file or when a malformed or unmappable byte
+     * sequence is read, is wrapped in an {@link UncheckedIOException} that will
+     * be thrown from the
+     * {@link java.util.stream.Stream} method that caused the read to take
+     * place. In case an {@code IOException} is thrown when closing the file,
+     * it is also wrapped as an {@code UncheckedIOException}.
+     *
+     * <p> The returned stream encapsulates a {@link Reader}.  If timely
+     * disposal of file system resources is required, the try-with-resources
+     * construct should be used to ensure that the stream's
+     * {@link Stream#close close} method is invoked after the stream operations
+     * are completed.
+     *
+     *
+     * @param   path
+     *          the path to the file
+     * @param   cs
+     *          the charset to use for decoding
+     *
+     * @return  the lines from the file as a {@code Stream}
+     *
+     * @throws  IOException
+     *          if an I/O error occurs opening the file
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     *
+     * @see     #readAllLines(Path, Charset)
+     * @see     #newBufferedReader(Path, Charset)
+     * @see     java.io.BufferedReader#lines()
+     * @since   1.8
+     */
+    public static Stream<String> lines(Path path, Charset cs) throws IOException {
+        BufferedReader br = Files.newBufferedReader(path, cs);
+        try {
+            return br.lines().onClose(asUncheckedRunnable(br));
+        } catch (Error|RuntimeException e) {
+            try {
+                br.close();
+            } catch (IOException ex) {
+                try {
+                    e.addSuppressed(ex);
+                } catch (Throwable ignore) {}
+            }
+            throw e;
+        }
+    }
+
+    /**
+     * Read all lines from a file as a {@code Stream}. Bytes from the file are
+     * decoded into characters using the {@link StandardCharsets#UTF_8 UTF-8}
+     * {@link Charset charset}.
+     *
+     * <p> This method works as if invoking it were equivalent to evaluating the
+     * expression:
+     * <pre>{@code
+     * Files.lines(path, StandardCharsets.UTF_8)
+     * }</pre>
+     *
+     * @param   path
+     *          the path to the file
+     *
+     * @return  the lines from the file as a {@code Stream}
+     *
+     * @throws  IOException
+     *          if an I/O error occurs opening the file
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     *
+     * @since 1.8
+     */
+    public static Stream<String> lines(Path path) throws IOException {
+        return lines(path, StandardCharsets.UTF_8);
+    }
+}
diff --git a/java/nio/file/InvalidPathException.java b/java/nio/file/InvalidPathException.java
new file mode 100644
index 0000000..2c62865
--- /dev/null
+++ b/java/nio/file/InvalidPathException.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Unchecked exception thrown when path string cannot be converted into a
+ * {@link Path} because the path string contains invalid characters, or
+ * the path string is invalid for other file system specific reasons.
+ */
+
+public class InvalidPathException
+    extends IllegalArgumentException
+{
+    static final long serialVersionUID = 4355821422286746137L;
+
+    private String input;
+    private int index;
+
+    /**
+     * Constructs an instance from the given input string, reason, and error
+     * index.
+     *
+     * @param  input   the input string
+     * @param  reason  a string explaining why the input was rejected
+     * @param  index   the index at which the error occurred,
+     *                 or <tt>-1</tt> if the index is not known
+     *
+     * @throws  NullPointerException
+     *          if either the input or reason strings are <tt>null</tt>
+     *
+     * @throws  IllegalArgumentException
+     *          if the error index is less than <tt>-1</tt>
+     */
+    public InvalidPathException(String input, String reason, int index) {
+        super(reason);
+        if ((input == null) || (reason == null))
+            throw new NullPointerException();
+        if (index < -1)
+            throw new IllegalArgumentException();
+        this.input = input;
+        this.index = index;
+    }
+
+    /**
+     * Constructs an instance from the given input string and reason.  The
+     * resulting object will have an error index of <tt>-1</tt>.
+     *
+     * @param  input   the input string
+     * @param  reason  a string explaining why the input was rejected
+     *
+     * @throws  NullPointerException
+     *          if either the input or reason strings are <tt>null</tt>
+     */
+    public InvalidPathException(String input, String reason) {
+        this(input, reason, -1);
+    }
+
+    /**
+     * Returns the input string.
+     *
+     * @return  the input string
+     */
+    public String getInput() {
+        return input;
+    }
+
+    /**
+     * Returns a string explaining why the input string was rejected.
+     *
+     * @return  the reason string
+     */
+    public String getReason() {
+        return super.getMessage();
+    }
+
+    /**
+     * Returns an index into the input string of the position at which the
+     * error occurred, or <tt>-1</tt> if this position is not known.
+     *
+     * @return  the error index
+     */
+    public int getIndex() {
+        return index;
+    }
+
+    /**
+     * Returns a string describing the error.  The resulting string
+     * consists of the reason string followed by a colon character
+     * (<tt>':'</tt>), a space, and the input string.  If the error index is
+     * defined then the string <tt>" at index "</tt> followed by the index, in
+     * decimal, is inserted after the reason string and before the colon
+     * character.
+     *
+     * @return  a string describing the error
+     */
+    public String getMessage() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getReason());
+        if (index > -1) {
+            sb.append(" at index ");
+            sb.append(index);
+        }
+        sb.append(": ");
+        sb.append(input);
+        return sb.toString();
+    }
+}
diff --git a/java/nio/file/LinkOption.java b/java/nio/file/LinkOption.java
new file mode 100644
index 0000000..f1e133f
--- /dev/null
+++ b/java/nio/file/LinkOption.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+/**
+ * Defines the options as to how symbolic links are handled.
+ *
+ * @since 1.7
+ */
+
+public enum LinkOption implements OpenOption, CopyOption {
+    /**
+     * Do not follow symbolic links.
+     *
+     * @see Files#getFileAttributeView(Path,Class,LinkOption[])
+     * @see Files#copy
+     * @see SecureDirectoryStream#newByteChannel
+     */
+    NOFOLLOW_LINKS;
+}
diff --git a/java/nio/file/LinkPermission.java b/java/nio/file/LinkPermission.java
new file mode 100644
index 0000000..bf54e16
--- /dev/null
+++ b/java/nio/file/LinkPermission.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+import java.security.BasicPermission;
+
+/**
+ * The {@code Permission} class for link creation operations.
+ *
+ * <p> The following table provides a summary description of what the permission
+ * allows, and discusses the risks of granting code the permission.
+ *
+ * <table border=1 cellpadding=5
+ *        summary="Table shows permission target name, what the permission allows, and associated risks">
+ * <tr>
+ * <th>Permission Target Name</th>
+ * <th>What the Permission Allows</th>
+ * <th>Risks of Allowing this Permission</th>
+ * </tr>
+ * <tr>
+ *   <td>hard</td>
+ *   <td> Ability to add an existing file to a directory. This is sometimes
+ *   known as creating a link, or hard link. </td>
+ *   <td> Extreme care should be taken when granting this permission. It allows
+ *   linking to any file or directory in the file system thus allowing the
+ *   attacker access to all files. </td>
+ * </tr>
+ * <tr>
+ *   <td>symbolic</td>
+ *   <td> Ability to create symbolic links. </td>
+ *   <td> Extreme care should be taken when granting this permission. It allows
+ *   linking to any file or directory in the file system thus allowing the
+ *   attacker to access to all files. </td>
+ * </tr>
+ * </table>
+ *
+ * @since 1.7
+ *
+ * @see Files#createLink
+ * @see Files#createSymbolicLink
+ */
+public final class LinkPermission extends BasicPermission {
+    static final long serialVersionUID = -1441492453772213220L;
+
+    private void checkName(String name) {
+        if (!name.equals("hard") && !name.equals("symbolic")) {
+            throw new IllegalArgumentException("name: " + name);
+        }
+    }
+
+    /**
+     * Constructs a {@code LinkPermission} with the specified name.
+     *
+     * @param   name
+     *          the name of the permission. It must be "hard" or "symbolic".
+     *
+     * @throws  IllegalArgumentException
+     *          if name is empty or invalid
+     */
+    public LinkPermission(String name) {
+        super(name);
+        checkName(name);
+    }
+
+    /**
+     * Constructs a {@code LinkPermission} with the specified name.
+     *
+     * @param   name
+     *          the name of the permission; must be "hard" or "symbolic".
+     * @param   actions
+     *          the actions for the permission; must be the empty string or
+     *          {@code null}
+     *
+     * @throws  IllegalArgumentException
+     *          if name is empty or invalid, or actions is a non-empty string
+     */
+    public LinkPermission(String name, String actions) {
+        super(name);
+        checkName(name);
+        if (actions != null && actions.length() > 0) {
+            throw new IllegalArgumentException("actions: " + actions);
+        }
+    }
+}
diff --git a/java/nio/file/NoSuchFileException.java b/java/nio/file/NoSuchFileException.java
new file mode 100644
index 0000000..1f2ab3d
--- /dev/null
+++ b/java/nio/file/NoSuchFileException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Checked exception thrown when an attempt is made to access a file that does
+ * not exist.
+ *
+ * @since 1.7
+ */
+
+public class NoSuchFileException
+    extends FileSystemException
+{
+    static final long serialVersionUID = -1390291775875351931L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known.
+     */
+    public NoSuchFileException(String file) {
+        super(file);
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known.
+     * @param   other
+     *          a string identifying the other file or {@code null} if not known.
+     * @param   reason
+     *          a reason message with additional information or {@code null}
+     */
+    public NoSuchFileException(String file, String other, String reason) {
+        super(file, other, reason);
+    }
+}
diff --git a/java/nio/file/NotDirectoryException.java b/java/nio/file/NotDirectoryException.java
new file mode 100644
index 0000000..4082cea
--- /dev/null
+++ b/java/nio/file/NotDirectoryException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation, intended for a
+ * directory, fails because the file is not a directory.
+ *
+ * @since 1.7
+ */
+
+public class NotDirectoryException
+    extends FileSystemException
+{
+    private static final long serialVersionUID = -9011457427178200199L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     */
+    public NotDirectoryException(String file) {
+        super(file);
+    }
+}
diff --git a/java/nio/file/NotLinkException.java b/java/nio/file/NotLinkException.java
new file mode 100644
index 0000000..353e4d7
--- /dev/null
+++ b/java/nio/file/NotLinkException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Checked exception thrown when a file system operation fails because a file
+ * is not a symbolic link.
+ *
+ * @since 1.7
+ */
+
+public class NotLinkException
+    extends FileSystemException
+{
+    static final long serialVersionUID = -388655596416518021L;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     */
+    public NotLinkException(String file) {
+        super(file);
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   file
+     *          a string identifying the file or {@code null} if not known
+     * @param   other
+     *          a string identifying the other file or {@code null} if not known
+     * @param   reason
+     *          a reason message with additional information or {@code null}
+     */
+    public NotLinkException(String file, String other, String reason) {
+        super(file, other, reason);
+    }
+}
diff --git a/java/nio/file/OpenOption.java b/java/nio/file/OpenOption.java
new file mode 100644
index 0000000..aef96fb
--- /dev/null
+++ b/java/nio/file/OpenOption.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+/**
+ * An object that configures how to open or create a file.
+ *
+ * <p> Objects of this type are used by methods such as {@link
+ * Files#newOutputStream(Path,OpenOption[]) newOutputStream}, {@link
+ * Files#newByteChannel newByteChannel}, {@link
+ * java.nio.channels.FileChannel#open FileChannel.open}, and {@link
+ * java.nio.channels.AsynchronousFileChannel#open AsynchronousFileChannel.open}
+ * when opening or creating a file.
+ *
+ * <p> The {@link StandardOpenOption} enumeration type defines the
+ * <i>standard</i> options.
+ *
+ * @since 1.7
+ */
+
+public interface OpenOption {
+}
diff --git a/java/nio/file/Path.java b/java/nio/file/Path.java
new file mode 100644
index 0000000..daa09f4
--- /dev/null
+++ b/java/nio/file/Path.java
@@ -0,0 +1,801 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.Iterator;
+
+/**
+ * An object that may be used to locate a file in a file system. It will
+ * typically represent a system dependent file path.
+ *
+ * <p> A {@code Path} represents a path that is hierarchical and composed of a
+ * sequence of directory and file name elements separated by a special separator
+ * or delimiter. A <em>root component</em>, that identifies a file system
+ * hierarchy, may also be present. The name element that is <em>farthest</em>
+ * from the root of the directory hierarchy is the name of a file or directory.
+ * The other name elements are directory names. A {@code Path} can represent a
+ * root, a root and a sequence of names, or simply one or more name elements.
+ * A {@code Path} is considered to be an <i>empty path</i> if it consists
+ * solely of one name element that is empty. Accessing a file using an
+ * <i>empty path</i> is equivalent to accessing the default directory of the
+ * file system. {@code Path} defines the {@link #getFileName() getFileName},
+ * {@link #getParent getParent}, {@link #getRoot getRoot}, and {@link #subpath
+ * subpath} methods to access the path components or a subsequence of its name
+ * elements.
+ *
+ * <p> In addition to accessing the components of a path, a {@code Path} also
+ * defines the {@link #resolve(Path) resolve} and {@link #resolveSibling(Path)
+ * resolveSibling} methods to combine paths. The {@link #relativize relativize}
+ * method that can be used to construct a relative path between two paths.
+ * Paths can be {@link #compareTo compared}, and tested against each other using
+ * the {@link #startsWith startsWith} and {@link #endsWith endsWith} methods.
+ *
+ * <p> This interface extends {@link Watchable} interface so that a directory
+ * located by a path can be {@link #register registered} with a {@link
+ * WatchService} and entries in the directory watched. </p>
+ *
+ * <p> <b>WARNING:</b> This interface is only intended to be implemented by
+ * those developing custom file system implementations. Methods may be added to
+ * this interface in future releases. </p>
+ *
+ * <h2>Accessing Files</h2>
+ * <p> Paths may be used with the {@link Files} class to operate on files,
+ * directories, and other types of files. For example, suppose we want a {@link
+ * java.io.BufferedReader} to read text from a file "{@code access.log}". The
+ * file is located in a directory "{@code logs}" relative to the current working
+ * directory and is UTF-8 encoded.
+ * <pre>
+ *     Path path = FileSystems.getDefault().getPath("logs", "access.log");
+ *     BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8);
+ * </pre>
+ *
+ * <a name="interop"></a><h2>Interoperability</h2>
+ * <p> Paths associated with the default {@link
+ * java.nio.file.spi.FileSystemProvider provider} are generally interoperable
+ * with the {@link java.io.File java.io.File} class. Paths created by other
+ * providers are unlikely to be interoperable with the abstract path names
+ * represented by {@code java.io.File}. The {@link java.io.File#toPath toPath}
+ * method may be used to obtain a {@code Path} from the abstract path name
+ * represented by a {@code java.io.File} object. The resulting {@code Path} can
+ * be used to operate on the same file as the {@code java.io.File} object. In
+ * addition, the {@link #toFile toFile} method is useful to construct a {@code
+ * File} from the {@code String} representation of a {@code Path}.
+ *
+ * <h2>Concurrency</h2>
+ * <p> Implementations of this interface are immutable and safe for use by
+ * multiple concurrent threads.
+ *
+ * @since 1.7
+ * @see Paths
+ */
+
+public interface Path
+    extends Comparable<Path>, Iterable<Path>, Watchable
+{
+    /**
+     * Returns the file system that created this object.
+     *
+     * @return  the file system that created this object
+     */
+    FileSystem getFileSystem();
+
+    /**
+     * Tells whether or not this path is absolute.
+     *
+     * <p> An absolute path is complete in that it doesn't need to be combined
+     * with other path information in order to locate a file.
+     *
+     * @return  {@code true} if, and only if, this path is absolute
+     */
+    boolean isAbsolute();
+
+    /**
+     * Returns the root component of this path as a {@code Path} object,
+     * or {@code null} if this path does not have a root component.
+     *
+     * @return  a path representing the root component of this path,
+     *          or {@code null}
+     */
+    Path getRoot();
+
+    /**
+     * Returns the name of the file or directory denoted by this path as a
+     * {@code Path} object. The file name is the <em>farthest</em> element from
+     * the root in the directory hierarchy.
+     *
+     * @return  a path representing the name of the file or directory, or
+     *          {@code null} if this path has zero elements
+     */
+    Path getFileName();
+
+    /**
+     * Returns the <em>parent path</em>, or {@code null} if this path does not
+     * have a parent.
+     *
+     * <p> The parent of this path object consists of this path's root
+     * component, if any, and each element in the path except for the
+     * <em>farthest</em> from the root in the directory hierarchy. This method
+     * does not access the file system; the path or its parent may not exist.
+     * Furthermore, this method does not eliminate special names such as "."
+     * and ".." that may be used in some implementations. On UNIX for example,
+     * the parent of "{@code /a/b/c}" is "{@code /a/b}", and the parent of
+     * {@code "x/y/.}" is "{@code x/y}". This method may be used with the {@link
+     * #normalize normalize} method, to eliminate redundant names, for cases where
+     * <em>shell-like</em> navigation is required.
+     *
+     * <p> If this path has one or more elements, and no root component, then
+     * this method is equivalent to evaluating the expression:
+     * <blockquote><pre>
+     * subpath(0,&nbsp;getNameCount()-1);
+     * </pre></blockquote>
+     *
+     * @return  a path representing the path's parent
+     */
+    Path getParent();
+
+    /**
+     * Returns the number of name elements in the path.
+     *
+     * @return  the number of elements in the path, or {@code 0} if this path
+     *          only represents a root component
+     */
+    int getNameCount();
+
+    /**
+     * Returns a name element of this path as a {@code Path} object.
+     *
+     * <p> The {@code index} parameter is the index of the name element to return.
+     * The element that is <em>closest</em> to the root in the directory hierarchy
+     * has index {@code 0}. The element that is <em>farthest</em> from the root
+     * has index {@link #getNameCount count}{@code -1}.
+     *
+     * @param   index
+     *          the index of the element
+     *
+     * @return  the name element
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code index} is negative, {@code index} is greater than or
+     *          equal to the number of elements, or this path has zero name
+     *          elements
+     */
+    Path getName(int index);
+
+    /**
+     * Returns a relative {@code Path} that is a subsequence of the name
+     * elements of this path.
+     *
+     * <p> The {@code beginIndex} and {@code endIndex} parameters specify the
+     * subsequence of name elements. The name that is <em>closest</em> to the root
+     * in the directory hierarchy has index {@code 0}. The name that is
+     * <em>farthest</em> from the root has index {@link #getNameCount
+     * count}{@code -1}. The returned {@code Path} object has the name elements
+     * that begin at {@code beginIndex} and extend to the element at index {@code
+     * endIndex-1}.
+     *
+     * @param   beginIndex
+     *          the index of the first element, inclusive
+     * @param   endIndex
+     *          the index of the last element, exclusive
+     *
+     * @return  a new {@code Path} object that is a subsequence of the name
+     *          elements in this {@code Path}
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code beginIndex} is negative, or greater than or equal to
+     *          the number of elements. If {@code endIndex} is less than or
+     *          equal to {@code beginIndex}, or larger than the number of elements.
+     */
+    Path subpath(int beginIndex, int endIndex);
+
+    /**
+     * Tests if this path starts with the given path.
+     *
+     * <p> This path <em>starts</em> with the given path if this path's root
+     * component <em>starts</em> with the root component of the given path,
+     * and this path starts with the same name elements as the given path.
+     * If the given path has more name elements than this path then {@code false}
+     * is returned.
+     *
+     * <p> Whether or not the root component of this path starts with the root
+     * component of the given path is file system specific. If this path does
+     * not have a root component and the given path has a root component then
+     * this path does not start with the given path.
+     *
+     * <p> If the given path is associated with a different {@code FileSystem}
+     * to this path then {@code false} is returned.
+     *
+     * @param   other
+     *          the given path
+     *
+     * @return  {@code true} if this path starts with the given path; otherwise
+     *          {@code false}
+     */
+    boolean startsWith(Path other);
+
+    /**
+     * Tests if this path starts with a {@code Path}, constructed by converting
+     * the given path string, in exactly the manner specified by the {@link
+     * #startsWith(Path) startsWith(Path)} method. On UNIX for example, the path
+     * "{@code foo/bar}" starts with "{@code foo}" and "{@code foo/bar}". It
+     * does not start with "{@code f}" or "{@code fo}".
+     *
+     * @param   other
+     *          the given path string
+     *
+     * @return  {@code true} if this path starts with the given path; otherwise
+     *          {@code false}
+     *
+     * @throws  InvalidPathException
+     *          If the path string cannot be converted to a Path.
+     */
+    boolean startsWith(String other);
+
+    /**
+     * Tests if this path ends with the given path.
+     *
+     * <p> If the given path has <em>N</em> elements, and no root component,
+     * and this path has <em>N</em> or more elements, then this path ends with
+     * the given path if the last <em>N</em> elements of each path, starting at
+     * the element farthest from the root, are equal.
+     *
+     * <p> If the given path has a root component then this path ends with the
+     * given path if the root component of this path <em>ends with</em> the root
+     * component of the given path, and the corresponding elements of both paths
+     * are equal. Whether or not the root component of this path ends with the
+     * root component of the given path is file system specific. If this path
+     * does not have a root component and the given path has a root component
+     * then this path does not end with the given path.
+     *
+     * <p> If the given path is associated with a different {@code FileSystem}
+     * to this path then {@code false} is returned.
+     *
+     * @param   other
+     *          the given path
+     *
+     * @return  {@code true} if this path ends with the given path; otherwise
+     *          {@code false}
+     */
+    boolean endsWith(Path other);
+
+    /**
+     * Tests if this path ends with a {@code Path}, constructed by converting
+     * the given path string, in exactly the manner specified by the {@link
+     * #endsWith(Path) endsWith(Path)} method. On UNIX for example, the path
+     * "{@code foo/bar}" ends with "{@code foo/bar}" and "{@code bar}". It does
+     * not end with "{@code r}" or "{@code /bar}". Note that trailing separators
+     * are not taken into account, and so invoking this method on the {@code
+     * Path}"{@code foo/bar}" with the {@code String} "{@code bar/}" returns
+     * {@code true}.
+     *
+     * @param   other
+     *          the given path string
+     *
+     * @return  {@code true} if this path ends with the given path; otherwise
+     *          {@code false}
+     *
+     * @throws  InvalidPathException
+     *          If the path string cannot be converted to a Path.
+     */
+    boolean endsWith(String other);
+
+    /**
+     * Returns a path that is this path with redundant name elements eliminated.
+     *
+     * <p> The precise definition of this method is implementation dependent but
+     * in general it derives from this path, a path that does not contain
+     * <em>redundant</em> name elements. In many file systems, the "{@code .}"
+     * and "{@code ..}" are special names used to indicate the current directory
+     * and parent directory. In such file systems all occurrences of "{@code .}"
+     * are considered redundant. If a "{@code ..}" is preceded by a
+     * non-"{@code ..}" name then both names are considered redundant (the
+     * process to identify such names is repeated until it is no longer
+     * applicable).
+     *
+     * <p> This method does not access the file system; the path may not locate
+     * a file that exists. Eliminating "{@code ..}" and a preceding name from a
+     * path may result in the path that locates a different file than the original
+     * path. This can arise when the preceding name is a symbolic link.
+     *
+     * @return  the resulting path or this path if it does not contain
+     *          redundant name elements; an empty path is returned if this path
+     *          does have a root component and all name elements are redundant
+     *
+     * @see #getParent
+     * @see #toRealPath
+     */
+    Path normalize();
+
+    // -- resolution and relativization --
+
+    /**
+     * Resolve the given path against this path.
+     *
+     * <p> If the {@code other} parameter is an {@link #isAbsolute() absolute}
+     * path then this method trivially returns {@code other}. If {@code other}
+     * is an <i>empty path</i> then this method trivially returns this path.
+     * Otherwise this method considers this path to be a directory and resolves
+     * the given path against this path. In the simplest case, the given path
+     * does not have a {@link #getRoot root} component, in which case this method
+     * <em>joins</em> the given path to this path and returns a resulting path
+     * that {@link #endsWith ends} with the given path. Where the given path has
+     * a root component then resolution is highly implementation dependent and
+     * therefore unspecified.
+     *
+     * @param   other
+     *          the path to resolve against this path
+     *
+     * @return  the resulting path
+     *
+     * @see #relativize
+     */
+    Path resolve(Path other);
+
+    /**
+     * Converts a given path string to a {@code Path} and resolves it against
+     * this {@code Path} in exactly the manner specified by the {@link
+     * #resolve(Path) resolve} method. For example, suppose that the name
+     * separator is "{@code /}" and a path represents "{@code foo/bar}", then
+     * invoking this method with the path string "{@code gus}" will result in
+     * the {@code Path} "{@code foo/bar/gus}".
+     *
+     * @param   other
+     *          the path string to resolve against this path
+     *
+     * @return  the resulting path
+     *
+     * @throws  InvalidPathException
+     *          if the path string cannot be converted to a Path.
+     *
+     * @see FileSystem#getPath
+     */
+    Path resolve(String other);
+
+    /**
+     * Resolves the given path against this path's {@link #getParent parent}
+     * path. This is useful where a file name needs to be <i>replaced</i> with
+     * another file name. For example, suppose that the name separator is
+     * "{@code /}" and a path represents "{@code dir1/dir2/foo}", then invoking
+     * this method with the {@code Path} "{@code bar}" will result in the {@code
+     * Path} "{@code dir1/dir2/bar}". If this path does not have a parent path,
+     * or {@code other} is {@link #isAbsolute() absolute}, then this method
+     * returns {@code other}. If {@code other} is an empty path then this method
+     * returns this path's parent, or where this path doesn't have a parent, the
+     * empty path.
+     *
+     * @param   other
+     *          the path to resolve against this path's parent
+     *
+     * @return  the resulting path
+     *
+     * @see #resolve(Path)
+     */
+    Path resolveSibling(Path other);
+
+    /**
+     * Converts a given path string to a {@code Path} and resolves it against
+     * this path's {@link #getParent parent} path in exactly the manner
+     * specified by the {@link #resolveSibling(Path) resolveSibling} method.
+     *
+     * @param   other
+     *          the path string to resolve against this path's parent
+     *
+     * @return  the resulting path
+     *
+     * @throws  InvalidPathException
+     *          if the path string cannot be converted to a Path.
+     *
+     * @see FileSystem#getPath
+     */
+    Path resolveSibling(String other);
+
+    /**
+     * Constructs a relative path between this path and a given path.
+     *
+     * <p> Relativization is the inverse of {@link #resolve(Path) resolution}.
+     * This method attempts to construct a {@link #isAbsolute relative} path
+     * that when {@link #resolve(Path) resolved} against this path, yields a
+     * path that locates the same file as the given path. For example, on UNIX,
+     * if this path is {@code "/a/b"} and the given path is {@code "/a/b/c/d"}
+     * then the resulting relative path would be {@code "c/d"}. Where this
+     * path and the given path do not have a {@link #getRoot root} component,
+     * then a relative path can be constructed. A relative path cannot be
+     * constructed if only one of the paths have a root component. Where both
+     * paths have a root component then it is implementation dependent if a
+     * relative path can be constructed. If this path and the given path are
+     * {@link #equals equal} then an <i>empty path</i> is returned.
+     *
+     * <p> For any two {@link #normalize normalized} paths <i>p</i> and
+     * <i>q</i>, where <i>q</i> does not have a root component,
+     * <blockquote>
+     *   <i>p</i><tt>.relativize(</tt><i>p</i><tt>.resolve(</tt><i>q</i><tt>)).equals(</tt><i>q</i><tt>)</tt>
+     * </blockquote>
+     *
+     * <p> When symbolic links are supported, then whether the resulting path,
+     * when resolved against this path, yields a path that can be used to locate
+     * the {@link Files#isSameFile same} file as {@code other} is implementation
+     * dependent. For example, if this path is  {@code "/a/b"} and the given
+     * path is {@code "/a/x"} then the resulting relative path may be {@code
+     * "../x"}. If {@code "b"} is a symbolic link then is implementation
+     * dependent if {@code "a/b/../x"} would locate the same file as {@code "/a/x"}.
+     *
+     * @param   other
+     *          the path to relativize against this path
+     *
+     * @return  the resulting relative path, or an empty path if both paths are
+     *          equal
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code other} is not a {@code Path} that can be relativized
+     *          against this path
+     */
+    Path relativize(Path other);
+
+    /**
+     * Returns a URI to represent this path.
+     *
+     * <p> This method constructs an absolute {@link URI} with a {@link
+     * URI#getScheme() scheme} equal to the URI scheme that identifies the
+     * provider. The exact form of the scheme specific part is highly provider
+     * dependent.
+     *
+     * <p> In the case of the default provider, the URI is hierarchical with
+     * a {@link URI#getPath() path} component that is absolute. The query and
+     * fragment components are undefined. Whether the authority component is
+     * defined or not is implementation dependent. There is no guarantee that
+     * the {@code URI} may be used to construct a {@link java.io.File java.io.File}.
+     * In particular, if this path represents a Universal Naming Convention (UNC)
+     * path, then the UNC server name may be encoded in the authority component
+     * of the resulting URI. In the case of the default provider, and the file
+     * exists, and it can be determined that the file is a directory, then the
+     * resulting {@code URI} will end with a slash.
+     *
+     * <p> The default provider provides a similar <em>round-trip</em> guarantee
+     * to the {@link java.io.File} class. For a given {@code Path} <i>p</i> it
+     * is guaranteed that
+     * <blockquote><tt>
+     * {@link Paths#get(URI) Paths.get}(</tt><i>p</i><tt>.toUri()).equals(</tt><i>p</i>
+     * <tt>.{@link #toAbsolutePath() toAbsolutePath}())</tt>
+     * </blockquote>
+     * so long as the original {@code Path}, the {@code URI}, and the new {@code
+     * Path} are all created in (possibly different invocations of) the same
+     * Java virtual machine. Whether other providers make any guarantees is
+     * provider specific and therefore unspecified.
+     *
+     * <p> When a file system is constructed to access the contents of a file
+     * as a file system then it is highly implementation specific if the returned
+     * URI represents the given path in the file system or it represents a
+     * <em>compound</em> URI that encodes the URI of the enclosing file system.
+     * A format for compound URIs is not defined in this release; such a scheme
+     * may be added in a future release.
+     *
+     * @return  the URI representing this path
+     *
+     * @throws  java.io.IOError
+     *          if an I/O error occurs obtaining the absolute path, or where a
+     *          file system is constructed to access the contents of a file as
+     *          a file system, and the URI of the enclosing file system cannot be
+     *          obtained
+     *
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, the {@link #toAbsolutePath toAbsolutePath} method
+     *          throws a security exception.
+     */
+    URI toUri();
+
+    /**
+     * Returns a {@code Path} object representing the absolute path of this
+     * path.
+     *
+     * <p> If this path is already {@link Path#isAbsolute absolute} then this
+     * method simply returns this path. Otherwise, this method resolves the path
+     * in an implementation dependent manner, typically by resolving the path
+     * against a file system default directory. Depending on the implementation,
+     * this method may throw an I/O error if the file system is not accessible.
+     *
+     * @return  a {@code Path} object representing the absolute path
+     *
+     * @throws  java.io.IOError
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager
+     *          is installed, and this path is not absolute, then the security
+     *          manager's {@link SecurityManager#checkPropertyAccess(String)
+     *          checkPropertyAccess} method is invoked to check access to the
+     *          system property {@code user.dir}
+     */
+    Path toAbsolutePath();
+
+    /**
+     * Returns the <em>real</em> path of an existing file.
+     *
+     * <p> The precise definition of this method is implementation dependent but
+     * in general it derives from this path, an {@link #isAbsolute absolute}
+     * path that locates the {@link Files#isSameFile same} file as this path, but
+     * with name elements that represent the actual name of the directories
+     * and the file. For example, where filename comparisons on a file system
+     * are case insensitive then the name elements represent the names in their
+     * actual case. Additionally, the resulting path has redundant name
+     * elements removed.
+     *
+     * <p> If this path is relative then its absolute path is first obtained,
+     * as if by invoking the {@link #toAbsolutePath toAbsolutePath} method.
+     *
+     * <p> The {@code options} array may be used to indicate how symbolic links
+     * are handled. By default, symbolic links are resolved to their final
+     * target. If the option {@link LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} is
+     * present then this method does not resolve symbolic links.
+     *
+     * Some implementations allow special names such as "{@code ..}" to refer to
+     * the parent directory. When deriving the <em>real path</em>, and a
+     * "{@code ..}" (or equivalent) is preceded by a non-"{@code ..}" name then
+     * an implementation will typically cause both names to be removed. When
+     * not resolving symbolic links and the preceding name is a symbolic link
+     * then the names are only removed if it guaranteed that the resulting path
+     * will locate the same file as this path.
+     *
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  an absolute path represent the <em>real</em> path of the file
+     *          located by this object
+     *
+     * @throws  IOException
+     *          if the file does not exist or an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file, and where
+     *          this path is not absolute, its {@link SecurityManager#checkPropertyAccess(String)
+     *          checkPropertyAccess} method is invoked to check access to the
+     *          system property {@code user.dir}
+     */
+    Path toRealPath(LinkOption... options) throws IOException;
+
+    /**
+     * Returns a {@link File} object representing this path. Where this {@code
+     * Path} is associated with the default provider, then this method is
+     * equivalent to returning a {@code File} object constructed with the
+     * {@code String} representation of this path.
+     *
+     * <p> If this path was created by invoking the {@code File} {@link
+     * File#toPath toPath} method then there is no guarantee that the {@code
+     * File} object returned by this method is {@link #equals equal} to the
+     * original {@code File}.
+     *
+     * @return  a {@code File} object representing this path
+     *
+     * @throws  UnsupportedOperationException
+     *          if this {@code Path} is not associated with the default provider
+     */
+    File toFile();
+
+    // -- watchable --
+
+    /**
+     * Registers the file located by this path with a watch service.
+     *
+     * <p> In this release, this path locates a directory that exists. The
+     * directory is registered with the watch service so that entries in the
+     * directory can be watched. The {@code events} parameter is the events to
+     * register and may contain the following events:
+     * <ul>
+     *   <li>{@link StandardWatchEventKinds#ENTRY_CREATE ENTRY_CREATE} -
+     *       entry created or moved into the directory</li>
+     *   <li>{@link StandardWatchEventKinds#ENTRY_DELETE ENTRY_DELETE} -
+     *        entry deleted or moved out of the directory</li>
+     *   <li>{@link StandardWatchEventKinds#ENTRY_MODIFY ENTRY_MODIFY} -
+     *        entry in directory was modified</li>
+     * </ul>
+     *
+     * <p> The {@link WatchEvent#context context} for these events is the
+     * relative path between the directory located by this path, and the path
+     * that locates the directory entry that is created, deleted, or modified.
+     *
+     * <p> The set of events may include additional implementation specific
+     * event that are not defined by the enum {@link StandardWatchEventKinds}
+     *
+     * <p> The {@code modifiers} parameter specifies <em>modifiers</em> that
+     * qualify how the directory is registered. This release does not define any
+     * <em>standard</em> modifiers. It may contain implementation specific
+     * modifiers.
+     *
+     * <p> Where a file is registered with a watch service by means of a symbolic
+     * link then it is implementation specific if the watch continues to depend
+     * on the existence of the symbolic link after it is registered.
+     *
+     * @param   watcher
+     *          the watch service to which this object is to be registered
+     * @param   events
+     *          the events for which this object should be registered
+     * @param   modifiers
+     *          the modifiers, if any, that modify how the object is registered
+     *
+     * @return  a key representing the registration of this object with the
+     *          given watch service
+     *
+     * @throws  UnsupportedOperationException
+     *          if unsupported events or modifiers are specified
+     * @throws  IllegalArgumentException
+     *          if an invalid combination of events or modifiers is specified
+     * @throws  ClosedWatchServiceException
+     *          if the watch service is closed
+     * @throws  NotDirectoryException
+     *          if the file is registered to watch the entries in a directory
+     *          and the file is not a directory  <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    @Override
+    WatchKey register(WatchService watcher,
+                      WatchEvent.Kind<?>[] events,
+                      WatchEvent.Modifier... modifiers)
+        throws IOException;
+
+    /**
+     * Registers the file located by this path with a watch service.
+     *
+     * <p> An invocation of this method behaves in exactly the same way as the
+     * invocation
+     * <pre>
+     *     watchable.{@link #register(WatchService,WatchEvent.Kind[],WatchEvent.Modifier[]) register}(watcher, events, new WatchEvent.Modifier[0]);
+     * </pre>
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we wish to register a directory for entry create, delete, and modify
+     * events:
+     * <pre>
+     *     Path dir = ...
+     *     WatchService watcher = ...
+     *
+     *     WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
+     * </pre>
+     * @param   watcher
+     *          The watch service to which this object is to be registered
+     * @param   events
+     *          The events for which this object should be registered
+     *
+     * @return  A key representing the registration of this object with the
+     *          given watch service
+     *
+     * @throws  UnsupportedOperationException
+     *          If unsupported events are specified
+     * @throws  IllegalArgumentException
+     *          If an invalid combination of events is specified
+     * @throws  ClosedWatchServiceException
+     *          If the watch service is closed
+     * @throws  NotDirectoryException
+     *          If the file is registered to watch the entries in a directory
+     *          and the file is not a directory  <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    @Override
+    WatchKey register(WatchService watcher,
+                      WatchEvent.Kind<?>... events)
+        throws IOException;
+
+    // -- Iterable --
+
+    /**
+     * Returns an iterator over the name elements of this path.
+     *
+     * <p> The first element returned by the iterator represents the name
+     * element that is closest to the root in the directory hierarchy, the
+     * second element is the next closest, and so on. The last element returned
+     * is the name of the file or directory denoted by this path. The {@link
+     * #getRoot root} component, if present, is not returned by the iterator.
+     *
+     * @return  an iterator over the name elements of this path.
+     */
+    @Override
+    Iterator<Path> iterator();
+
+    // -- compareTo/equals/hashCode --
+
+    /**
+     * Compares two abstract paths lexicographically. The ordering defined by
+     * this method is provider specific, and in the case of the default
+     * provider, platform specific. This method does not access the file system
+     * and neither file is required to exist.
+     *
+     * <p> This method may not be used to compare paths that are associated
+     * with different file system providers.
+     *
+     * @param   other  the path compared to this path.
+     *
+     * @return  zero if the argument is {@link #equals equal} to this path, a
+     *          value less than zero if this path is lexicographically less than
+     *          the argument, or a value greater than zero if this path is
+     *          lexicographically greater than the argument
+     *
+     * @throws  ClassCastException
+     *          if the paths are associated with different providers
+     */
+    @Override
+    int compareTo(Path other);
+
+    /**
+     * Tests this path for equality with the given object.
+     *
+     * <p> If the given object is not a Path, or is a Path associated with a
+     * different {@code FileSystem}, then this method returns {@code false}.
+     *
+     * <p> Whether or not two path are equal depends on the file system
+     * implementation. In some cases the paths are compared without regard
+     * to case, and others are case sensitive. This method does not access the
+     * file system and the file is not required to exist. Where required, the
+     * {@link Files#isSameFile isSameFile} method may be used to check if two
+     * paths locate the same file.
+     *
+     * <p> This method satisfies the general contract of the {@link
+     * java.lang.Object#equals(Object) Object.equals} method. </p>
+     *
+     * @param   other
+     *          the object to which this object is to be compared
+     *
+     * @return  {@code true} if, and only if, the given object is a {@code Path}
+     *          that is identical to this {@code Path}
+     */
+    boolean equals(Object other);
+
+    /**
+     * Computes a hash code for this path.
+     *
+     * <p> The hash code is based upon the components of the path, and
+     * satisfies the general contract of the {@link Object#hashCode
+     * Object.hashCode} method.
+     *
+     * @return  the hash-code value for this path
+     */
+    int hashCode();
+
+    /**
+     * Returns the string representation of this path.
+     *
+     * <p> If this path was created by converting a path string using the
+     * {@link FileSystem#getPath getPath} method then the path string returned
+     * by this method may differ from the original String used to create the path.
+     *
+     * <p> The returned path string uses the default name {@link
+     * FileSystem#getSeparator separator} to separate names in the path.
+     *
+     * @return  the string representation of this path
+     */
+    String toString();
+}
diff --git a/java/nio/file/PathMatcher.java b/java/nio/file/PathMatcher.java
new file mode 100644
index 0000000..24e6149
--- /dev/null
+++ b/java/nio/file/PathMatcher.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+/**
+ * An interface that is implemented by objects that perform match operations on
+ * paths.
+ *
+ * @since 1.7
+ *
+ * @see FileSystem#getPathMatcher
+ * @see Files#newDirectoryStream(Path,String)
+ */
+@FunctionalInterface
+public interface PathMatcher {
+    /**
+     * Tells if given path matches this matcher's pattern.
+     *
+     * @param   path
+     *          the path to match
+     *
+     * @return  {@code true} if, and only if, the path matches this
+     *          matcher's pattern
+     */
+    boolean matches(Path path);
+}
diff --git a/java/nio/file/Paths.java b/java/nio/file/Paths.java
new file mode 100644
index 0000000..bb49f99
--- /dev/null
+++ b/java/nio/file/Paths.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+import java.nio.file.spi.FileSystemProvider;
+import java.net.URI;
+
+/**
+ * This class consists exclusively of static methods that return a {@link Path}
+ * by converting a path string or {@link URI}.
+ *
+ * @since 1.7
+ */
+
+public final class Paths {
+    private Paths() { }
+
+    /**
+     * Converts a path string, or a sequence of strings that when joined form
+     * a path string, to a {@code Path}. If {@code more} does not specify any
+     * elements then the value of the {@code first} parameter is the path string
+     * to convert. If {@code more} specifies one or more elements then each
+     * non-empty string, including {@code first}, is considered to be a sequence
+     * of name elements (see {@link Path}) and is joined to form a path string.
+     * The details as to how the Strings are joined is provider specific but
+     * typically they will be joined using the {@link FileSystem#getSeparator
+     * name-separator} as the separator. For example, if the name separator is
+     * "{@code /}" and {@code getPath("/foo","bar","gus")} is invoked, then the
+     * path string {@code "/foo/bar/gus"} is converted to a {@code Path}.
+     * A {@code Path} representing an empty path is returned if {@code first}
+     * is the empty string and {@code more} does not contain any non-empty
+     * strings.
+     *
+     * <p> The {@code Path} is obtained by invoking the {@link FileSystem#getPath
+     * getPath} method of the {@link FileSystems#getDefault default} {@link
+     * FileSystem}.
+     *
+     * <p> Note that while this method is very convenient, using it will imply
+     * an assumed reference to the default {@code FileSystem} and limit the
+     * utility of the calling code. Hence it should not be used in library code
+     * intended for flexible reuse. A more flexible alternative is to use an
+     * existing {@code Path} instance as an anchor, such as:
+     * <pre>
+     *     Path dir = ...
+     *     Path path = dir.resolve("file");
+     * </pre>
+     *
+     * @param   first
+     *          the path string or initial part of the path string
+     * @param   more
+     *          additional strings to be joined to form the path string
+     *
+     * @return  the resulting {@code Path}
+     *
+     * @throws  InvalidPathException
+     *          if the path string cannot be converted to a {@code Path}
+     *
+     * @see FileSystem#getPath
+     */
+    public static Path get(String first, String... more) {
+        return FileSystems.getDefault().getPath(first, more);
+    }
+
+    /**
+     * Converts the given URI to a {@link Path} object.
+     *
+     * <p> This method iterates over the {@link FileSystemProvider#installedProviders()
+     * installed} providers to locate the provider that is identified by the
+     * URI {@link URI#getScheme scheme} of the given URI. URI schemes are
+     * compared without regard to case. If the provider is found then its {@link
+     * FileSystemProvider#getPath getPath} method is invoked to convert the
+     * URI.
+     *
+     * <p> In the case of the default provider, identified by the URI scheme
+     * "file", the given URI has a non-empty path component, and undefined query
+     * and fragment components. Whether the authority component may be present
+     * is platform specific. The returned {@code Path} is associated with the
+     * {@link FileSystems#getDefault default} file system.
+     *
+     * <p> The default provider provides a similar <em>round-trip</em> guarantee
+     * to the {@link java.io.File} class. For a given {@code Path} <i>p</i> it
+     * is guaranteed that
+     * <blockquote><tt>
+     * Paths.get(</tt><i>p</i><tt>.{@link Path#toUri() toUri}()).equals(</tt>
+     * <i>p</i><tt>.{@link Path#toAbsolutePath() toAbsolutePath}())</tt>
+     * </blockquote>
+     * so long as the original {@code Path}, the {@code URI}, and the new {@code
+     * Path} are all created in (possibly different invocations of) the same
+     * Java virtual machine. Whether other providers make any guarantees is
+     * provider specific and therefore unspecified.
+     *
+     * @param   uri
+     *          the URI to convert
+     *
+     * @return  the resulting {@code Path}
+     *
+     * @throws  IllegalArgumentException
+     *          if preconditions on the {@code uri} parameter do not hold. The
+     *          format of the URI is provider specific.
+     * @throws  FileSystemNotFoundException
+     *          The file system, identified by the URI, does not exist and
+     *          cannot be created automatically, or the provider identified by
+     *          the URI's scheme component is not installed
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission to access the file system
+     */
+    public static Path get(URI uri) {
+        String scheme =  uri.getScheme();
+        if (scheme == null)
+            throw new IllegalArgumentException("Missing scheme");
+
+        // check for default provider to avoid loading of installed providers
+        if (scheme.equalsIgnoreCase("file"))
+            return FileSystems.getDefault().provider().getPath(uri);
+
+        // try to find provider
+        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            if (provider.getScheme().equalsIgnoreCase(scheme)) {
+                return provider.getPath(uri);
+            }
+        }
+
+        throw new FileSystemNotFoundException("Provider \"" + scheme + "\" not installed");
+    }
+}
diff --git a/java/nio/file/ProviderMismatchException.java b/java/nio/file/ProviderMismatchException.java
new file mode 100644
index 0000000..0220d6e
--- /dev/null
+++ b/java/nio/file/ProviderMismatchException.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to invoke a method on an
+ * object created by one file system provider with a parameter created by a
+ * different file system provider.
+ */
+public class ProviderMismatchException
+    extends java.lang.IllegalArgumentException
+{
+    static final long serialVersionUID = 4990847485741612530L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ProviderMismatchException() {
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   msg
+     *          the detail message
+     */
+    public ProviderMismatchException(String msg) {
+        super(msg);
+    }
+}
diff --git a/java/nio/file/ProviderNotFoundException.java b/java/nio/file/ProviderNotFoundException.java
new file mode 100644
index 0000000..8fa0cef
--- /dev/null
+++ b/java/nio/file/ProviderNotFoundException.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Runtime exception thrown when a provider of the required type cannot be found.
+ */
+
+public class ProviderNotFoundException
+    extends RuntimeException
+{
+    static final long serialVersionUID = -1880012509822920354L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ProviderNotFoundException() {
+    }
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   msg
+     *          the detail message
+     */
+    public ProviderNotFoundException(String msg) {
+        super(msg);
+    }
+}
diff --git a/java/nio/file/ReadOnlyFileSystemException.java b/java/nio/file/ReadOnlyFileSystemException.java
new file mode 100644
index 0000000..9b25e5f
--- /dev/null
+++ b/java/nio/file/ReadOnlyFileSystemException.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Unchecked exception thrown when an attempt is made to update an object
+ * associated with a {@link FileSystem#isReadOnly() read-only} {@code FileSystem}.
+ */
+
+public class ReadOnlyFileSystemException
+    extends UnsupportedOperationException
+{
+    static final long serialVersionUID = -6822409595617487197L;
+
+    /**
+     * Constructs an instance of this class.
+     */
+    public ReadOnlyFileSystemException() {
+    }
+}
diff --git a/java/nio/file/SecureDirectoryStream.java b/java/nio/file/SecureDirectoryStream.java
new file mode 100644
index 0000000..064618b
--- /dev/null
+++ b/java/nio/file/SecureDirectoryStream.java
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.util.Set;
+import java.io.IOException;
+
+/**
+ * A {@code DirectoryStream} that defines operations on files that are located
+ * relative to an open directory. A {@code SecureDirectoryStream} is intended
+ * for use by sophisticated or security sensitive applications requiring to
+ * traverse file trees or otherwise operate on directories in a race-free manner.
+ * Race conditions can arise when a sequence of file operations cannot be
+ * carried out in isolation. Each of the file operations defined by this
+ * interface specify a relative path. All access to the file is relative
+ * to the open directory irrespective of if the directory is moved or replaced
+ * by an attacker while the directory is open. A {@code SecureDirectoryStream}
+ * may also be used as a virtual <em>working directory</em>.
+ *
+ * <p> A {@code SecureDirectoryStream} requires corresponding support from the
+ * underlying operating system. Where an implementation supports this features
+ * then the {@code DirectoryStream} returned by the {@link Files#newDirectoryStream
+ * newDirectoryStream} method will be a {@code SecureDirectoryStream} and must
+ * be cast to that type in order to invoke the methods defined by this interface.
+ *
+ * <p> In the case of the default {@link java.nio.file.spi.FileSystemProvider
+ * provider}, and a security manager is set, then the permission checks are
+ * performed using the path obtained by resolving the given relative path
+ * against the <i>original path</i> of the directory (irrespective of if the
+ * directory is moved since it was opened).
+ *
+ * @since   1.7
+ */
+
+public interface SecureDirectoryStream<T>
+    extends DirectoryStream<T>
+{
+    /**
+     * Opens the directory identified by the given path, returning a {@code
+     * SecureDirectoryStream} to iterate over the entries in the directory.
+     *
+     * <p> This method works in exactly the manner specified by the {@link
+     * Files#newDirectoryStream(Path) newDirectoryStream} method for the case that
+     * the {@code path} parameter is an {@link Path#isAbsolute absolute} path.
+     * When the parameter is a relative path then the directory to open is
+     * relative to this open directory. The {@link
+     * LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
+     * ensure that this method fails if the file is a symbolic link.
+     *
+     * <p> The new directory stream, once created, is not dependent upon the
+     * directory stream used to create it. Closing this directory stream has no
+     * effect upon newly created directory stream.
+     *
+     * @param   path
+     *          the path to the directory to open
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a new and open {@code SecureDirectoryStream} object
+     *
+     * @throws  ClosedDirectoryStreamException
+     *          if the directory stream is closed
+     * @throws  NotDirectoryException
+     *          if the file could not otherwise be opened because it is not
+     *          a directory <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the directory.
+     */
+    SecureDirectoryStream<T> newDirectoryStream(T path, LinkOption... options)
+        throws IOException;
+
+    /**
+     * Opens or creates a file in this directory, returning a seekable byte
+     * channel to access the file.
+     *
+     * <p> This method works in exactly the manner specified by the {@link
+     * Files#newByteChannel Files.newByteChannel} method for the
+     * case that the {@code path} parameter is an {@link Path#isAbsolute absolute}
+     * path. When the parameter is a relative path then the file to open or
+     * create is relative to this open directory. In addition to the options
+     * defined by the {@code Files.newByteChannel} method, the {@link
+     * LinkOption#NOFOLLOW_LINKS NOFOLLOW_LINKS} option may be used to
+     * ensure that this method fails if the file is a symbolic link.
+     *
+     * <p> The channel, once created, is not dependent upon the directory stream
+     * used to create it. Closing this directory stream has no effect upon the
+     * channel.
+     *
+     * @param   path
+     *          the path of the file to open open or create
+     * @param   options
+     *          options specifying how the file is opened
+     * @param   attrs
+     *          an optional list of attributes to set atomically when creating
+     *          the file
+     *
+     * @return  the seekable byte channel
+     *
+     * @throws  ClosedDirectoryStreamException
+     *          if the directory stream is closed
+     * @throws  IllegalArgumentException
+     *          if the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported open option is specified or the array contains
+     *          attributes that cannot be set atomically when creating the file
+     * @throws  FileAlreadyExistsException
+     *          if a file of that name already exists and the {@link
+     *          StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the path if the file
+     *          is opened for reading. The {@link SecurityManager#checkWrite(String)
+     *          checkWrite} method is invoked to check write access to the path
+     *          if the file is opened for writing.
+     */
+    SeekableByteChannel newByteChannel(T path,
+                                       Set<? extends OpenOption> options,
+                                       FileAttribute<?>... attrs)
+        throws IOException;
+
+    /**
+     * Deletes a file.
+     *
+     * <p> Unlike the {@link Files#delete delete()} method, this method does
+     * not first examine the file to determine if the file is a directory.
+     * Whether a directory is deleted by this method is system dependent and
+     * therefore not specified. If the file is a symbolic link, then the link
+     * itself, not the final target of the link, is deleted. When the
+     * parameter is a relative path then the file to delete is relative to
+     * this open directory.
+     *
+     * @param   path
+     *          the path of the file to delete
+     *
+     * @throws  ClosedDirectoryStreamException
+     *          if the directory stream is closed
+     * @throws  NoSuchFileException
+     *          if the file does not exist <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkDelete(String) checkDelete}
+     *          method is invoked to check delete access to the file
+     */
+    void deleteFile(T path) throws IOException;
+
+    /**
+     * Deletes a directory.
+     *
+     * <p> Unlike the {@link Files#delete delete()} method, this method
+     * does not first examine the file to determine if the file is a directory.
+     * Whether non-directories are deleted by this method is system dependent and
+     * therefore not specified. When the parameter is a relative path then the
+     * directory to delete is relative to this open directory.
+     *
+     * @param   path
+     *          the path of the directory to delete
+     *
+     * @throws  ClosedDirectoryStreamException
+     *          if the directory stream is closed
+     * @throws  NoSuchFileException
+     *          if the directory does not exist <i>(optional specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          if the directory could not otherwise be deleted because it is
+     *          not empty <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkDelete(String) checkDelete}
+     *          method is invoked to check delete access to the directory
+     */
+    void deleteDirectory(T path) throws IOException;
+
+    /**
+     * Move a file from this directory to another directory.
+     *
+     * <p> This method works in a similar manner to {@link Files#move move}
+     * method when the {@link StandardCopyOption#ATOMIC_MOVE ATOMIC_MOVE} option
+     * is specified. That is, this method moves a file as an atomic file system
+     * operation. If the {@code srcpath} parameter is an {@link Path#isAbsolute
+     * absolute} path then it locates the source file. If the parameter is a
+     * relative path then it is located relative to this open directory. If
+     * the {@code targetpath} parameter is absolute then it locates the target
+     * file (the {@code targetdir} parameter is ignored). If the parameter is
+     * a relative path it is located relative to the open directory identified
+     * by the {@code targetdir} parameter. In all cases, if the target file
+     * exists then it is implementation specific if it is replaced or this
+     * method fails.
+     *
+     * @param   srcpath
+     *          the name of the file to move
+     * @param   targetdir
+     *          the destination directory
+     * @param   targetpath
+     *          the name to give the file in the destination directory
+     *
+     * @throws  ClosedDirectoryStreamException
+     *          if this or the target directory stream is closed
+     * @throws  FileAlreadyExistsException
+     *          if the file already exists in the target directory and cannot
+     *          be replaced <i>(optional specific exception)</i>
+     * @throws  AtomicMoveNotSupportedException
+     *          if the file cannot be moved as an atomic file system operation
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to both the source and
+     *          target file.
+     */
+    void move(T srcpath, SecureDirectoryStream<T> targetdir, T targetpath)
+        throws IOException;
+
+    /**
+     * Returns a new file attribute view to access the file attributes of this
+     * directory.
+     *
+     * <p> The resulting file attribute view can be used to read or update the
+     * attributes of this (open) directory. The {@code type} parameter specifies
+     * the type of the attribute view and the method returns an instance of that
+     * type if supported. Invoking this method to obtain a {@link
+     * BasicFileAttributeView} always returns an instance of that class that is
+     * bound to this open directory.
+     *
+     * <p> The state of resulting file attribute view is intimately connected
+     * to this directory stream. Once the directory stream is {@link #close closed},
+     * then all methods to read or update attributes will throw {@link
+     * ClosedDirectoryStreamException ClosedDirectoryStreamException}.
+     *
+     * @param   <V>
+     *          The {@code FileAttributeView} type
+     * @param   type
+     *          the {@code Class} object corresponding to the file attribute view
+     *
+     * @return  a new file attribute view of the specified type bound to
+     *          this directory stream, or {@code null} if the attribute view
+     *          type is not available
+     */
+    <V extends FileAttributeView> V getFileAttributeView(Class<V> type);
+
+    /**
+     * Returns a new file attribute view to access the file attributes of a file
+     * in this directory.
+     *
+     * <p> The resulting file attribute view can be used to read or update the
+     * attributes of file in this directory. The {@code type} parameter specifies
+     * the type of the attribute view and the method returns an instance of that
+     * type if supported. Invoking this method to obtain a {@link
+     * BasicFileAttributeView} always returns an instance of that class that is
+     * bound to the file in the directory.
+     *
+     * <p> The state of resulting file attribute view is intimately connected
+     * to this directory stream. Once the directory stream {@link #close closed},
+     * then all methods to read or update attributes will throw {@link
+     * ClosedDirectoryStreamException ClosedDirectoryStreamException}. The
+     * file is not required to exist at the time that the file attribute view
+     * is created but methods to read or update attributes of the file will
+     * fail when invoked and the file does not exist.
+     *
+     * @param   <V>
+     *          The {@code FileAttributeView} type
+     * @param   path
+     *          the path of the file
+     * @param   type
+     *          the {@code Class} object corresponding to the file attribute view
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a new file attribute view of the specified type bound to a
+     *          this directory stream, or {@code null} if the attribute view
+     *          type is not available
+     *
+     */
+    <V extends FileAttributeView> V getFileAttributeView(T path,
+                                                         Class<V> type,
+                                                         LinkOption... options);
+}
diff --git a/java/nio/file/SimpleFileVisitor.java b/java/nio/file/SimpleFileVisitor.java
new file mode 100644
index 0000000..321e30e
--- /dev/null
+++ b/java/nio/file/SimpleFileVisitor.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+import java.nio.file.attribute.BasicFileAttributes;
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * A simple visitor of files with default behavior to visit all files and to
+ * re-throw I/O errors.
+ *
+ * <p> Methods in this class may be overridden subject to their general contract.
+ *
+ * @param   <T>     The type of reference to the files
+ *
+ * @since 1.7
+ */
+
+public class SimpleFileVisitor<T> implements FileVisitor<T> {
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected SimpleFileVisitor() {
+    }
+
+    /**
+     * Invoked for a directory before entries in the directory are visited.
+     *
+     * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
+     * CONTINUE}.
+     */
+    @Override
+    public FileVisitResult preVisitDirectory(T dir, BasicFileAttributes attrs)
+        throws IOException
+    {
+        Objects.requireNonNull(dir);
+        Objects.requireNonNull(attrs);
+        return FileVisitResult.CONTINUE;
+    }
+
+    /**
+     * Invoked for a file in a directory.
+     *
+     * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
+     * CONTINUE}.
+     */
+    @Override
+    public FileVisitResult visitFile(T file, BasicFileAttributes attrs)
+        throws IOException
+    {
+        Objects.requireNonNull(file);
+        Objects.requireNonNull(attrs);
+        return FileVisitResult.CONTINUE;
+    }
+
+    /**
+     * Invoked for a file that could not be visited.
+     *
+     * <p> Unless overridden, this method re-throws the I/O exception that prevented
+     * the file from being visited.
+     */
+    @Override
+    public FileVisitResult visitFileFailed(T file, IOException exc)
+        throws IOException
+    {
+        Objects.requireNonNull(file);
+        throw exc;
+    }
+
+    /**
+     * Invoked for a directory after entries in the directory, and all of their
+     * descendants, have been visited.
+     *
+     * <p> Unless overridden, this method returns {@link FileVisitResult#CONTINUE
+     * CONTINUE} if the directory iteration completes without an I/O exception;
+     * otherwise this method re-throws the I/O exception that caused the iteration
+     * of the directory to terminate prematurely.
+     */
+    @Override
+    public FileVisitResult postVisitDirectory(T dir, IOException exc)
+        throws IOException
+    {
+        Objects.requireNonNull(dir);
+        if (exc != null)
+            throw exc;
+        return FileVisitResult.CONTINUE;
+    }
+}
diff --git a/java/nio/file/StandardCopyOption.java b/java/nio/file/StandardCopyOption.java
new file mode 100644
index 0000000..30a5786
--- /dev/null
+++ b/java/nio/file/StandardCopyOption.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Defines the standard copy options.
+ *
+ * @since 1.7
+ */
+
+public enum StandardCopyOption implements CopyOption {
+    /**
+     * Replace an existing file if it exists.
+     */
+    REPLACE_EXISTING,
+    /**
+     * Copy attributes to the new file.
+     */
+    COPY_ATTRIBUTES,
+    /**
+     * Move the file as an atomic file system operation.
+     */
+    ATOMIC_MOVE;
+}
diff --git a/java/nio/file/StandardOpenOption.java b/java/nio/file/StandardOpenOption.java
new file mode 100644
index 0000000..3ed2a9d
--- /dev/null
+++ b/java/nio/file/StandardOpenOption.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file;
+
+/**
+ * Defines the standard open options.
+ *
+ * @since 1.7
+ */
+
+public enum StandardOpenOption implements OpenOption {
+    /**
+     * Open for read access.
+     */
+    READ,
+
+    /**
+     * Open for write access.
+     */
+    WRITE,
+
+    /**
+     * If the file is opened for {@link #WRITE} access then bytes will be written
+     * to the end of the file rather than the beginning.
+     *
+     * <p> If the file is opened for write access by other programs, then it
+     * is file system specific if writing to the end of the file is atomic.
+     */
+    APPEND,
+
+    /**
+     * If the file already exists and it is opened for {@link #WRITE}
+     * access, then its length is truncated to 0. This option is ignored
+     * if the file is opened only for {@link #READ} access.
+     */
+    TRUNCATE_EXISTING,
+
+    /**
+     * Create a new file if it does not exist.
+     * This option is ignored if the {@link #CREATE_NEW} option is also set.
+     * The check for the existence of the file and the creation of the file
+     * if it does not exist is atomic with respect to other file system
+     * operations.
+     */
+    CREATE,
+
+    /**
+     * Create a new file, failing if the file already exists.
+     * The check for the existence of the file and the creation of the file
+     * if it does not exist is atomic with respect to other file system
+     * operations.
+     */
+    CREATE_NEW,
+
+    /**
+     * Delete on close. When this option is present then the implementation
+     * makes a <em>best effort</em> attempt to delete the file when closed
+     * by the appropriate {@code close} method. If the {@code close} method is
+     * not invoked then a <em>best effort</em> attempt is made to delete the
+     * file when the Java virtual machine terminates (either normally, as
+     * defined by the Java Language Specification, or where possible, abnormally).
+     * This option is primarily intended for use with <em>work files</em> that
+     * are used solely by a single instance of the Java virtual machine. This
+     * option is not recommended for use when opening files that are open
+     * concurrently by other entities. Many of the details as to when and how
+     * the file is deleted are implementation specific and therefore not
+     * specified. In particular, an implementation may be unable to guarantee
+     * that it deletes the expected file when replaced by an attacker while the
+     * file is open. Consequently, security sensitive applications should take
+     * care when using this option.
+     *
+     * <p> For security reasons, this option may imply the {@link
+     * LinkOption#NOFOLLOW_LINKS} option. In other words, if the option is present
+     * when opening an existing file that is a symbolic link then it may fail
+     * (by throwing {@link java.io.IOException}).
+     */
+    DELETE_ON_CLOSE,
+
+    /**
+     * Sparse file. When used with the {@link #CREATE_NEW} option then this
+     * option provides a <em>hint</em> that the new file will be sparse. The
+     * option is ignored when the file system does not support the creation of
+     * sparse files.
+     */
+    SPARSE,
+
+    /**
+     * Requires that every update to the file's content or metadata be written
+     * synchronously to the underlying storage device.
+     *
+     * @see <a href="package-summary.html#integrity">Synchronized I/O file integrity</a>
+     */
+    SYNC,
+
+    /**
+     * Requires that every update to the file's content be written
+     * synchronously to the underlying storage device.
+     *
+     * @see <a href="package-summary.html#integrity">Synchronized I/O file integrity</a>
+     */
+    DSYNC;
+}
diff --git a/java/nio/file/StandardWatchEventKinds.java b/java/nio/file/StandardWatchEventKinds.java
new file mode 100644
index 0000000..8b3aba0
--- /dev/null
+++ b/java/nio/file/StandardWatchEventKinds.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+/**
+ * Defines the <em>standard</em> event kinds.
+ *
+ * @since 1.7
+ */
+
+public final class StandardWatchEventKinds {
+    private StandardWatchEventKinds() { }
+
+    /**
+     * A special event to indicate that events may have been lost or
+     * discarded.
+     *
+     * <p> The {@link WatchEvent#context context} for this event is
+     * implementation specific and may be {@code null}. The event {@link
+     * WatchEvent#count count} may be greater than {@code 1}.
+     *
+     * @see WatchService
+     */
+    public static final WatchEvent.Kind<Object> OVERFLOW =
+        new StdWatchEventKind<Object>("OVERFLOW", Object.class);
+
+    /**
+     * Directory entry created.
+     *
+     * <p> When a directory is registered for this event then the {@link WatchKey}
+     * is queued when it is observed that an entry is created in the directory
+     * or renamed into the directory. The event {@link WatchEvent#count count}
+     * for this event is always {@code 1}.
+     */
+    public static final WatchEvent.Kind<Path> ENTRY_CREATE =
+        new StdWatchEventKind<Path>("ENTRY_CREATE", Path.class);
+
+    /**
+     * Directory entry deleted.
+     *
+     * <p> When a directory is registered for this event then the {@link WatchKey}
+     * is queued when it is observed that an entry is deleted or renamed out of
+     * the directory. The event {@link WatchEvent#count count} for this event
+     * is always {@code 1}.
+     */
+    public static final WatchEvent.Kind<Path> ENTRY_DELETE =
+        new StdWatchEventKind<Path>("ENTRY_DELETE", Path.class);
+
+    /**
+     * Directory entry modified.
+     *
+     * <p> When a directory is registered for this event then the {@link WatchKey}
+     * is queued when it is observed that an entry in the directory has been
+     * modified. The event {@link WatchEvent#count count} for this event is
+     * {@code 1} or greater.
+     */
+    public static final WatchEvent.Kind<Path> ENTRY_MODIFY =
+        new StdWatchEventKind<Path>("ENTRY_MODIFY", Path.class);
+
+    private static class StdWatchEventKind<T> implements WatchEvent.Kind<T> {
+        private final String name;
+        private final Class<T> type;
+        StdWatchEventKind(String name, Class<T> type) {
+            this.name = name;
+            this.type = type;
+        }
+        @Override public String name() { return name; }
+        @Override public Class<T> type() { return type; }
+        @Override public String toString() { return name; }
+    }
+}
diff --git a/java/nio/file/TempFileHelper.java b/java/nio/file/TempFileHelper.java
new file mode 100644
index 0000000..8d171de
--- /dev/null
+++ b/java/nio/file/TempFileHelper.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2009, 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.nio.file;
+
+import java.util.Set;
+import java.util.EnumSet;
+import java.security.SecureRandom;
+import static java.security.AccessController.*;
+import java.io.IOException;
+import java.nio.file.attribute.FileAttribute;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import static java.nio.file.attribute.PosixFilePermission.*;
+import sun.security.action.GetPropertyAction;
+
+
+/**
+ * Helper class to support creation of temporary files and directories with
+ * initial attributes.
+ */
+
+class TempFileHelper {
+    private TempFileHelper() { }
+
+    // temporary directory location
+    private static final Path tmpdir =
+        Paths.get(doPrivileged(new GetPropertyAction("java.io.tmpdir")));
+
+    private static final boolean isPosix =
+        FileSystems.getDefault().supportedFileAttributeViews().contains("posix");
+
+    // file name generation, same as java.io.File for now
+    private static final SecureRandom random = new SecureRandom();
+    private static Path generatePath(String prefix, String suffix, Path dir) {
+        long n = random.nextLong();
+        n = (n == Long.MIN_VALUE) ? 0 : Math.abs(n);
+        Path name = dir.getFileSystem().getPath(prefix + Long.toString(n) + suffix);
+        // the generated name should be a simple file name
+        if (name.getParent() != null)
+            throw new IllegalArgumentException("Invalid prefix or suffix");
+        return dir.resolve(name);
+    }
+
+    // default file and directory permissions (lazily initialized)
+    private static class PosixPermissions {
+        static final FileAttribute<Set<PosixFilePermission>> filePermissions =
+            PosixFilePermissions.asFileAttribute(EnumSet.of(OWNER_READ, OWNER_WRITE));
+        static final FileAttribute<Set<PosixFilePermission>> dirPermissions =
+            PosixFilePermissions.asFileAttribute(EnumSet
+                .of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE));
+    }
+
+    /**
+     * Creates a file or directory in in the given given directory (or in the
+     * temporary directory if dir is {@code null}).
+     */
+    private static Path create(Path dir,
+                               String prefix,
+                               String suffix,
+                               boolean createDirectory,
+                               FileAttribute<?>[] attrs)
+        throws IOException
+    {
+        if (prefix == null)
+            prefix = "";
+        if (suffix == null)
+            suffix = (createDirectory) ? "" : ".tmp";
+        if (dir == null)
+            dir = tmpdir;
+
+        // in POSIX environments use default file and directory permissions
+        // if initial permissions not given by caller.
+        if (isPosix && (dir.getFileSystem() == FileSystems.getDefault())) {
+            if (attrs.length == 0) {
+                // no attributes so use default permissions
+                attrs = new FileAttribute<?>[1];
+                attrs[0] = (createDirectory) ? PosixPermissions.dirPermissions :
+                                               PosixPermissions.filePermissions;
+            } else {
+                // check if posix permissions given; if not use default
+                boolean hasPermissions = false;
+                for (int i=0; i<attrs.length; i++) {
+                    if (attrs[i].name().equals("posix:permissions")) {
+                        hasPermissions = true;
+                        break;
+                    }
+                }
+                if (!hasPermissions) {
+                    FileAttribute<?>[] copy = new FileAttribute<?>[attrs.length+1];
+                    System.arraycopy(attrs, 0, copy, 0, attrs.length);
+                    attrs = copy;
+                    attrs[attrs.length-1] = (createDirectory) ?
+                        PosixPermissions.dirPermissions :
+                        PosixPermissions.filePermissions;
+                }
+            }
+        }
+
+        // loop generating random names until file or directory can be created
+        SecurityManager sm = System.getSecurityManager();
+        for (;;) {
+            Path f;
+            try {
+                f = generatePath(prefix, suffix, dir);
+            } catch (InvalidPathException e) {
+                // don't reveal temporary directory location
+                if (sm != null)
+                    throw new IllegalArgumentException("Invalid prefix or suffix");
+                throw e;
+            }
+            try {
+                if (createDirectory) {
+                    return Files.createDirectory(f, attrs);
+                } else {
+                    return Files.createFile(f, attrs);
+                }
+            } catch (SecurityException e) {
+                // don't reveal temporary directory location
+                if (dir == tmpdir && sm != null)
+                    throw new SecurityException("Unable to create temporary file or directory");
+                throw e;
+            } catch (FileAlreadyExistsException e) {
+                // ignore
+            }
+        }
+    }
+
+    /**
+     * Creates a temporary file in the given directory, or in in the
+     * temporary directory if dir is {@code null}.
+     */
+    static Path createTempFile(Path dir,
+                               String prefix,
+                               String suffix,
+                               FileAttribute<?>[] attrs)
+        throws IOException
+    {
+        return create(dir, prefix, suffix, false, attrs);
+    }
+
+    /**
+     * Creates a temporary directory in the given directory, or in in the
+     * temporary directory if dir is {@code null}.
+     */
+    static Path createTempDirectory(Path dir,
+                                    String prefix,
+                                    FileAttribute<?>[] attrs)
+        throws IOException
+    {
+        return create(dir, prefix, null, true, attrs);
+    }
+}
diff --git a/java/nio/file/WatchEvent.java b/java/nio/file/WatchEvent.java
new file mode 100644
index 0000000..25438a8
--- /dev/null
+++ b/java/nio/file/WatchEvent.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+/**
+ * An event or a repeated event for an object that is registered with a {@link
+ * WatchService}.
+ *
+ * <p> An event is classified by its {@link #kind() kind} and has a {@link
+ * #count() count} to indicate the number of times that the event has been
+ * observed. This allows for efficient representation of repeated events. The
+ * {@link #context() context} method returns any context associated with
+ * the event. In the case of a repeated event then the context is the same for
+ * all events.
+ *
+ * <p> Watch events are immutable and safe for use by multiple concurrent
+ * threads.
+ *
+ * @param   <T>     The type of the context object associated with the event
+ *
+ * @since 1.7
+ */
+
+public interface WatchEvent<T> {
+
+    /**
+     * An event kind, for the purposes of identification.
+     *
+     * @since 1.7
+     * @see StandardWatchEventKinds
+     */
+    public static interface Kind<T> {
+        /**
+         * Returns the name of the event kind.
+         *
+         * @return the name of the event kind
+         */
+        String name();
+
+        /**
+         * Returns the type of the {@link WatchEvent#context context} value.
+         *
+         *
+         * @return the type of the context value
+         */
+        Class<T> type();
+    }
+
+    /**
+     * An event modifier that qualifies how a {@link Watchable} is registered
+     * with a {@link WatchService}.
+     *
+     * <p> This release does not define any <em>standard</em> modifiers.
+     *
+     * @since 1.7
+     * @see Watchable#register
+     */
+    public static interface Modifier {
+        /**
+         * Returns the name of the modifier.
+         *
+         * @return the name of the modifier
+         */
+        String name();
+    }
+
+    /**
+     * Returns the event kind.
+     *
+     * @return  the event kind
+     */
+    Kind<T> kind();
+
+    /**
+     * Returns the event count. If the event count is greater than {@code 1}
+     * then this is a repeated event.
+     *
+     * @return  the event count
+     */
+    int count();
+
+    /**
+     * Returns the context for the event.
+     *
+     * <p> In the case of {@link StandardWatchEventKinds#ENTRY_CREATE ENTRY_CREATE},
+     * {@link StandardWatchEventKinds#ENTRY_DELETE ENTRY_DELETE}, and {@link
+     * StandardWatchEventKinds#ENTRY_MODIFY ENTRY_MODIFY} events the context is
+     * a {@code Path} that is the {@link Path#relativize relative} path between
+     * the directory registered with the watch service, and the entry that is
+     * created, deleted, or modified.
+     *
+     * @return  the event context; may be {@code null}
+     */
+    T context();
+}
diff --git a/java/nio/file/WatchKey.java b/java/nio/file/WatchKey.java
new file mode 100644
index 0000000..a4933f8
--- /dev/null
+++ b/java/nio/file/WatchKey.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+import java.util.List;
+
+/**
+ * A token representing the registration of a {@link Watchable watchable} object
+ * with a {@link WatchService}.
+ *
+ * <p> A watch key is created when a watchable object is registered with a watch
+ * service. The key remains {@link #isValid valid} until:
+ * <ol>
+ *   <li> It is cancelled, explicitly, by invoking its {@link #cancel cancel}
+ *     method, or</li>
+ *   <li> Cancelled implicitly, because the object is no longer accessible,
+ *     or </li>
+ *   <li> By {@link WatchService#close closing} the watch service. </li>
+ * </ol>
+ *
+ * <p> A watch key has a state. When initially created the key is said to be
+ * <em>ready</em>. When an event is detected then the key is <em>signalled</em>
+ * and queued so that it can be retrieved by invoking the watch service's {@link
+ * WatchService#poll() poll} or {@link WatchService#take() take} methods. Once
+ * signalled, a key remains in this state until its {@link #reset reset} method
+ * is invoked to return the key to the ready state. Events detected while the
+ * key is in the signalled state are queued but do not cause the key to be
+ * re-queued for retrieval from the watch service. Events are retrieved by
+ * invoking the key's {@link #pollEvents pollEvents} method. This method
+ * retrieves and removes all events accumulated for the object. When initially
+ * created, a watch key has no pending events. Typically events are retrieved
+ * when the key is in the signalled state leading to the following idiom:
+ *
+ * <pre>
+ *     for (;;) {
+ *         // retrieve key
+ *         WatchKey key = watcher.take();
+ *
+ *         // process events
+ *         for (WatchEvent&lt;?&gt; event: key.pollEvents()) {
+ *             :
+ *         }
+ *
+ *         // reset the key
+ *         boolean valid = key.reset();
+ *         if (!valid) {
+ *             // object no longer registered
+ *         }
+ *     }
+ * </pre>
+ *
+ * <p> Watch keys are safe for use by multiple concurrent threads. Where there
+ * are several threads retrieving signalled keys from a watch service then care
+ * should be taken to ensure that the {@code reset} method is only invoked after
+ * the events for the object have been processed. This ensures that one thread
+ * is processing the events for an object at any time.
+ *
+ * @since 1.7
+ */
+
+public interface WatchKey {
+
+    /**
+     * Tells whether or not this watch key is valid.
+     *
+     * <p> A watch key is valid upon creation and remains until it is cancelled,
+     * or its watch service is closed.
+     *
+     * @return  {@code true} if, and only if, this watch key is valid
+     */
+    boolean isValid();
+
+    /**
+     * Retrieves and removes all pending events for this watch key, returning
+     * a {@code List} of the events that were retrieved.
+     *
+     * <p> Note that this method does not wait if there are no events pending.
+     *
+     * @return  the list of the events retrieved; may be empty
+     */
+    List<WatchEvent<?>> pollEvents();
+
+    /**
+     * Resets this watch key.
+     *
+     * <p> If this watch key has been cancelled or this watch key is already in
+     * the ready state then invoking this method has no effect. Otherwise
+     * if there are pending events for the object then this watch key is
+     * immediately re-queued to the watch service. If there are no pending
+     * events then the watch key is put into the ready state and will remain in
+     * that state until an event is detected or the watch key is cancelled.
+     *
+     * @return  {@code true} if the watch key is valid and has been reset, and
+     *          {@code false} if the watch key could not be reset because it is
+     *          no longer {@link #isValid valid}
+     */
+    boolean reset();
+
+    /**
+     * Cancels the registration with the watch service. Upon return the watch key
+     * will be invalid. If the watch key is enqueued, waiting to be retrieved
+     * from the watch service, then it will remain in the queue until it is
+     * removed. Pending events, if any, remain pending and may be retrieved by
+     * invoking the {@link #pollEvents pollEvents} method after the key is
+     * cancelled.
+     *
+     * <p> If this watch key has already been cancelled then invoking this
+     * method has no effect.  Once cancelled, a watch key remains forever invalid.
+     */
+    void cancel();
+
+    /**
+     * Returns the object for which this watch key was created. This method will
+     * continue to return the object even after the key is cancelled.
+     *
+     * <p> As the {@code WatchService} is intended to map directly on to the
+     * native file event notification facility (where available) then many of
+     * details on how registered objects are watched is highly implementation
+     * specific. When watching a directory for changes for example, and the
+     * directory is moved or renamed in the file system, there is no guarantee
+     * that the watch key will be cancelled and so the object returned by this
+     * method may no longer be a valid path to the directory.
+     *
+     * @return the object for which this watch key was created
+     */
+    Watchable watchable();
+}
diff --git a/java/nio/file/WatchService.java b/java/nio/file/WatchService.java
new file mode 100644
index 0000000..d06222e
--- /dev/null
+++ b/java/nio/file/WatchService.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2007, 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.nio.file;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A watch service that <em>watches</em> registered objects for changes and
+ * events. For example a file manager may use a watch service to monitor a
+ * directory for changes so that it can update its display of the list of files
+ * when files are created or deleted.
+ *
+ * <p> A {@link Watchable} object is registered with a watch service by invoking
+ * its {@link Watchable#register register} method, returning a {@link WatchKey}
+ * to represent the registration. When an event for an object is detected the
+ * key is <em>signalled</em>, and if not currently signalled, it is queued to
+ * the watch service so that it can be retrieved by consumers that invoke the
+ * {@link #poll() poll} or {@link #take() take} methods to retrieve keys
+ * and process events. Once the events have been processed the consumer
+ * invokes the key's {@link WatchKey#reset reset} method to reset the key which
+ * allows the key to be signalled and re-queued with further events.
+ *
+ * <p> Registration with a watch service is cancelled by invoking the key's
+ * {@link WatchKey#cancel cancel} method. A key that is queued at the time that
+ * it is cancelled remains in the queue until it is retrieved. Depending on the
+ * object, a key may be cancelled automatically. For example, suppose a
+ * directory is watched and the watch service detects that it has been deleted
+ * or its file system is no longer accessible. When a key is cancelled in this
+ * manner it is signalled and queued, if not currently signalled. To ensure
+ * that the consumer is notified the return value from the {@code reset}
+ * method indicates if the key is valid.
+ *
+ * <p> A watch service is safe for use by multiple concurrent consumers. To
+ * ensure that only one consumer processes the events for a particular object at
+ * any time then care should be taken to ensure that the key's {@code reset}
+ * method is only invoked after its events have been processed. The {@link
+ * #close close} method may be invoked at any time to close the service causing
+ * any threads waiting to retrieve keys, to throw {@code
+ * ClosedWatchServiceException}.
+ *
+ * <p> File systems may report events faster than they can be retrieved or
+ * processed and an implementation may impose an unspecified limit on the number
+ * of events that it may accumulate. Where an implementation <em>knowingly</em>
+ * discards events then it arranges for the key's {@link WatchKey#pollEvents
+ * pollEvents} method to return an element with an event type of {@link
+ * StandardWatchEventKinds#OVERFLOW OVERFLOW}. This event can be used by the
+ * consumer as a trigger to re-examine the state of the object.
+ *
+ * <p> When an event is reported to indicate that a file in a watched directory
+ * has been modified then there is no guarantee that the program (or programs)
+ * that have modified the file have completed. Care should be taken to coordinate
+ * access with other programs that may be updating the file.
+ * The {@link java.nio.channels.FileChannel FileChannel} class defines methods
+ * to lock regions of a file against access by other programs.
+ *
+ * <h2>Platform dependencies</h2>
+ *
+ * <p> The implementation that observes events from the file system is intended
+ * to map directly on to the native file event notification facility where
+ * available, or to use a primitive mechanism, such as polling, when a native
+ * facility is not available. Consequently, many of the details on how events
+ * are detected, their timeliness, and whether their ordering is preserved are
+ * highly implementation specific. For example, when a file in a watched
+ * directory is modified then it may result in a single {@link
+ * StandardWatchEventKinds#ENTRY_MODIFY ENTRY_MODIFY} event in some
+ * implementations but several events in other implementations. Short-lived
+ * files (meaning files that are deleted very quickly after they are created)
+ * may not be detected by primitive implementations that periodically poll the
+ * file system to detect changes.
+ *
+ * <p> If a watched file is not located on a local storage device then it is
+ * implementation specific if changes to the file can be detected. In particular,
+ * it is not required that changes to files carried out on remote systems be
+ * detected.
+ *
+ * @since 1.7
+ *
+ * @see FileSystem#newWatchService
+ */
+
+public interface WatchService
+    extends Closeable
+{
+
+    /**
+     * Closes this watch service.
+     *
+     * <p> If a thread is currently blocked in the {@link #take take} or {@link
+     * #poll(long,TimeUnit) poll} methods waiting for a key to be queued then
+     * it immediately receives a {@link ClosedWatchServiceException}. Any
+     * valid keys associated with this watch service are {@link WatchKey#isValid
+     * invalidated}.
+     *
+     * <p> After a watch service is closed, any further attempt to invoke
+     * operations upon it will throw {@link ClosedWatchServiceException}.
+     * If this watch service is already closed then invoking this method
+     * has no effect.
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     */
+    @Override
+    void close() throws IOException;
+
+    /**
+     * Retrieves and removes the next watch key, or {@code null} if none are
+     * present.
+     *
+     * @return  the next watch key, or {@code null}
+     *
+     * @throws  ClosedWatchServiceException
+     *          if this watch service is closed
+     */
+    WatchKey poll();
+
+    /**
+     * Retrieves and removes the next watch key, waiting if necessary up to the
+     * specified wait time if none are yet present.
+     *
+     * @param   timeout
+     *          how to wait before giving up, in units of unit
+     * @param   unit
+     *          a {@code TimeUnit} determining how to interpret the timeout
+     *          parameter
+     *
+     * @return  the next watch key, or {@code null}
+     *
+     * @throws  ClosedWatchServiceException
+     *          if this watch service is closed, or it is closed while waiting
+     *          for the next key
+     * @throws  InterruptedException
+     *          if interrupted while waiting
+     */
+    WatchKey poll(long timeout, TimeUnit unit)
+        throws InterruptedException;
+
+    /**
+     * Retrieves and removes next watch key, waiting if none are yet present.
+     *
+     * @return  the next watch key
+     *
+     * @throws  ClosedWatchServiceException
+     *          if this watch service is closed, or it is closed while waiting
+     *          for the next key
+     * @throws  InterruptedException
+     *          if interrupted while waiting
+     */
+    WatchKey take() throws InterruptedException;
+}
diff --git a/java/nio/file/Watchable.java b/java/nio/file/Watchable.java
new file mode 100644
index 0000000..e3a86e6
--- /dev/null
+++ b/java/nio/file/Watchable.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file;
+
+import java.io.IOException;
+
+/**
+ * An object that may be registered with a watch service so that it can be
+ * <em>watched</em> for changes and events.
+ *
+ * <p> This interface defines the {@link #register register} method to register
+ * the object with a {@link WatchService} returning a {@link WatchKey} to
+ * represent the registration. An object may be registered with more than one
+ * watch service. Registration with a watch service is cancelled by invoking the
+ * key's {@link WatchKey#cancel cancel} method.
+ *
+ * @since 1.7
+ *
+ * @see Path#register
+ */
+
+public interface Watchable {
+
+    /**
+     * Registers an object with a watch service.
+     *
+     * <p> If the file system object identified by this object is currently
+     * registered with the watch service then the watch key, representing that
+     * registration, is returned after changing the event set or modifiers to
+     * those specified by the {@code events} and {@code modifiers} parameters.
+     * Changing the event set does not cause pending events for the object to be
+     * discarded. Objects are automatically registered for the {@link
+     * StandardWatchEventKinds#OVERFLOW OVERFLOW} event. This event is not
+     * required to be present in the array of events.
+     *
+     * <p> Otherwise the file system object has not yet been registered with the
+     * given watch service, so it is registered and the resulting new key is
+     * returned.
+     *
+     * <p> Implementations of this interface should specify the events they
+     * support.
+     *
+     * @param   watcher
+     *          the watch service to which this object is to be registered
+     * @param   events
+     *          the events for which this object should be registered
+     * @param   modifiers
+     *          the modifiers, if any, that modify how the object is registered
+     *
+     * @return  a key representing the registration of this object with the
+     *          given watch service
+     *
+     * @throws  UnsupportedOperationException
+     *          if unsupported events or modifiers are specified
+     * @throws  IllegalArgumentException
+     *          if an invalid of combination of events are modifiers are specified
+     * @throws  ClosedWatchServiceException
+     *          if the watch service is closed
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission required to monitor this object. Implementations of
+     *          this interface should specify the permission checks.
+     */
+    WatchKey register(WatchService watcher,
+                      WatchEvent.Kind<?>[] events,
+                      WatchEvent.Modifier... modifiers)
+        throws IOException;
+
+
+    /**
+     * Registers an object with a watch service.
+     *
+     * <p> An invocation of this method behaves in exactly the same way as the
+     * invocation
+     * <pre>
+     *     watchable.{@link #register(WatchService,WatchEvent.Kind[],WatchEvent.Modifier[]) register}(watcher, events, new WatchEvent.Modifier[0]);
+     * </pre>
+     *
+     * @param   watcher
+     *          the watch service to which this object is to be registered
+     * @param   events
+     *          the events for which this object should be registered
+     *
+     * @return  a key representing the registration of this object with the
+     *          given watch service
+     *
+     * @throws  UnsupportedOperationException
+     *          if unsupported events are specified
+     * @throws  IllegalArgumentException
+     *          if an invalid of combination of events are specified
+     * @throws  ClosedWatchServiceException
+     *          if the watch service is closed
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          if a security manager is installed and it denies an unspecified
+     *          permission required to monitor this object. Implementations of
+     *          this interface should specify the permission checks.
+     */
+    WatchKey register(WatchService watcher, WatchEvent.Kind<?>... events)
+        throws IOException;
+}
diff --git a/java/nio/file/attribute/AclEntry.java b/java/nio/file/attribute/AclEntry.java
new file mode 100644
index 0000000..b008494
--- /dev/null
+++ b/java/nio/file/attribute/AclEntry.java
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2007, 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.nio.file.attribute;
+
+import java.util.*;
+
+/**
+ * An entry in an access control list (ACL).
+ *
+ * <p> The ACL entry represented by this class is based on the ACL model
+ * specified in <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC&nbsp;3530:
+ * Network File System (NFS) version 4 Protocol</i></a>. Each entry has four
+ * components as follows:
+ *
+ * <ol>
+ *    <li><p> The {@link #type() type} component determines if the entry
+ *    grants or denies access. </p></li>
+ *
+ *    <li><p> The {@link #principal() principal} component, sometimes called the
+ *    "who" component, is a {@link UserPrincipal} corresponding to the identity
+ *    that the entry grants or denies access
+ *    </p></li>
+ *
+ *    <li><p> The {@link #permissions permissions} component is a set of
+ *    {@link AclEntryPermission permissions}
+ *    </p></li>
+ *
+ *    <li><p> The {@link #flags flags} component is a set of {@link AclEntryFlag
+ *    flags} to indicate how entries are inherited and propagated </p></li>
+ * </ol>
+ *
+ * <p> ACL entries are created using an associated {@link Builder} object by
+ * invoking its {@link Builder#build build} method.
+ *
+ * <p> ACL entries are immutable and are safe for use by multiple concurrent
+ * threads.
+ *
+ * @since 1.7
+ */
+
+public final class AclEntry {
+
+    private final AclEntryType type;
+    private final UserPrincipal who;
+    private final Set<AclEntryPermission> perms;
+    private final Set<AclEntryFlag> flags;
+
+    // cached hash code
+    private volatile int hash;
+
+    // private constructor
+    private AclEntry(AclEntryType type,
+                     UserPrincipal who,
+                     Set<AclEntryPermission> perms,
+                     Set<AclEntryFlag> flags)
+    {
+        this.type = type;
+        this.who = who;
+        this.perms = perms;
+        this.flags = flags;
+    }
+
+    /**
+     * A builder of {@link AclEntry} objects.
+     *
+     * <p> A {@code Builder} object is obtained by invoking one of the {@link
+     * AclEntry#newBuilder newBuilder} methods defined by the {@code AclEntry}
+     * class.
+     *
+     * <p> Builder objects are mutable and are not safe for use by multiple
+     * concurrent threads without appropriate synchronization.
+     *
+     * @since 1.7
+     */
+    public static final class Builder {
+        private AclEntryType type;
+        private UserPrincipal who;
+        private Set<AclEntryPermission> perms;
+        private Set<AclEntryFlag> flags;
+
+        private Builder(AclEntryType type,
+                        UserPrincipal who,
+                        Set<AclEntryPermission> perms,
+                        Set<AclEntryFlag> flags)
+        {
+            assert perms != null && flags != null;
+            this.type = type;
+            this.who = who;
+            this.perms = perms;
+            this.flags = flags;
+        }
+
+        /**
+         * Constructs an {@link AclEntry} from the components of this builder.
+         * The type and who components are required to have been set in order
+         * to construct an {@code AclEntry}.
+         *
+         * @return  a new ACL entry
+         *
+         * @throws  IllegalStateException
+         *          if the type or who component have not been set
+         */
+        public AclEntry build() {
+            if (type == null)
+                throw new IllegalStateException("Missing type component");
+            if (who == null)
+                throw new IllegalStateException("Missing who component");
+            return new AclEntry(type, who, perms, flags);
+        }
+
+        /**
+         * Sets the type component of this builder.
+         *
+         * @param   type  the component type
+         * @return  this builder
+         */
+        public Builder setType(AclEntryType type) {
+            if (type == null)
+                throw new NullPointerException();
+            this.type = type;
+            return this;
+        }
+
+        /**
+         * Sets the principal component of this builder.
+         *
+         * @param   who  the principal component
+         * @return  this builder
+         */
+        public Builder setPrincipal(UserPrincipal who) {
+            if (who == null)
+                throw new NullPointerException();
+            this.who = who;
+            return this;
+        }
+
+        // check set only contains elements of the given type
+        private static void checkSet(Set<?> set, Class<?> type) {
+            for (Object e: set) {
+                if (e == null)
+                    throw new NullPointerException();
+                type.cast(e);
+            }
+        }
+
+        /**
+         * Sets the permissions component of this builder. On return, the
+         * permissions component of this builder is a copy of the given set.
+         *
+         * @param   perms  the permissions component
+         * @return  this builder
+         *
+         * @throws  ClassCastException
+         *          if the set contains elements that are not of type {@code
+         *          AclEntryPermission}
+         */
+        public Builder setPermissions(Set<AclEntryPermission> perms) {
+            if (perms.isEmpty()) {
+                // EnumSet.copyOf does not allow empty set
+                perms = Collections.emptySet();
+            } else {
+                // copy and check for erroneous elements
+                perms = EnumSet.copyOf(perms);
+                checkSet(perms, AclEntryPermission.class);
+            }
+
+            this.perms = perms;
+            return this;
+        }
+
+        /**
+         * Sets the permissions component of this builder. On return, the
+         * permissions component of this builder is a copy of the permissions in
+         * the given array.
+         *
+         * @param   perms  the permissions component
+         * @return  this builder
+         */
+        public Builder setPermissions(AclEntryPermission... perms) {
+            Set<AclEntryPermission> set = EnumSet.noneOf(AclEntryPermission.class);
+            // copy and check for null elements
+            for (AclEntryPermission p: perms) {
+                if (p == null)
+                    throw new NullPointerException();
+                set.add(p);
+            }
+            this.perms = set;
+            return this;
+        }
+
+        /**
+         * Sets the flags component of this builder. On return, the flags
+         * component of this builder is a copy of the given set.
+         *
+         * @param   flags  the flags component
+         * @return  this builder
+         *
+         * @throws  ClassCastException
+         *          if the set contains elements that are not of type {@code
+         *          AclEntryFlag}
+         */
+        public Builder setFlags(Set<AclEntryFlag> flags) {
+            if (flags.isEmpty()) {
+                // EnumSet.copyOf does not allow empty set
+                flags = Collections.emptySet();
+            } else {
+                // copy and check for erroneous elements
+                flags = EnumSet.copyOf(flags);
+                checkSet(flags, AclEntryFlag.class);
+            }
+
+            this.flags = flags;
+            return this;
+        }
+
+        /**
+         * Sets the flags component of this builder. On return, the flags
+         * component of this builder is a copy of the flags in the given
+         * array.
+         *
+         * @param   flags  the flags component
+         * @return  this builder
+         */
+        public Builder setFlags(AclEntryFlag... flags) {
+            Set<AclEntryFlag> set = EnumSet.noneOf(AclEntryFlag.class);
+            // copy and check for null elements
+            for (AclEntryFlag f: flags) {
+                if (f == null)
+                    throw new NullPointerException();
+                set.add(f);
+            }
+            this.flags = set;
+            return this;
+        }
+    }
+
+    /**
+     * Constructs a new builder. The initial value of the type and who
+     * components is {@code null}. The initial value of the permissions and
+     * flags components is the empty set.
+     *
+     * @return  a new builder
+     */
+    public static Builder newBuilder() {
+        Set<AclEntryPermission> perms = Collections.emptySet();
+        Set<AclEntryFlag> flags = Collections.emptySet();
+        return new Builder(null, null, perms, flags);
+    }
+
+    /**
+     * Constructs a new builder with the components of an existing ACL entry.
+     *
+     * @param   entry  an ACL entry
+     * @return  a new builder
+     */
+    public static Builder newBuilder(AclEntry entry) {
+        return new Builder(entry.type, entry.who, entry.perms, entry.flags);
+    }
+
+    /**
+     * Returns the ACL entry type.
+     *
+     * @return the ACL entry type
+     */
+    public AclEntryType type() {
+        return type;
+    }
+
+    /**
+     * Returns the principal component.
+     *
+     * @return the principal component
+     */
+    public UserPrincipal principal() {
+        return who;
+    }
+
+    /**
+     * Returns a copy of the permissions component.
+     *
+     * <p> The returned set is a modifiable copy of the permissions.
+     *
+     * @return the permissions component
+     */
+    public Set<AclEntryPermission> permissions() {
+        return new HashSet<AclEntryPermission>(perms);
+    }
+
+    /**
+     * Returns a copy of the flags component.
+     *
+     * <p> The returned set is a modifiable copy of the flags.
+     *
+     * @return the flags component
+     */
+    public Set<AclEntryFlag> flags() {
+        return new HashSet<AclEntryFlag>(flags);
+    }
+
+    /**
+     * Compares the specified object with this ACL entry for equality.
+     *
+     * <p> If the given object is not an {@code AclEntry} then this method
+     * immediately returns {@code false}.
+     *
+     * <p> For two ACL entries to be considered equals requires that they are
+     * both the same type, their who components are equal, their permissions
+     * components are equal, and their flags components are equal.
+     *
+     * <p> This method satisfies the general contract of the {@link
+     * java.lang.Object#equals(Object) Object.equals} method. </p>
+     *
+     * @param   ob   the object to which this object is to be compared
+     *
+     * @return  {@code true} if, and only if, the given object is an AclEntry that
+     *          is identical to this AclEntry
+     */
+    @Override
+    public boolean equals(Object ob) {
+        if (ob == this)
+            return true;
+        if (ob == null || !(ob instanceof AclEntry))
+            return false;
+        AclEntry other = (AclEntry)ob;
+        if (this.type != other.type)
+            return false;
+        if (!this.who.equals(other.who))
+            return false;
+        if (!this.perms.equals(other.perms))
+            return false;
+        if (!this.flags.equals(other.flags))
+            return false;
+        return true;
+    }
+
+    private static int hash(int h, Object o) {
+        return h * 127 + o.hashCode();
+    }
+
+    /**
+     * Returns the hash-code value for this ACL entry.
+     *
+     * <p> This method satisfies the general contract of the {@link
+     * Object#hashCode} method.
+     */
+    @Override
+    public int hashCode() {
+        // return cached hash if available
+        if (hash != 0)
+            return hash;
+        int h = type.hashCode();
+        h = hash(h, who);
+        h = hash(h, perms);
+        h = hash(h, flags);
+        hash = h;
+        return hash;
+    }
+
+    /**
+     * Returns the string representation of this ACL entry.
+     *
+     * @return  the string representation of this entry
+     */
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        // who
+        sb.append(who.getName());
+        sb.append(':');
+
+        // permissions
+        for (AclEntryPermission perm: perms) {
+            sb.append(perm.name());
+            sb.append('/');
+        }
+        sb.setLength(sb.length()-1); // drop final slash
+        sb.append(':');
+
+        // flags
+        if (!flags.isEmpty()) {
+            for (AclEntryFlag flag: flags) {
+                sb.append(flag.name());
+                sb.append('/');
+            }
+            sb.setLength(sb.length()-1);  // drop final slash
+            sb.append(':');
+        }
+
+        // type
+        sb.append(type.name());
+        return sb.toString();
+    }
+}
diff --git a/java/nio/file/attribute/AclEntryFlag.java b/java/nio/file/attribute/AclEntryFlag.java
new file mode 100644
index 0000000..6cb91f2
--- /dev/null
+++ b/java/nio/file/attribute/AclEntryFlag.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file.attribute;
+
+/**
+ * Defines the flags for used by the flags component of an ACL {@link AclEntry
+ * entry}.
+ *
+ * <p> In this release, this class does not define flags related to {@link
+ * AclEntryType#AUDIT} and {@link AclEntryType#ALARM} entry types.
+ *
+ * @since 1.7
+ */
+
+public enum AclEntryFlag {
+
+    /**
+     * Can be placed on a directory and indicates that the ACL entry should be
+     * added to each new non-directory file created.
+     */
+    FILE_INHERIT,
+
+    /**
+     * Can be placed on a directory and indicates that the ACL entry should be
+     * added to each new directory created.
+     */
+    DIRECTORY_INHERIT,
+
+    /**
+     * Can be placed on a directory to indicate that the ACL entry should not
+     * be placed on the newly created directory which is inheritable by
+     * subdirectories of the created directory.
+     */
+    NO_PROPAGATE_INHERIT,
+
+    /**
+     * Can be placed on a directory but does not apply to the directory,
+     * only to newly created files/directories as specified by the
+     * {@link #FILE_INHERIT} and {@link #DIRECTORY_INHERIT} flags.
+     */
+    INHERIT_ONLY;
+}
diff --git a/java/nio/file/attribute/AclEntryPermission.java b/java/nio/file/attribute/AclEntryPermission.java
new file mode 100644
index 0000000..492ab77
--- /dev/null
+++ b/java/nio/file/attribute/AclEntryPermission.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file.attribute;
+
+/**
+ * Defines the permissions for use with the permissions component of an ACL
+ * {@link AclEntry entry}.
+ *
+ * @since 1.7
+ */
+
+public enum AclEntryPermission {
+
+    /**
+     * Permission to read the data of the file.
+     */
+    READ_DATA,
+
+    /**
+     * Permission to modify the file's data.
+     */
+    WRITE_DATA,
+
+    /**
+     * Permission to append data to a file.
+     */
+    APPEND_DATA,
+
+    /**
+     * Permission to read the named attributes of a file.
+     *
+     * <p> <a href="http://www.ietf.org/rfc/rfc3530.txt">RFC&nbsp;3530: Network
+     * File System (NFS) version 4 Protocol</a> defines <em>named attributes</em>
+     * as opaque files associated with a file in the file system.
+     */
+    READ_NAMED_ATTRS,
+
+    /**
+     * Permission to write the named attributes of a file.
+     *
+     * <p> <a href="http://www.ietf.org/rfc/rfc3530.txt">RFC&nbsp;3530: Network
+     * File System (NFS) version 4 Protocol</a> defines <em>named attributes</em>
+     * as opaque files associated with a file in the file system.
+     */
+    WRITE_NAMED_ATTRS,
+
+    /**
+     * Permission to execute a file.
+     */
+    EXECUTE,
+
+    /**
+     * Permission to delete a file or directory within a directory.
+     */
+    DELETE_CHILD,
+
+    /**
+     * The ability to read (non-acl) file attributes.
+     */
+    READ_ATTRIBUTES,
+
+    /**
+     * The ability to write (non-acl) file attributes.
+     */
+    WRITE_ATTRIBUTES,
+
+    /**
+     * Permission to delete the file.
+     */
+    DELETE,
+
+    /**
+     * Permission to read the ACL attribute.
+     */
+    READ_ACL,
+
+    /**
+     * Permission to write the ACL attribute.
+     */
+    WRITE_ACL,
+
+    /**
+     * Permission to change the owner.
+     */
+    WRITE_OWNER,
+
+    /**
+     * Permission to access file locally at the server with synchronous reads
+     * and writes.
+     */
+    SYNCHRONIZE;
+
+    /**
+     * Permission to list the entries of a directory (equal to {@link #READ_DATA})
+     */
+    public static final AclEntryPermission LIST_DIRECTORY = READ_DATA;
+
+    /**
+     * Permission to add a new file to a directory (equal to {@link #WRITE_DATA})
+     */
+    public static final AclEntryPermission ADD_FILE = WRITE_DATA;
+
+    /**
+     * Permission to create a subdirectory to a directory (equal to {@link #APPEND_DATA})
+     */
+    public static final AclEntryPermission ADD_SUBDIRECTORY = APPEND_DATA;
+}
diff --git a/java/nio/file/attribute/AclEntryType.java b/java/nio/file/attribute/AclEntryType.java
new file mode 100644
index 0000000..9773b3f
--- /dev/null
+++ b/java/nio/file/attribute/AclEntryType.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file.attribute;
+
+/**
+ * A typesafe enumeration of the access control entry types.
+ *
+ * @since 1.7
+ */
+
+public enum AclEntryType {
+    /**
+     * Explicitly grants access to a file or directory.
+     */
+    ALLOW,
+
+    /**
+     * Explicitly denies access to a file or directory.
+     */
+    DENY,
+
+    /**
+     * Log, in a system dependent way, the access specified in the
+     * permissions component of the ACL entry.
+     */
+    AUDIT,
+
+    /**
+     * Generate an alarm, in a system dependent way, the access specified in the
+     * permissions component of the ACL entry.
+     */
+    ALARM
+}
diff --git a/java/nio/file/attribute/AclFileAttributeView.java b/java/nio/file/attribute/AclFileAttributeView.java
new file mode 100644
index 0000000..129d0ee
--- /dev/null
+++ b/java/nio/file/attribute/AclFileAttributeView.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2007, 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.nio.file.attribute;
+
+import java.nio.file.*;
+import java.util.List;
+import java.io.IOException;
+
+/**
+ * A file attribute view that supports reading or updating a file's Access
+ * Control Lists (ACL) or file owner attributes.
+ *
+ * <p> ACLs are used to specify access rights to file system objects. An ACL is
+ * an ordered list of {@link AclEntry access-control-entries}, each specifying a
+ * {@link UserPrincipal} and the level of access for that user principal. This
+ * file attribute view defines the {@link #getAcl() getAcl}, and {@link
+ * #setAcl(List) setAcl} methods to read and write ACLs based on the ACL
+ * model specified in <a href="http://www.ietf.org/rfc/rfc3530.txt"><i>RFC&nbsp;3530:
+ * Network File System (NFS) version 4 Protocol</i></a>. This file attribute view
+ * is intended for file system implementations that support the NFSv4 ACL model
+ * or have a <em>well-defined</em> mapping between the NFSv4 ACL model and the ACL
+ * model used by the file system. The details of such mapping are implementation
+ * dependent and are therefore unspecified.
+ *
+ * <p> This class also extends {@code FileOwnerAttributeView} so as to define
+ * methods to get and set the file owner.
+ *
+ * <p> When a file system provides access to a set of {@link FileStore
+ * file-systems} that are not homogeneous then only some of the file systems may
+ * support ACLs. The {@link FileStore#supportsFileAttributeView
+ * supportsFileAttributeView} method can be used to test if a file system
+ * supports ACLs.
+ *
+ * <h2>Interoperability</h2>
+ *
+ * RFC&nbsp;3530 allows for special user identities to be used on platforms that
+ * support the POSIX defined access permissions. The special user identities
+ * are "{@code OWNER@}", "{@code GROUP@}", and "{@code EVERYONE@}". When both
+ * the {@code AclFileAttributeView} and the {@link PosixFileAttributeView}
+ * are supported then these special user identities may be included in ACL {@link
+ * AclEntry entries} that are read or written. The file system's {@link
+ * UserPrincipalLookupService} may be used to obtain a {@link UserPrincipal}
+ * to represent these special identities by invoking the {@link
+ * UserPrincipalLookupService#lookupPrincipalByName lookupPrincipalByName}
+ * method.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we wish to add an entry to an existing ACL to grant "joe" access:
+ * <pre>
+ *     // lookup "joe"
+ *     UserPrincipal joe = file.getFileSystem().getUserPrincipalLookupService()
+ *         .lookupPrincipalByName("joe");
+ *
+ *     // get view
+ *     AclFileAttributeView view = Files.getFileAttributeView(file, AclFileAttributeView.class);
+ *
+ *     // create ACE to give "joe" read access
+ *     AclEntry entry = AclEntry.newBuilder()
+ *         .setType(AclEntryType.ALLOW)
+ *         .setPrincipal(joe)
+ *         .setPermissions(AclEntryPermission.READ_DATA, AclEntryPermission.READ_ATTRIBUTES)
+ *         .build();
+ *
+ *     // read ACL, insert ACE, re-write ACL
+ *     List&lt;AclEntry&gt; acl = view.getAcl();
+ *     acl.add(0, entry);   // insert before any DENY entries
+ *     view.setAcl(acl);
+ * </pre>
+ *
+ * <h2> Dynamic Access </h2>
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view are as follows:
+ * <blockquote>
+ * <table border="1" cellpadding="8" summary="Supported attributes">
+ *   <tr>
+ *     <th> Name </th>
+ *     <th> Type </th>
+ *   </tr>
+ *   <tr>
+ *     <td> "acl" </td>
+ *     <td> {@link List}&lt;{@link AclEntry}&gt; </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "owner" </td>
+ *     <td> {@link UserPrincipal} </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link Files#getAttribute getAttribute} method may be used to read
+ * the ACL or owner attributes as if by invoking the {@link #getAcl getAcl} or
+ * {@link #getOwner getOwner} methods.
+ *
+ * <p> The {@link Files#setAttribute setAttribute} method may be used to
+ * update the ACL or owner attributes as if by invoking the {@link #setAcl setAcl}
+ * or {@link #setOwner setOwner} methods.
+ *
+ * <h2> Setting the ACL when creating a file </h2>
+ *
+ * <p> Implementations supporting this attribute view may also support setting
+ * the initial ACL when creating a file or directory. The initial ACL
+ * may be provided to methods such as {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} as an {@link FileAttribute} with {@link
+ * FileAttribute#name name} {@code "acl:acl"} and a {@link FileAttribute#value
+ * value} that is the list of {@code AclEntry} objects.
+ *
+ * <p> Where an implementation supports an ACL model that differs from the NFSv4
+ * defined ACL model then setting the initial ACL when creating the file must
+ * translate the ACL to the model supported by the file system. Methods that
+ * create a file should reject (by throwing {@link IOException IOException})
+ * any attempt to create a file that would be less secure as a result of the
+ * translation.
+ *
+ * @since 1.7
+ */
+
+public interface AclFileAttributeView
+    extends FileOwnerAttributeView
+{
+    /**
+     * Returns the name of the attribute view. Attribute views of this type
+     * have the name {@code "acl"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * Reads the access control list.
+     *
+     * <p> When the file system uses an ACL model that differs from the NFSv4
+     * defined ACL model, then this method returns an ACL that is the translation
+     * of the ACL to the NFSv4 ACL model.
+     *
+     * <p> The returned list is modifiable so as to facilitate changes to the
+     * existing ACL. The {@link #setAcl setAcl} method is used to update
+     * the file's ACL attribute.
+     *
+     * @return  an ordered list of {@link AclEntry entries} representing the
+     *          ACL
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     */
+    List<AclEntry> getAcl() throws IOException;
+
+    /**
+     * Updates (replace) the access control list.
+     *
+     * <p> Where the file system supports Access Control Lists, and it uses an
+     * ACL model that differs from the NFSv4 defined ACL model, then this method
+     * must translate the ACL to the model supported by the file system. This
+     * method should reject (by throwing {@link IOException IOException}) any
+     * attempt to write an ACL that would appear to make the file more secure
+     * than would be the case if the ACL were updated. Where an implementation
+     * does not support a mapping of {@link AclEntryType#AUDIT} or {@link
+     * AclEntryType#ALARM} entries, then this method ignores these entries when
+     * writing the ACL.
+     *
+     * <p> If an ACL entry contains a {@link AclEntry#principal user-principal}
+     * that is not associated with the same provider as this attribute view then
+     * {@link ProviderMismatchException} is thrown. Additional validation, if
+     * any, is implementation dependent.
+     *
+     * <p> If the file system supports other security related file attributes
+     * (such as a file {@link PosixFileAttributes#permissions
+     * access-permissions} for example), the updating the access control list
+     * may also cause these security related attributes to be updated.
+     *
+     * @param   acl
+     *          the new access control list
+     *
+     * @throws  IOException
+     *          if an I/O error occurs or the ACL is invalid
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     */
+    void setAcl(List<AclEntry> acl) throws IOException;
+}
diff --git a/java/nio/file/attribute/AttributeView.java b/java/nio/file/attribute/AttributeView.java
new file mode 100644
index 0000000..569076c
--- /dev/null
+++ b/java/nio/file/attribute/AttributeView.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 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.nio.file.attribute;
+
+/**
+ * An object that provides a read-only or updatable <em>view</em> of non-opaque
+ * values associated with an object in a filesystem. This interface is extended
+ * or implemented by specific attribute views that define the attributes
+ * supported by the view. A specific attribute view will typically define
+ * type-safe methods to read or update the attributes that it supports.
+ *
+ * @since 1.7
+ */
+
+public interface AttributeView {
+    /**
+     * Returns the name of the attribute view.
+     *
+     * @return the name of the attribute view
+     */
+    String name();
+}
diff --git a/java/nio/file/attribute/BasicFileAttributeView.java b/java/nio/file/attribute/BasicFileAttributeView.java
new file mode 100644
index 0000000..bfa3fdc
--- /dev/null
+++ b/java/nio/file/attribute/BasicFileAttributeView.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2007, 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.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of a <em>basic set</em> of file
+ * attributes common to many file systems. The basic set of file attributes
+ * consist of <em>mandatory</em> and <em>optional</em> file attributes as
+ * defined by the {@link BasicFileAttributes} interface.
+
+ * <p> The file attributes are retrieved from the file system as a <em>bulk
+ * operation</em> by invoking the {@link #readAttributes() readAttributes} method.
+ * This class also defines the {@link #setTimes setTimes} method to update the
+ * file's time attributes.
+ *
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view have the following names and types:
+ * <blockquote>
+ *  <table border="1" cellpadding="8" summary="Supported attributes">
+ *   <tr>
+ *     <th> Name </th>
+ *     <th> Type </th>
+ *   </tr>
+ *  <tr>
+ *     <td> "lastModifiedTime" </td>
+ *     <td> {@link FileTime} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "lastAccessTime" </td>
+ *     <td> {@link FileTime} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "creationTime" </td>
+ *     <td> {@link FileTime} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "size" </td>
+ *     <td> {@link Long} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "isRegularFile" </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "isDirectory" </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "isSymbolicLink" </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "isOther" </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "fileKey" </td>
+ *     <td> {@link Object} </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} method may be
+ * used to read any of these attributes as if by invoking the {@link
+ * #readAttributes() readAttributes()} method.
+ *
+ * <p> The {@link java.nio.file.Files#setAttribute setAttribute} method may be
+ * used to update the file's last modified time, last access time or create time
+ * attributes as if by invoking the {@link #setTimes setTimes} method.
+ *
+ * @since 1.7
+ */
+
+public interface BasicFileAttributeView
+    extends FileAttributeView
+{
+    /**
+     * Returns the name of the attribute view. Attribute views of this type
+     * have the name {@code "basic"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * Reads the basic file attributes as a bulk operation.
+     *
+     * <p> It is implementation specific if all file attributes are read as an
+     * atomic operation with respect to other file system operations.
+     *
+     * @return  the file attributes
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file
+     */
+    BasicFileAttributes readAttributes() throws IOException;
+
+    /**
+     * Updates any or all of the file's last modified time, last access time,
+     * and create time attributes.
+     *
+     * <p> This method updates the file's timestamp attributes. The values are
+     * converted to the epoch and precision supported by the file system.
+     * Converting from finer to coarser granularities result in precision loss.
+     * The behavior of this method when attempting to set a timestamp that is
+     * not supported or to a value that is outside the range supported by the
+     * underlying file store is not defined. It may or not fail by throwing an
+     * {@code IOException}.
+     *
+     * <p> If any of the {@code lastModifiedTime}, {@code lastAccessTime},
+     * or {@code createTime} parameters has the value {@code null} then the
+     * corresponding timestamp is not changed. An implementation may require to
+     * read the existing values of the file attributes when only some, but not
+     * all, of the timestamp attributes are updated. Consequently, this method
+     * may not be an atomic operation with respect to other file system
+     * operations. Reading and re-writing existing values may also result in
+     * precision loss. If all of the {@code lastModifiedTime}, {@code
+     * lastAccessTime} and {@code createTime} parameters are {@code null} then
+     * this method has no effect.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to change a file's last access time.
+     * <pre>
+     *    Path path = ...
+     *    FileTime time = ...
+     *    Files.getFileAttributeView(path, BasicFileAttributeView.class).setTimes(null, time, null);
+     * </pre>
+     *
+     * @param   lastModifiedTime
+     *          the new last modified time, or {@code null} to not change the
+     *          value
+     * @param   lastAccessTime
+     *          the last access time, or {@code null} to not change the value
+     * @param   createTime
+     *          the file's create time, or {@code null} to not change the value
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, its  {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file
+     *
+     * @see java.nio.file.Files#setLastModifiedTime
+     */
+    void setTimes(FileTime lastModifiedTime,
+                  FileTime lastAccessTime,
+                  FileTime createTime) throws IOException;
+}
diff --git a/java/nio/file/attribute/BasicFileAttributes.java b/java/nio/file/attribute/BasicFileAttributes.java
new file mode 100644
index 0000000..1aeb0d7
--- /dev/null
+++ b/java/nio/file/attribute/BasicFileAttributes.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2007, 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.nio.file.attribute;
+
+/**
+ * Basic attributes associated with a file in a file system.
+ *
+ * <p> Basic file attributes are attributes that are common to many file systems
+ * and consist of mandatory and optional file attributes as defined by this
+ * interface.
+ *
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ *    Path file = ...
+ *    BasicFileAttributes attrs = Files.readAttributes(file, BasicFileAttributes.class);
+ * </pre>
+ *
+ * @since 1.7
+ *
+ * @see BasicFileAttributeView
+ */
+
+public interface BasicFileAttributes {
+
+    /**
+     * Returns the time of last modification.
+     *
+     * <p> If the file system implementation does not support a time stamp
+     * to indicate the time of last modification then this method returns an
+     * implementation specific default value, typically a {@code FileTime}
+     * representing the epoch (1970-01-01T00:00:00Z).
+     *
+     * @return  a {@code FileTime} representing the time the file was last
+     *          modified
+     */
+    FileTime lastModifiedTime();
+
+    /**
+     * Returns the time of last access.
+     *
+     * <p> If the file system implementation does not support a time stamp
+     * to indicate the time of last access then this method returns
+     * an implementation specific default value, typically the {@link
+     * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+     * representing the epoch (1970-01-01T00:00:00Z).
+     *
+     * @return  a {@code FileTime} representing the time of last access
+     */
+    FileTime lastAccessTime();
+
+    /**
+     * Returns the creation time. The creation time is the time that the file
+     * was created.
+     *
+     * <p> If the file system implementation does not support a time stamp
+     * to indicate the time when the file was created then this method returns
+     * an implementation specific default value, typically the {@link
+     * #lastModifiedTime() last-modified-time} or a {@code FileTime}
+     * representing the epoch (1970-01-01T00:00:00Z).
+     *
+     * @return   a {@code FileTime} representing the time the file was created
+     */
+    FileTime creationTime();
+
+    /**
+     * Tells whether the file is a regular file with opaque content.
+     *
+     * @return {@code true} if the file is a regular file with opaque content
+     */
+    boolean isRegularFile();
+
+    /**
+     * Tells whether the file is a directory.
+     *
+     * @return {@code true} if the file is a directory
+     */
+    boolean isDirectory();
+
+    /**
+     * Tells whether the file is a symbolic link.
+     *
+     * @return {@code true} if the file is a symbolic link
+     */
+    boolean isSymbolicLink();
+
+    /**
+     * Tells whether the file is something other than a regular file, directory,
+     * or symbolic link.
+     *
+     * @return {@code true} if the file something other than a regular file,
+     *         directory or symbolic link
+     */
+    boolean isOther();
+
+    /**
+     * Returns the size of the file (in bytes). The size may differ from the
+     * actual size on the file system due to compression, support for sparse
+     * files, or other reasons. The size of files that are not {@link
+     * #isRegularFile regular} files is implementation specific and
+     * therefore unspecified.
+     *
+     * @return  the file size, in bytes
+     */
+    long size();
+
+    /**
+     * Returns an object that uniquely identifies the given file, or {@code
+     * null} if a file key is not available. On some platforms or file systems
+     * it is possible to use an identifier, or a combination of identifiers to
+     * uniquely identify a file. Such identifiers are important for operations
+     * such as file tree traversal in file systems that support <a
+     * href="../package-summary.html#links">symbolic links</a> or file systems
+     * that allow a file to be an entry in more than one directory. On UNIX file
+     * systems, for example, the <em>device ID</em> and <em>inode</em> are
+     * commonly used for such purposes.
+     *
+     * <p> The file key returned by this method can only be guaranteed to be
+     * unique if the file system and files remain static. Whether a file system
+     * re-uses identifiers after a file is deleted is implementation dependent and
+     * therefore unspecified.
+     *
+     * <p> File keys returned by this method can be compared for equality and are
+     * suitable for use in collections. If the file system and files remain static,
+     * and two files are the {@link java.nio.file.Files#isSameFile same} with
+     * non-{@code null} file keys, then their file keys are equal.
+     *
+     * @return an object that uniquely identifies the given file, or {@code null}
+     *
+     * @see java.nio.file.Files#walkFileTree
+     */
+    Object fileKey();
+}
diff --git a/java/nio/file/attribute/DosFileAttributeView.java b/java/nio/file/attribute/DosFileAttributeView.java
new file mode 100644
index 0000000..c12d8a0
--- /dev/null
+++ b/java/nio/file/attribute/DosFileAttributeView.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2007, 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.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of the legacy "DOS" file attributes.
+ * These attributes are supported by file systems such as the File Allocation
+ * Table (FAT) format commonly used in <em>consumer devices</em>.
+ *
+ * <p> A {@code DosFileAttributeView} is a {@link BasicFileAttributeView} that
+ * additionally supports access to the set of DOS attribute flags that are used
+ * to indicate if the file is read-only, hidden, a system file, or archived.
+ *
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view are as defined by {@code
+ * BasicFileAttributeView}, and in addition, the following attributes are
+ * supported:
+ * <blockquote>
+ * <table border="1" cellpadding="8" summary="Supported attributes">
+ *   <tr>
+ *     <th> Name </th>
+ *     <th> Type </th>
+ *   </tr>
+ *   <tr>
+ *     <td> readonly </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> hidden </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> system </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ *   <tr>
+ *     <td> archive </td>
+ *     <td> {@link Boolean} </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} method may
+ * be used to read any of these attributes, or any of the attributes defined by
+ * {@link BasicFileAttributeView} as if by invoking the {@link #readAttributes
+ * readAttributes()} method.
+ *
+ * <p> The {@link java.nio.file.Files#setAttribute setAttribute} method may
+ * be used to update the file's last modified time, last access time or create
+ * time attributes as defined by {@link BasicFileAttributeView}. It may also be
+ * used to update the DOS attributes as if by invoking the {@link #setReadOnly
+ * setReadOnly}, {@link #setHidden setHidden}, {@link #setSystem setSystem}, and
+ * {@link #setArchive setArchive} methods respectively.
+ *
+ * @since 1.7
+ */
+
+public interface DosFileAttributeView
+    extends BasicFileAttributeView
+{
+    /**
+     * Returns the name of the attribute view. Attribute views of this type
+     * have the name {@code "dos"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * @throws  IOException                             {@inheritDoc}
+     * @throws  SecurityException                       {@inheritDoc}
+     */
+    @Override
+    DosFileAttributes readAttributes() throws IOException;
+
+    /**
+     * Updates the value of the read-only attribute.
+     *
+     * <p> It is implementation specific if the attribute can be updated as an
+     * atomic operation with respect to other file system operations. An
+     * implementation may, for example, require to read the existing value of
+     * the DOS attribute in order to update this attribute.
+     *
+     * @param   value
+     *          the new value of the attribute
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default, and a security manager is installed,
+     *          its  {@link SecurityManager#checkWrite(String) checkWrite} method
+     *          is invoked to check write access to the file
+     */
+    void setReadOnly(boolean value) throws IOException;
+
+    /**
+     * Updates the value of the hidden attribute.
+     *
+     * <p> It is implementation specific if the attribute can be updated as an
+     * atomic operation with respect to other file system operations. An
+     * implementation may, for example, require to read the existing value of
+     * the DOS attribute in order to update this attribute.
+     *
+     * @param   value
+     *          the new value of the attribute
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default, and a security manager is installed,
+     *          its  {@link SecurityManager#checkWrite(String) checkWrite} method
+     *          is invoked to check write access to the file
+     */
+    void setHidden(boolean value) throws IOException;
+
+    /**
+     * Updates the value of the system attribute.
+     *
+     * <p> It is implementation specific if the attribute can be updated as an
+     * atomic operation with respect to other file system operations. An
+     * implementation may, for example, require to read the existing value of
+     * the DOS attribute in order to update this attribute.
+     *
+     * @param   value
+     *          the new value of the attribute
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default, and a security manager is installed,
+     *          its  {@link SecurityManager#checkWrite(String) checkWrite} method
+     *          is invoked to check write access to the file
+     */
+    void setSystem(boolean value) throws IOException;
+
+    /**
+     * Updates the value of the archive attribute.
+     *
+     * <p> It is implementation specific if the attribute can be updated as an
+     * atomic operation with respect to other file system operations. An
+     * implementation may, for example, require to read the existing value of
+     * the DOS attribute in order to update this attribute.
+     *
+     * @param   value
+     *          the new value of the attribute
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default, and a security manager is installed,
+     *          its  {@link SecurityManager#checkWrite(String) checkWrite} method
+     *          is invoked to check write access to the file
+     */
+    void setArchive(boolean value) throws IOException;
+}
diff --git a/java/nio/file/attribute/DosFileAttributes.java b/java/nio/file/attribute/DosFileAttributes.java
new file mode 100644
index 0000000..e1fbca9
--- /dev/null
+++ b/java/nio/file/attribute/DosFileAttributes.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file.attribute;
+
+/**
+ * File attributes associated with a file in a file system that supports
+ * legacy "DOS" attributes.
+ *
+ * <p> <b>Usage Example:</b>
+ * <pre>
+ *    Path file = ...
+ *    DosFileAttributes attrs = Files.readAttributes(file, DosFileAttributes.class);
+ * </pre>
+ *
+ * @since 1.7
+ */
+
+public interface DosFileAttributes
+    extends BasicFileAttributes
+{
+    /**
+     * Returns the value of the read-only attribute.
+     *
+     * <p> This attribute is often used as a simple access control mechanism
+     * to prevent files from being deleted or updated. Whether the file system
+     * or platform does any enforcement to prevent <em>read-only</em> files
+     * from being updated is implementation specific.
+     *
+     * @return  the value of the read-only attribute
+     */
+    boolean isReadOnly();
+
+    /**
+     * Returns the value of the hidden attribute.
+     *
+     * <p> This attribute is often used to indicate if the file is visible to
+     * users.
+     *
+     * @return  the value of the hidden attribute
+     */
+    boolean isHidden();
+
+    /**
+     * Returns the value of the archive attribute.
+     *
+     * <p> This attribute is typically used by backup programs.
+     *
+     * @return  the value of the archive attribute
+     */
+    boolean isArchive();
+
+    /**
+     * Returns the value of the system attribute.
+     *
+     * <p> This attribute is often used to indicate that the file is a component
+     * of the operating system.
+     *
+     * @return  the value of the system attribute
+     */
+    boolean isSystem();
+}
diff --git a/java/nio/file/attribute/FileAttribute.java b/java/nio/file/attribute/FileAttribute.java
new file mode 100644
index 0000000..16181dd
--- /dev/null
+++ b/java/nio/file/attribute/FileAttribute.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, 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.nio.file.attribute;
+
+/**
+ * An object that encapsulates the value of a file attribute that can be set
+ * atomically when creating a new file or directory by invoking the {@link
+ * java.nio.file.Files#createFile createFile} or {@link
+ * java.nio.file.Files#createDirectory createDirectory} methods.
+ *
+ * @param <T> The type of the file attribute value
+ *
+ * @since 1.7
+ * @see PosixFilePermissions#asFileAttribute
+ */
+
+public interface FileAttribute<T> {
+    /**
+     * Returns the attribute name.
+     *
+     * @return The attribute name
+     */
+    String name();
+
+    /**
+     * Returns the attribute value.
+     *
+     * @return The attribute value
+     */
+    T value();
+}
diff --git a/java/nio/file/attribute/FileAttributeView.java b/java/nio/file/attribute/FileAttributeView.java
new file mode 100644
index 0000000..d82e402
--- /dev/null
+++ b/java/nio/file/attribute/FileAttributeView.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file.attribute;
+
+/**
+ * An attribute view that is a read-only or updatable view of non-opaque
+ * values associated with a file in a filesystem. This interface is extended or
+ * implemented by specific file attribute views that define methods to read
+ * and/or update the attributes of a file.
+ *
+ * @since 1.7
+ *
+ * @see java.nio.file.Files#getFileAttributeView(Path,Class,java.nio.file.LinkOption[])
+ */
+
+public interface FileAttributeView
+    extends AttributeView
+{
+}
diff --git a/java/nio/file/attribute/FileOwnerAttributeView.java b/java/nio/file/attribute/FileOwnerAttributeView.java
new file mode 100644
index 0000000..f18caaf
--- /dev/null
+++ b/java/nio/file/attribute/FileOwnerAttributeView.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * A file attribute view that supports reading or updating the owner of a file.
+ * This file attribute view is intended for file system implementations that
+ * support a file attribute that represents an identity that is the owner of
+ * the file. Often the owner of a file is the identity of the entity that
+ * created the file.
+ *
+ * <p> The {@link #getOwner getOwner} or {@link #setOwner setOwner} methods may
+ * be used to read or update the owner of the file.
+ *
+ * <p> The {@link java.nio.file.Files#getAttribute getAttribute} and
+ * {@link java.nio.file.Files#setAttribute setAttribute} methods may also be
+ * used to read or update the owner. In that case, the owner attribute is
+ * identified by the name {@code "owner"}, and the value of the attribute is
+ * a {@link UserPrincipal}.
+ *
+ * @since 1.7
+ */
+
+public interface FileOwnerAttributeView
+    extends FileAttributeView
+{
+    /**
+     * Returns the name of the attribute view. Attribute views of this type
+     * have the name {@code "owner"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * Read the file owner.
+     *
+     * <p> It it implementation specific if the file owner can be a {@link
+     * GroupPrincipal group}.
+     *
+     * @return  the file owner
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link
+     *          RuntimePermission}<tt>("accessUserInformation")</tt> or its
+     *          {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     */
+    UserPrincipal getOwner() throws IOException;
+
+    /**
+     * Updates the file owner.
+     *
+     * <p> It it implementation specific if the file owner can be a {@link
+     * GroupPrincipal group}. To ensure consistent and correct behavior
+     * across platforms it is recommended that this method should only be used
+     * to set the file owner to a user principal that is not a group.
+     *
+     * @param   owner
+     *          the new file owner
+     *
+     * @throws  IOException
+     *          if an I/O error occurs, or the {@code owner} parameter is a
+     *          group and this implementation does not support setting the owner
+     *          to a group
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link
+     *          RuntimePermission}<tt>("accessUserInformation")</tt> or its
+     *          {@link SecurityManager#checkWrite(String) checkWrite} method
+     *          denies write access to the file.
+     */
+    void setOwner(UserPrincipal owner) throws IOException;
+}
diff --git a/java/nio/file/attribute/FileStoreAttributeView.java b/java/nio/file/attribute/FileStoreAttributeView.java
new file mode 100644
index 0000000..0efb9b6
--- /dev/null
+++ b/java/nio/file/attribute/FileStoreAttributeView.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file.attribute;
+
+/**
+ * An attribute view that is a read-only or updatable view of the attributes of
+ * a {@link java.nio.file.FileStore}.
+ *
+ * @since 1.7
+ */
+
+public interface FileStoreAttributeView
+    extends AttributeView
+{
+}
diff --git a/java/nio/file/attribute/FileTime.java b/java/nio/file/attribute/FileTime.java
new file mode 100644
index 0000000..2f3399b
--- /dev/null
+++ b/java/nio/file/attribute/FileTime.java
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2009, 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.nio.file.attribute;
+
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Represents the value of a file's time stamp attribute. For example, it may
+ * represent the time that the file was last
+ * {@link BasicFileAttributes#lastModifiedTime() modified},
+ * {@link BasicFileAttributes#lastAccessTime() accessed},
+ * or {@link BasicFileAttributes#creationTime() created}.
+ *
+ * <p> Instances of this class are immutable.
+ *
+ * @since 1.7
+ * @see java.nio.file.Files#setLastModifiedTime
+ * @see java.nio.file.Files#getLastModifiedTime
+ */
+
+public final class FileTime
+    implements Comparable<FileTime>
+{
+    /**
+     * The unit of granularity to interpret the value. Null if
+     * this {@code FileTime} is converted from an {@code Instant},
+     * the {@code value} and {@code unit} pair will not be used
+     * in this scenario.
+     */
+    private final TimeUnit unit;
+
+    /**
+     * The value since the epoch; can be negative.
+     */
+    private final long value;
+
+    /**
+     * The value as Instant (created lazily, if not from an instant)
+     */
+    private Instant instant;
+
+    /**
+     * The value return by toString (created lazily)
+     */
+    private String valueAsString;
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    private FileTime(long value, TimeUnit unit, Instant instant) {
+        this.value = value;
+        this.unit = unit;
+        this.instant = instant;
+    }
+
+    /**
+     * Returns a {@code FileTime} representing a value at the given unit of
+     * granularity.
+     *
+     * @param   value
+     *          the value since the epoch (1970-01-01T00:00:00Z); can be
+     *          negative
+     * @param   unit
+     *          the unit of granularity to interpret the value
+     *
+     * @return  a {@code FileTime} representing the given value
+     */
+    public static FileTime from(long value, TimeUnit unit) {
+        Objects.requireNonNull(unit, "unit");
+        return new FileTime(value, unit, null);
+    }
+
+    /**
+     * Returns a {@code FileTime} representing the given value in milliseconds.
+     *
+     * @param   value
+     *          the value, in milliseconds, since the epoch
+     *          (1970-01-01T00:00:00Z); can be negative
+     *
+     * @return  a {@code FileTime} representing the given value
+     */
+    public static FileTime fromMillis(long value) {
+        return new FileTime(value, TimeUnit.MILLISECONDS, null);
+    }
+
+    /**
+     * Returns a {@code FileTime} representing the same point of time value
+     * on the time-line as the provided {@code Instant} object.
+     *
+     * @param   instant
+     *          the instant to convert
+     * @return  a {@code FileTime} representing the same point on the time-line
+     *          as the provided instant
+     * @since 1.8
+     */
+    public static FileTime from(Instant instant) {
+        Objects.requireNonNull(instant, "instant");
+        return new FileTime(0, null, instant);
+    }
+
+    /**
+     * Returns the value at the given unit of granularity.
+     *
+     * <p> Conversion from a coarser granularity that would numerically overflow
+     * saturate to {@code Long.MIN_VALUE} if negative or {@code Long.MAX_VALUE}
+     * if positive.
+     *
+     * @param   unit
+     *          the unit of granularity for the return value
+     *
+     * @return  value in the given unit of granularity, since the epoch
+     *          since the epoch (1970-01-01T00:00:00Z); can be negative
+     */
+    public long to(TimeUnit unit) {
+        Objects.requireNonNull(unit, "unit");
+        if (this.unit != null) {
+            return unit.convert(this.value, this.unit);
+        } else {
+            long secs = unit.convert(instant.getEpochSecond(), TimeUnit.SECONDS);
+            if (secs == Long.MIN_VALUE || secs == Long.MAX_VALUE) {
+                return secs;
+            }
+            long nanos = unit.convert(instant.getNano(), TimeUnit.NANOSECONDS);
+            long r = secs + nanos;
+            // Math.addExact() variant
+            if (((secs ^ r) & (nanos ^ r)) < 0) {
+                return (secs < 0) ? Long.MIN_VALUE : Long.MAX_VALUE;
+            }
+            return r;
+        }
+    }
+
+    /**
+     * Returns the value in milliseconds.
+     *
+     * <p> Conversion from a coarser granularity that would numerically overflow
+     * saturate to {@code Long.MIN_VALUE} if negative or {@code Long.MAX_VALUE}
+     * if positive.
+     *
+     * @return  the value in milliseconds, since the epoch (1970-01-01T00:00:00Z)
+     */
+    public long toMillis() {
+        if (unit != null) {
+            return unit.toMillis(value);
+        } else {
+            long secs = instant.getEpochSecond();
+            int  nanos = instant.getNano();
+            // Math.multiplyExact() variant
+            long r = secs * 1000;
+            long ax = Math.abs(secs);
+            if (((ax | 1000) >>> 31 != 0)) {
+                if ((r / 1000) != secs) {
+                    return (secs < 0) ? Long.MIN_VALUE : Long.MAX_VALUE;
+                }
+            }
+            return r + nanos / 1000_000;
+        }
+    }
+
+    /**
+     * Time unit constants for conversion.
+     */
+    private static final long HOURS_PER_DAY      = 24L;
+    private static final long MINUTES_PER_HOUR   = 60L;
+    private static final long SECONDS_PER_MINUTE = 60L;
+    private static final long SECONDS_PER_HOUR   = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
+    private static final long SECONDS_PER_DAY    = SECONDS_PER_HOUR * HOURS_PER_DAY;
+    private static final long MILLIS_PER_SECOND  = 1000L;
+    private static final long MICROS_PER_SECOND  = 1000_000L;
+    private static final long NANOS_PER_SECOND   = 1000_000_000L;
+    private static final int  NANOS_PER_MILLI    = 1000_000;
+    private static final int  NANOS_PER_MICRO    = 1000;
+    // The epoch second of Instant.MIN.
+    private static final long MIN_SECOND = -31557014167219200L;
+    // The epoch second of Instant.MAX.
+    private static final long MAX_SECOND = 31556889864403199L;
+
+    /*
+     * Scale d by m, checking for overflow.
+     */
+    private static long scale(long d, long m, long over) {
+        if (d >  over) return Long.MAX_VALUE;
+        if (d < -over) return Long.MIN_VALUE;
+        return d * m;
+    }
+
+    /**
+     * Converts this {@code FileTime} object to an {@code Instant}.
+     *
+     * <p> The conversion creates an {@code Instant} that represents the
+     * same point on the time-line as this {@code FileTime}.
+     *
+     * <p> {@code FileTime} can store points on the time-line further in the
+     * future and further in the past than {@code Instant}. Conversion
+     * from such further time points saturates to {@link Instant#MIN} if
+     * earlier than {@code Instant.MIN} or {@link Instant#MAX} if later
+     * than {@code Instant.MAX}.
+     *
+     * @return  an instant representing the same point on the time-line as
+     *          this {@code FileTime} object
+     * @since 1.8
+     */
+    public Instant toInstant() {
+        if (instant == null) {
+            long secs = 0L;
+            int nanos = 0;
+            switch (unit) {
+                case DAYS:
+                    secs = scale(value, SECONDS_PER_DAY,
+                                 Long.MAX_VALUE/SECONDS_PER_DAY);
+                    break;
+                case HOURS:
+                    secs = scale(value, SECONDS_PER_HOUR,
+                                 Long.MAX_VALUE/SECONDS_PER_HOUR);
+                    break;
+                case MINUTES:
+                    secs = scale(value, SECONDS_PER_MINUTE,
+                                 Long.MAX_VALUE/SECONDS_PER_MINUTE);
+                    break;
+                case SECONDS:
+                    secs = value;
+                    break;
+                case MILLISECONDS:
+                    secs = Math.floorDiv(value, MILLIS_PER_SECOND);
+                    nanos = (int)Math.floorMod(value, MILLIS_PER_SECOND)
+                            * NANOS_PER_MILLI;
+                    break;
+                case MICROSECONDS:
+                    secs = Math.floorDiv(value, MICROS_PER_SECOND);
+                    nanos = (int)Math.floorMod(value, MICROS_PER_SECOND)
+                            * NANOS_PER_MICRO;
+                    break;
+                case NANOSECONDS:
+                    secs = Math.floorDiv(value, NANOS_PER_SECOND);
+                    nanos = (int)Math.floorMod(value, NANOS_PER_SECOND);
+                    break;
+                default : throw new AssertionError("Unit not handled");
+            }
+            if (secs <= MIN_SECOND)
+                instant = Instant.MIN;
+            else if (secs >= MAX_SECOND)
+                instant = Instant.MAX;
+            else
+                instant = Instant.ofEpochSecond(secs, nanos);
+        }
+        return instant;
+    }
+
+    /**
+     * Tests this {@code FileTime} for equality with the given object.
+     *
+     * <p> The result is {@code true} if and only if the argument is not {@code
+     * null} and is a {@code FileTime} that represents the same time. This
+     * method satisfies the general contract of the {@code Object.equals} method.
+     *
+     * @param   obj
+     *          the object to compare with
+     *
+     * @return  {@code true} if, and only if, the given object is a {@code
+     *          FileTime} that represents the same time
+     */
+    @Override
+    public boolean equals(Object obj) {
+        return (obj instanceof FileTime) ? compareTo((FileTime)obj) == 0 : false;
+    }
+
+    /**
+     * Computes a hash code for this file time.
+     *
+     * <p> The hash code is based upon the value represented, and satisfies the
+     * general contract of the {@link Object#hashCode} method.
+     *
+     * @return  the hash-code value
+     */
+    @Override
+    public int hashCode() {
+        // hashcode of instant representation to satisfy contract with equals
+        return toInstant().hashCode();
+    }
+
+    private long toDays() {
+        if (unit != null) {
+            return unit.toDays(value);
+        } else {
+            return TimeUnit.SECONDS.toDays(toInstant().getEpochSecond());
+        }
+    }
+
+    private long toExcessNanos(long days) {
+        if (unit != null) {
+            return unit.toNanos(value - unit.convert(days, TimeUnit.DAYS));
+        } else {
+            return TimeUnit.SECONDS.toNanos(toInstant().getEpochSecond()
+                                            - TimeUnit.DAYS.toSeconds(days));
+        }
+    }
+
+    /**
+     * Compares the value of two {@code FileTime} objects for order.
+     *
+     * @param   other
+     *          the other {@code FileTime} to be compared
+     *
+     * @return  {@code 0} if this {@code FileTime} is equal to {@code other}, a
+     *          value less than 0 if this {@code FileTime} represents a time
+     *          that is before {@code other}, and a value greater than 0 if this
+     *          {@code FileTime} represents a time that is after {@code other}
+     */
+    @Override
+    public int compareTo(FileTime other) {
+        // same granularity
+        if (unit != null && unit == other.unit) {
+            return Long.compare(value, other.value);
+        } else {
+            // compare using instant representation when unit differs
+            long secs = toInstant().getEpochSecond();
+            long secsOther = other.toInstant().getEpochSecond();
+            int cmp = Long.compare(secs, secsOther);
+            if (cmp != 0) {
+                return cmp;
+            }
+            cmp = Long.compare(toInstant().getNano(), other.toInstant().getNano());
+            if (cmp != 0) {
+                return cmp;
+            }
+            if (secs != MAX_SECOND && secs != MIN_SECOND) {
+                return 0;
+            }
+            // if both this and other's Instant reps are MIN/MAX,
+            // use daysSinceEpoch and nanosOfDays, which will not
+            // saturate during calculation.
+            long days = toDays();
+            long daysOther = other.toDays();
+            if (days == daysOther) {
+                return Long.compare(toExcessNanos(days), other.toExcessNanos(daysOther));
+            }
+            return Long.compare(days, daysOther);
+        }
+    }
+
+    // days in a 400 year cycle = 146097
+    // days in a 10,000 year cycle = 146097 * 25
+    // seconds per day = 86400
+    private static final long DAYS_PER_10000_YEARS = 146097L * 25L;
+    private static final long SECONDS_PER_10000_YEARS = 146097L * 25L * 86400L;
+    private static final long SECONDS_0000_TO_1970 = ((146097L * 5L) - (30L * 365L + 7L)) * 86400L;
+
+    // append year/month/day/hour/minute/second/nano with width and 0 padding
+    private StringBuilder append(StringBuilder sb, int w, int d) {
+        while (w > 0) {
+            sb.append((char)(d/w + '0'));
+            d = d % w;
+            w /= 10;
+        }
+        return sb;
+    }
+
+    /**
+     * Returns the string representation of this {@code FileTime}. The string
+     * is returned in the <a
+     * href="http://www.w3.org/TR/NOTE-datetime">ISO&nbsp;8601</a> format:
+     * <pre>
+     *     YYYY-MM-DDThh:mm:ss[.s+]Z
+     * </pre>
+     * where "{@code [.s+]}" represents a dot followed by one of more digits
+     * for the decimal fraction of a second. It is only present when the decimal
+     * fraction of a second is not zero. For example, {@code
+     * FileTime.fromMillis(1234567890000L).toString()} yields {@code
+     * "2009-02-13T23:31:30Z"}, and {@code FileTime.fromMillis(1234567890123L).toString()}
+     * yields {@code "2009-02-13T23:31:30.123Z"}.
+     *
+     * <p> A {@code FileTime} is primarily intended to represent the value of a
+     * file's time stamp. Where used to represent <i>extreme values</i>, where
+     * the year is less than "{@code 0001}" or greater than "{@code 9999}" then
+     * this method deviates from ISO 8601 in the same manner as the
+     * <a href="http://www.w3.org/TR/xmlschema-2/#deviantformats">XML Schema
+     * language</a>. That is, the year may be expanded to more than four digits
+     * and may be negative-signed. If more than four digits then leading zeros
+     * are not present. The year before "{@code 0001}" is "{@code -0001}".
+     *
+     * @return  the string representation of this file time
+     */
+    @Override
+    public String toString() {
+        if (valueAsString == null) {
+            long secs = 0L;
+            int  nanos = 0;
+            if (instant == null && unit.compareTo(TimeUnit.SECONDS) >= 0) {
+                secs = unit.toSeconds(value);
+            } else {
+                secs = toInstant().getEpochSecond();
+                nanos = toInstant().getNano();
+            }
+            LocalDateTime ldt;
+            int year = 0;
+            if (secs >= -SECONDS_0000_TO_1970) {
+                // current era
+                long zeroSecs = secs - SECONDS_PER_10000_YEARS + SECONDS_0000_TO_1970;
+                long hi = Math.floorDiv(zeroSecs, SECONDS_PER_10000_YEARS) + 1;
+                long lo = Math.floorMod(zeroSecs, SECONDS_PER_10000_YEARS);
+                ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, nanos, ZoneOffset.UTC);
+                year = ldt.getYear() +  (int)hi * 10000;
+            } else {
+                // before current era
+                long zeroSecs = secs + SECONDS_0000_TO_1970;
+                long hi = zeroSecs / SECONDS_PER_10000_YEARS;
+                long lo = zeroSecs % SECONDS_PER_10000_YEARS;
+                ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, nanos, ZoneOffset.UTC);
+                year = ldt.getYear() + (int)hi * 10000;
+            }
+            if (year <= 0) {
+                year = year - 1;
+            }
+            int fraction = ldt.getNano();
+            StringBuilder sb = new StringBuilder(64);
+            sb.append(year < 0 ? "-" : "");
+            year = Math.abs(year);
+            if (year < 10000) {
+                append(sb, 1000, Math.abs(year));
+            } else {
+                sb.append(String.valueOf(year));
+            }
+            sb.append('-');
+            append(sb, 10, ldt.getMonthValue());
+            sb.append('-');
+            append(sb, 10, ldt.getDayOfMonth());
+            sb.append('T');
+            append(sb, 10, ldt.getHour());
+            sb.append(':');
+            append(sb, 10, ldt.getMinute());
+            sb.append(':');
+            append(sb, 10, ldt.getSecond());
+            if (fraction != 0) {
+                sb.append('.');
+                // adding leading zeros and stripping any trailing zeros
+                int w = 100_000_000;
+                while (fraction % 10 == 0) {
+                    fraction /= 10;
+                    w /= 10;
+                }
+                append(sb, w, fraction);
+            }
+            sb.append('Z');
+            valueAsString = sb.toString();
+        }
+        return valueAsString;
+    }
+}
diff --git a/java/nio/file/attribute/GroupPrincipal.java b/java/nio/file/attribute/GroupPrincipal.java
new file mode 100644
index 0000000..8c679c5
--- /dev/null
+++ b/java/nio/file/attribute/GroupPrincipal.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file.attribute;
+
+/**
+ * A {@code UserPrincipal} representing a <em>group identity</em>, used to
+ * determine access rights to objects in a file system. The exact definition of
+ * a group is implementation specific, but typically, it represents an identity
+ * created for administrative purposes so as to determine the access rights for
+ * the members of the group. Whether an entity can be a member of multiple
+ * groups, and whether groups can be nested, are implementation specified and
+ * therefore not specified.
+ *
+ * @since 1.7
+ *
+ * @see UserPrincipalLookupService#lookupPrincipalByGroupName
+ */
+
+public interface GroupPrincipal extends UserPrincipal { }
diff --git a/java/nio/file/attribute/PosixFileAttributeView.java b/java/nio/file/attribute/PosixFileAttributeView.java
new file mode 100644
index 0000000..25466f2
--- /dev/null
+++ b/java/nio/file/attribute/PosixFileAttributeView.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2007, 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.nio.file.attribute;
+
+import java.nio.file.*;
+import java.util.Set;
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of the file attributes commonly
+ * associated with files on file systems used by operating systems that implement
+ * the Portable Operating System Interface (POSIX) family of standards.
+ *
+ * <p> Operating systems that implement the <a href="http://www.opengroup.org">
+ * POSIX</a> family of standards commonly use file systems that have a
+ * file <em>owner</em>, <em>group-owner</em>, and related <em>access
+ * permissions</em>. This file attribute view provides read and write access
+ * to these attributes.
+ *
+ * <p> The {@link #readAttributes() readAttributes} method is used to read the
+ * file's attributes. The file {@link PosixFileAttributes#owner() owner} is
+ * represented by a {@link UserPrincipal} that is the identity of the file owner
+ * for the purposes of access control. The {@link PosixFileAttributes#group()
+ * group-owner}, represented by a {@link GroupPrincipal}, is the identity of the
+ * group owner, where a group is an identity created for administrative purposes
+ * so as to determine the access rights for the members of the group.
+ *
+ * <p> The {@link PosixFileAttributes#permissions() permissions} attribute is a
+ * set of access permissions. This file attribute view provides access to the nine
+ * permission defined by the {@link PosixFilePermission} class.
+ * These nine permission bits determine the <em>read</em>, <em>write</em>, and
+ * <em>execute</em> access for the file owner, group, and others (others
+ * meaning identities other than the owner and members of the group). Some
+ * operating systems and file systems may provide additional permission bits
+ * but access to these other bits is not defined by this class in this release.
+ *
+ * <p> <b>Usage Example:</b>
+ * Suppose we need to print out the owner and access permissions of a file:
+ * <pre>
+ *     Path file = ...
+ *     PosixFileAttributes attrs = Files.getFileAttributeView(file, PosixFileAttributeView.class)
+ *         .readAttributes();
+ *     System.out.format("%s %s%n",
+ *         attrs.owner().getName(),
+ *         PosixFilePermissions.toString(attrs.permissions()));
+ * </pre>
+ *
+ * <h2> Dynamic Access </h2>
+ * <p> Where dynamic access to file attributes is required, the attributes
+ * supported by this attribute view are as defined by {@link
+ * BasicFileAttributeView} and {@link FileOwnerAttributeView}, and in addition,
+ * the following attributes are supported:
+ * <blockquote>
+ * <table border="1" cellpadding="8" summary="Supported attributes">
+ *   <tr>
+ *     <th> Name </th>
+ *     <th> Type </th>
+ *   </tr>
+ *  <tr>
+ *     <td> "permissions" </td>
+ *     <td> {@link Set}&lt;{@link PosixFilePermission}&gt; </td>
+ *   </tr>
+ *   <tr>
+ *     <td> "group" </td>
+ *     <td> {@link GroupPrincipal} </td>
+ *   </tr>
+ * </table>
+ * </blockquote>
+ *
+ * <p> The {@link Files#getAttribute getAttribute} method may be used to read
+ * any of these attributes, or any of the attributes defined by {@link
+ * BasicFileAttributeView} as if by invoking the {@link #readAttributes
+ * readAttributes()} method.
+ *
+ * <p> The {@link Files#setAttribute setAttribute} method may be used to update
+ * the file's last modified time, last access time or create time attributes as
+ * defined by {@link BasicFileAttributeView}. It may also be used to update
+ * the permissions, owner, or group-owner as if by invoking the {@link
+ * #setPermissions setPermissions}, {@link #setOwner setOwner}, and {@link
+ * #setGroup setGroup} methods respectively.
+ *
+ * <h2> Setting Initial Permissions </h2>
+ * <p> Implementations supporting this attribute view may also support setting
+ * the initial permissions when creating a file or directory. The
+ * initial permissions are provided to the {@link Files#createFile createFile}
+ * or {@link Files#createDirectory createDirectory} methods as a {@link
+ * FileAttribute} with {@link FileAttribute#name name} {@code "posix:permissions"}
+ * and a {@link FileAttribute#value value} that is the set of permissions. The
+ * following example uses the {@link PosixFilePermissions#asFileAttribute
+ * asFileAttribute} method to construct a {@code FileAttribute} when creating a
+ * file:
+ *
+ * <pre>
+ *     Path path = ...
+ *     Set&lt;PosixFilePermission&gt; perms =
+ *         EnumSet.of(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE, GROUP_READ);
+ *     Files.createFile(path, PosixFilePermissions.asFileAttribute(perms));
+ * </pre>
+ *
+ * <p> When the access permissions are set at file creation time then the actual
+ * value of the permissions may differ that the value of the attribute object.
+ * The reasons for this are implementation specific. On UNIX systems, for
+ * example, a process has a <em>umask</em> that impacts the permission bits
+ * of newly created files. Where an implementation supports the setting of
+ * the access permissions, and the underlying file system supports access
+ * permissions, then it is required that the value of the actual access
+ * permissions will be equal or less than the value of the attribute
+ * provided to the {@link Files#createFile createFile} or {@link
+ * Files#createDirectory createDirectory} methods. In other words, the file may
+ * be more secure than requested.
+ *
+ * @since 1.7
+ */
+
+public interface PosixFileAttributeView
+    extends BasicFileAttributeView, FileOwnerAttributeView
+{
+    /**
+     * Returns the name of the attribute view. Attribute views of this type
+     * have the name {@code "posix"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * @throws  IOException                {@inheritDoc}
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     */
+    @Override
+    PosixFileAttributes readAttributes() throws IOException;
+
+    /**
+     * Updates the file permissions.
+     *
+     * @param   perms
+     *          the new set of permissions
+     *
+     * @throws  ClassCastException
+     *          if the sets contains elements that are not of type {@code
+     *          PosixFilePermission}
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     */
+    void setPermissions(Set<PosixFilePermission> perms) throws IOException;
+
+    /**
+     * Updates the file group-owner.
+     *
+     * @param   group
+     *          the new file group-owner
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it denies {@link RuntimePermission}<tt>("accessUserInformation")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     */
+    void setGroup(GroupPrincipal group) throws IOException;
+}
diff --git a/java/nio/file/attribute/PosixFileAttributes.java b/java/nio/file/attribute/PosixFileAttributes.java
new file mode 100644
index 0000000..182c422
--- /dev/null
+++ b/java/nio/file/attribute/PosixFileAttributes.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file.attribute;
+
+import java.util.Set;
+
+/**
+ * File attributes associated with files on file systems used by operating systems
+ * that implement the Portable Operating System Interface (POSIX) family of
+ * standards.
+ *
+ * <p> The POSIX attributes of a file are retrieved using a {@link
+ * PosixFileAttributeView} by invoking its {@link
+ * PosixFileAttributeView#readAttributes readAttributes} method.
+ *
+ * @since 1.7
+ */
+
+public interface PosixFileAttributes
+    extends BasicFileAttributes
+{
+    /**
+     * Returns the owner of the file.
+     *
+     * @return  the file owner
+     *
+     * @see PosixFileAttributeView#setOwner
+     */
+    UserPrincipal owner();
+
+    /**
+     * Returns the group owner of the file.
+     *
+     * @return  the file group owner
+     *
+     * @see PosixFileAttributeView#setGroup
+     */
+    GroupPrincipal group();
+
+    /**
+     * Returns the permissions of the file. The file permissions are returned
+     * as a set of {@link PosixFilePermission} elements. The returned set is a
+     * copy of the file permissions and is modifiable. This allows the result
+     * to be modified and passed to the {@link PosixFileAttributeView#setPermissions
+     * setPermissions} method to update the file's permissions.
+     *
+     * @return  the file permissions
+     *
+     * @see PosixFileAttributeView#setPermissions
+     */
+    Set<PosixFilePermission> permissions();
+}
diff --git a/java/nio/file/attribute/PosixFilePermission.java b/java/nio/file/attribute/PosixFilePermission.java
new file mode 100644
index 0000000..03e2209
--- /dev/null
+++ b/java/nio/file/attribute/PosixFilePermission.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file.attribute;
+
+/**
+ * Defines the bits for use with the {@link PosixFileAttributes#permissions()
+ * permissions} attribute.
+ *
+ * <p> The {@link PosixFilePermissions} class defines methods for manipulating
+ * set of permissions.
+ *
+ * @since 1.7
+ */
+
+public enum PosixFilePermission {
+
+    /**
+     * Read permission, owner.
+     */
+    OWNER_READ,
+
+    /**
+     * Write permission, owner.
+     */
+    OWNER_WRITE,
+
+    /**
+     * Execute/search permission, owner.
+     */
+    OWNER_EXECUTE,
+
+    /**
+     * Read permission, group.
+     */
+    GROUP_READ,
+
+    /**
+     * Write permission, group.
+     */
+    GROUP_WRITE,
+
+    /**
+     * Execute/search permission, group.
+     */
+    GROUP_EXECUTE,
+
+    /**
+     * Read permission, others.
+     */
+    OTHERS_READ,
+
+    /**
+     * Write permission, others.
+     */
+    OTHERS_WRITE,
+
+    /**
+     * Execute/search permission, others.
+     */
+    OTHERS_EXECUTE;
+}
diff --git a/java/nio/file/attribute/PosixFilePermissions.java b/java/nio/file/attribute/PosixFilePermissions.java
new file mode 100644
index 0000000..45a866a
--- /dev/null
+++ b/java/nio/file/attribute/PosixFilePermissions.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file.attribute;
+
+import static java.nio.file.attribute.PosixFilePermission.*;
+import java.util.*;
+
+/**
+ * This class consists exclusively of static methods that operate on sets of
+ * {@link PosixFilePermission} objects.
+ *
+ * @since 1.7
+ */
+
+public final class PosixFilePermissions {
+    private PosixFilePermissions() { }
+
+    // Write string representation of permission bits to {@code sb}.
+    private static void writeBits(StringBuilder sb, boolean r, boolean w, boolean x) {
+        if (r) {
+            sb.append('r');
+        } else {
+            sb.append('-');
+        }
+        if (w) {
+            sb.append('w');
+        } else {
+            sb.append('-');
+        }
+        if (x) {
+            sb.append('x');
+        } else {
+            sb.append('-');
+        }
+    }
+
+    /**
+     * Returns the {@code String} representation of a set of permissions. It
+     * is guaranteed that the returned {@code String} can be parsed by the
+     * {@link #fromString} method.
+     *
+     * <p> If the set contains {@code null} or elements that are not of type
+     * {@code PosixFilePermission} then these elements are ignored.
+     *
+     * @param   perms
+     *          the set of permissions
+     *
+     * @return  the string representation of the permission set
+     */
+    public static String toString(Set<PosixFilePermission> perms) {
+        StringBuilder sb = new StringBuilder(9);
+        writeBits(sb, perms.contains(OWNER_READ), perms.contains(OWNER_WRITE),
+          perms.contains(OWNER_EXECUTE));
+        writeBits(sb, perms.contains(GROUP_READ), perms.contains(GROUP_WRITE),
+          perms.contains(GROUP_EXECUTE));
+        writeBits(sb, perms.contains(OTHERS_READ), perms.contains(OTHERS_WRITE),
+          perms.contains(OTHERS_EXECUTE));
+        return sb.toString();
+    }
+
+    private static boolean isSet(char c, char setValue) {
+        if (c == setValue)
+            return true;
+        if (c == '-')
+            return false;
+        throw new IllegalArgumentException("Invalid mode");
+    }
+    private static boolean isR(char c) { return isSet(c, 'r'); }
+    private static boolean isW(char c) { return isSet(c, 'w'); }
+    private static boolean isX(char c) { return isSet(c, 'x'); }
+
+    /**
+     * Returns the set of permissions corresponding to a given {@code String}
+     * representation.
+     *
+     * <p> The {@code perms} parameter is a {@code String} representing the
+     * permissions. It has 9 characters that are interpreted as three sets of
+     * three. The first set refers to the owner's permissions; the next to the
+     * group permissions and the last to others. Within each set, the first
+     * character is {@code 'r'} to indicate permission to read, the second
+     * character is {@code 'w'} to indicate permission to write, and the third
+     * character is {@code 'x'} for execute permission. Where a permission is
+     * not set then the corresponding character is set to {@code '-'}.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we require the set of permissions that indicate the owner has read,
+     * write, and execute permissions, the group has read and execute permissions
+     * and others have none.
+     * <pre>
+     *   Set&lt;PosixFilePermission&gt; perms = PosixFilePermissions.fromString("rwxr-x---");
+     * </pre>
+     *
+     * @param   perms
+     *          string representing a set of permissions
+     *
+     * @return  the resulting set of permissions
+     *
+     * @throws  IllegalArgumentException
+     *          if the string cannot be converted to a set of permissions
+     *
+     * @see #toString(Set)
+     */
+    public static Set<PosixFilePermission> fromString(String perms) {
+        if (perms.length() != 9)
+            throw new IllegalArgumentException("Invalid mode");
+        Set<PosixFilePermission> result = EnumSet.noneOf(PosixFilePermission.class);
+        if (isR(perms.charAt(0))) result.add(OWNER_READ);
+        if (isW(perms.charAt(1))) result.add(OWNER_WRITE);
+        if (isX(perms.charAt(2))) result.add(OWNER_EXECUTE);
+        if (isR(perms.charAt(3))) result.add(GROUP_READ);
+        if (isW(perms.charAt(4))) result.add(GROUP_WRITE);
+        if (isX(perms.charAt(5))) result.add(GROUP_EXECUTE);
+        if (isR(perms.charAt(6))) result.add(OTHERS_READ);
+        if (isW(perms.charAt(7))) result.add(OTHERS_WRITE);
+        if (isX(perms.charAt(8))) result.add(OTHERS_EXECUTE);
+        return result;
+    }
+
+    /**
+     * Creates a {@link FileAttribute}, encapsulating a copy of the given file
+     * permissions, suitable for passing to the {@link java.nio.file.Files#createFile
+     * createFile} or {@link java.nio.file.Files#createDirectory createDirectory}
+     * methods.
+     *
+     * @param   perms
+     *          the set of permissions
+     *
+     * @return  an attribute encapsulating the given file permissions with
+     *          {@link FileAttribute#name name} {@code "posix:permissions"}
+     *
+     * @throws  ClassCastException
+     *          if the set contains elements that are not of type {@code
+     *          PosixFilePermission}
+     */
+    public static FileAttribute<Set<PosixFilePermission>>
+        asFileAttribute(Set<PosixFilePermission> perms)
+    {
+        // copy set and check for nulls (CCE will be thrown if an element is not
+        // a PosixFilePermission)
+        perms = new HashSet<PosixFilePermission>(perms);
+        for (PosixFilePermission p: perms) {
+            if (p == null)
+                throw new NullPointerException();
+        }
+        final Set<PosixFilePermission> value = perms;
+        return new FileAttribute<Set<PosixFilePermission>>() {
+            @Override
+            public String name() {
+                return "posix:permissions";
+            }
+            @Override
+            public Set<PosixFilePermission> value() {
+                return Collections.unmodifiableSet(value);
+            }
+        };
+    }
+}
diff --git a/java/nio/file/attribute/UserDefinedFileAttributeView.java b/java/nio/file/attribute/UserDefinedFileAttributeView.java
new file mode 100644
index 0000000..56e7135
--- /dev/null
+++ b/java/nio/file/attribute/UserDefinedFileAttributeView.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2007, 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.nio.file.attribute;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.io.IOException;
+
+/**
+ * A file attribute view that provides a view of a file's user-defined
+ * attributes, sometimes known as <em>extended attributes</em>. User-defined
+ * file attributes are used to store metadata with a file that is not meaningful
+ * to the file system. It is primarily intended for file system implementations
+ * that support such a capability directly but may be emulated. The details of
+ * such emulation are highly implementation specific and therefore not specified.
+ *
+ * <p> This {@code FileAttributeView} provides a view of a file's user-defined
+ * attributes as a set of name/value pairs, where the attribute name is
+ * represented by a {@code String}. An implementation may require to encode and
+ * decode from the platform or file system representation when accessing the
+ * attribute. The value has opaque content. This attribute view defines the
+ * {@link #read read} and {@link #write write} methods to read the value into
+ * or write from a {@link ByteBuffer}. This {@code FileAttributeView} is not
+ * intended for use where the size of an attribute value is larger than {@link
+ * Integer#MAX_VALUE}.
+ *
+ * <p> User-defined attributes may be used in some implementations to store
+ * security related attributes so consequently, in the case of the default
+ * provider at least, all methods that access user-defined attributes require the
+ * {@code RuntimePermission("accessUserDefinedAttributes")} permission when a
+ * security manager is installed.
+ *
+ * <p> The {@link java.nio.file.FileStore#supportsFileAttributeView
+ * supportsFileAttributeView} method may be used to test if a specific {@link
+ * java.nio.file.FileStore FileStore} supports the storage of user-defined
+ * attributes.
+ *
+ * <p> Where dynamic access to file attributes is required, the {@link
+ * java.nio.file.Files#getAttribute getAttribute} method may be used to read
+ * the attribute value. The attribute value is returned as a byte array (byte[]).
+ * The {@link java.nio.file.Files#setAttribute setAttribute} method may be used
+ * to write the value of a user-defined attribute from a buffer (as if by
+ * invoking the {@link #write write} method), or byte array (byte[]).
+ *
+ * @since 1.7
+ */
+
+public interface UserDefinedFileAttributeView
+    extends FileAttributeView
+{
+    /**
+     * Returns the name of this attribute view. Attribute views of this type
+     * have the name {@code "user"}.
+     */
+    @Override
+    String name();
+
+    /**
+     * Returns a list containing the names of the user-defined attributes.
+     *
+     * @return  An unmodifiable list containing the names of the file's
+     *          user-defined
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link
+     *          RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     */
+    List<String> list() throws IOException;
+
+    /**
+     * Returns the size of the value of a user-defined attribute.
+     *
+     * @param   name
+     *          The attribute name
+     *
+     * @return  The size of the attribute value, in bytes.
+     *
+     * @throws  ArithmeticException
+     *          If the size of the attribute is larger than {@link Integer#MAX_VALUE}
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link
+     *          RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     */
+    int size(String name) throws IOException;
+
+    /**
+     * Read the value of a user-defined attribute into a buffer.
+     *
+     * <p> This method reads the value of the attribute into the given buffer
+     * as a sequence of bytes, failing if the number of bytes remaining in
+     * the buffer is insufficient to read the complete attribute value. The
+     * number of bytes transferred into the buffer is {@code n}, where {@code n}
+     * is the size of the attribute value. The first byte in the sequence is at
+     * index {@code p} and the last byte is at index {@code p + n - 1}, where
+     * {@code p} is the buffer's position. Upon return the buffer's position
+     * will be equal to {@code p + n}; its limit will not have changed.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to read a file's MIME type that is stored as a user-defined
+     * attribute with the name "{@code user.mimetype}".
+     * <pre>
+     *    UserDefinedFileAttributeView view =
+     *        Files.getFileAttributeView(path, UserDefinedFileAttributeView.class);
+     *    String name = "user.mimetype";
+     *    ByteBuffer buf = ByteBuffer.allocate(view.size(name));
+     *    view.read(name, buf);
+     *    buf.flip();
+     *    String value = Charset.defaultCharset().decode(buf).toString();
+     * </pre>
+     *
+     * @param   name
+     *          The attribute name
+     * @param   dst
+     *          The destination buffer
+     *
+     * @return  The number of bytes read, possibly zero
+     *
+     * @throws  IllegalArgumentException
+     *          If the destination buffer is read-only
+     * @throws  IOException
+     *          If an I/O error occurs or there is insufficient space in the
+     *          destination buffer for the attribute value
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link
+     *          RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+     *          or its {@link SecurityManager#checkRead(String) checkRead} method
+     *          denies read access to the file.
+     *
+     * @see #size
+     */
+    int read(String name, ByteBuffer dst) throws IOException;
+
+    /**
+     * Writes the value of a user-defined attribute from a buffer.
+     *
+     * <p> This method writes the value of the attribute from a given buffer as
+     * a sequence of bytes. The size of the value to transfer is {@code r},
+     * where {@code r} is the number of bytes remaining in the buffer, that is
+     * {@code src.remaining()}. The sequence of bytes is transferred from the
+     * buffer starting at index {@code p}, where {@code p} is the buffer's
+     * position. Upon return, the buffer's position will be equal to {@code
+     * p + n}, where {@code n} is the number of bytes transferred; its limit
+     * will not have changed.
+     *
+     * <p> If an attribute of the given name already exists then its value is
+     * replaced. If the attribute does not exist then it is created. If it
+     * implementation specific if a test to check for the existence of the
+     * attribute and the creation of attribute are atomic with respect to other
+     * file system activities.
+     *
+     * <p> Where there is insufficient space to store the attribute, or the
+     * attribute name or value exceed an implementation specific maximum size
+     * then an {@code IOException} is thrown.
+     *
+     * <p> <b>Usage Example:</b>
+     * Suppose we want to write a file's MIME type as a user-defined attribute:
+     * <pre>
+     *    UserDefinedFileAttributeView view =
+     *        FIles.getFileAttributeView(path, UserDefinedFileAttributeView.class);
+     *    view.write("user.mimetype", Charset.defaultCharset().encode("text/html"));
+     * </pre>
+     *
+     * @param   name
+     *          The attribute name
+     * @param   src
+     *          The buffer containing the attribute value
+     *
+     * @return  The number of bytes written, possibly zero
+     *
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link
+     *          RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     */
+    int write(String name, ByteBuffer src) throws IOException;
+
+    /**
+     * Deletes a user-defined attribute.
+     *
+     * @param   name
+     *          The attribute name
+     *
+     * @throws  IOException
+     *          If an I/O error occurs or the attribute does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, and it denies {@link
+     *          RuntimePermission}<tt>("accessUserDefinedAttributes")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file.
+     */
+    void delete(String name) throws IOException;
+}
diff --git a/java/nio/file/attribute/UserPrincipal.java b/java/nio/file/attribute/UserPrincipal.java
new file mode 100644
index 0000000..01b26bb
--- /dev/null
+++ b/java/nio/file/attribute/UserPrincipal.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file.attribute;
+
+import java.security.Principal;
+
+/**
+ * A {@code Principal} representing an identity used to determine access rights
+ * to objects in a file system.
+ *
+ * <p> On many platforms and file systems an entity requires appropriate access
+ * rights or permissions in order to access objects in a file system. The
+ * access rights are generally performed by checking the identity of the entity.
+ * For example, on implementations that use Access Control Lists (ACLs) to
+ * enforce privilege separation then a file in the file system may have an
+ * associated ACL that determines the access rights of identities specified in
+ * the ACL.
+ *
+ * <p> A {@code UserPrincipal} object is an abstract representation of an
+ * identity. It has a {@link #getName() name} that is typically the username or
+ * account name that it represents. User principal objects may be obtained using
+ * a {@link UserPrincipalLookupService}, or returned by {@link
+ * FileAttributeView} implementations that provide access to identity related
+ * attributes. For example, the {@link AclFileAttributeView} and {@link
+ * PosixFileAttributeView} provide access to a file's {@link
+ * PosixFileAttributes#owner owner}.
+ *
+ * @since 1.7
+ */
+
+public interface UserPrincipal extends Principal { }
diff --git a/java/nio/file/attribute/UserPrincipalLookupService.java b/java/nio/file/attribute/UserPrincipalLookupService.java
new file mode 100644
index 0000000..c3f3bef
--- /dev/null
+++ b/java/nio/file/attribute/UserPrincipalLookupService.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * An object to lookup user and group principals by name. A {@link UserPrincipal}
+ * represents an identity that may be used to determine access rights to objects
+ * in a file system. A {@link GroupPrincipal} represents a <em>group identity</em>.
+ * A {@code UserPrincipalLookupService} defines methods to lookup identities by
+ * name or group name (which are typically user or account names). Whether names
+ * and group names are case sensitive or not depends on the implementation.
+ * The exact definition of a group is implementation specific but typically a
+ * group represents an identity created for administrative purposes so as to
+ * determine the access rights for the members of the group. In particular it is
+ * implementation specific if the <em>namespace</em> for names and groups is the
+ * same or is distinct. To ensure consistent and correct behavior across
+ * platforms it is recommended that this API be used as if the namespaces are
+ * distinct. In other words, the {@link #lookupPrincipalByName
+ * lookupPrincipalByName} should be used to lookup users, and {@link
+ * #lookupPrincipalByGroupName lookupPrincipalByGroupName} should be used to
+ * lookup groups.
+ *
+ * @since 1.7
+ *
+ * @see java.nio.file.FileSystem#getUserPrincipalLookupService
+ */
+
+public abstract class UserPrincipalLookupService {
+
+    /**
+     * Initializes a new instance of this class.
+     */
+    protected UserPrincipalLookupService() {
+    }
+
+    /**
+     * Lookup a user principal by name.
+     *
+     * @param   name
+     *          the string representation of the user principal to lookup
+     *
+     * @return  a user principal
+     *
+     * @throws  UserPrincipalNotFoundException
+     *          the principal does not exist
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it checks {@link RuntimePermission}<tt>("lookupUserInformation")</tt>
+     */
+    public abstract UserPrincipal lookupPrincipalByName(String name)
+        throws IOException;
+
+    /**
+     * Lookup a group principal by group name.
+     *
+     * <p> Where an implementation does not support any notion of group then
+     * this method always throws {@link UserPrincipalNotFoundException}. Where
+     * the namespace for user accounts and groups is the same, then this method
+     * is identical to invoking {@link #lookupPrincipalByName
+     * lookupPrincipalByName}.
+     *
+     * @param   group
+     *          the string representation of the group to lookup
+     *
+     * @return  a group principal
+     *
+     * @throws  UserPrincipalNotFoundException
+     *          the principal does not exist or is not a group
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, it checks {@link RuntimePermission}<tt>("lookupUserInformation")</tt>
+     */
+    public abstract GroupPrincipal lookupPrincipalByGroupName(String group)
+        throws IOException;
+}
diff --git a/java/nio/file/attribute/UserPrincipalNotFoundException.java b/java/nio/file/attribute/UserPrincipalNotFoundException.java
new file mode 100644
index 0000000..5cf0ab0
--- /dev/null
+++ b/java/nio/file/attribute/UserPrincipalNotFoundException.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2007, 2009, 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.nio.file.attribute;
+
+import java.io.IOException;
+
+/**
+ * Checked exception thrown when a lookup of {@link UserPrincipal} fails because
+ * the principal does not exist.
+ *
+ * @since 1.7
+ */
+
+public class UserPrincipalNotFoundException
+    extends IOException
+{
+    static final long serialVersionUID = -5369283889045833024L;
+
+    private final String name;
+
+    /**
+     * Constructs an instance of this class.
+     *
+     * @param   name
+     *          the principal name; may be {@code null}
+     */
+    public UserPrincipalNotFoundException(String name) {
+        super();
+        this.name = name;
+    }
+
+    /**
+     * Returns the user principal name if this exception was created with the
+     * user principal name that was not found, otherwise <tt>null</tt>.
+     *
+     * @return  the user principal name or {@code null}
+     */
+    public String getName() {
+        return name;
+    }
+}
diff --git a/java/nio/file/spi/FileSystemProvider.java b/java/nio/file/spi/FileSystemProvider.java
new file mode 100644
index 0000000..bed8416
--- /dev/null
+++ b/java/nio/file/spi/FileSystemProvider.java
@@ -0,0 +1,1103 @@
+/*
+ * Copyright (c) 2007, 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.nio.file.spi;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.*;
+import java.net.URI;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.ExecutorService;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Service-provider class for file systems. The methods defined by the {@link
+ * java.nio.file.Files} class will typically delegate to an instance of this
+ * class.
+ *
+ * <p> A file system provider is a concrete implementation of this class that
+ * implements the abstract methods defined by this class. A provider is
+ * identified by a {@code URI} {@link #getScheme() scheme}. The default provider
+ * is identified by the URI scheme "file". It creates the {@link FileSystem} that
+ * provides access to the file systems accessible to the Java virtual machine.
+ * The {@link FileSystems} class defines how file system providers are located
+ * and loaded. The default provider is typically a system-default provider but
+ * may be overridden if the system property {@code
+ * java.nio.file.spi.DefaultFileSystemProvider} is set. In that case, the
+ * provider has a one argument constructor whose formal parameter type is {@code
+ * FileSystemProvider}. All other providers have a zero argument constructor
+ * that initializes the provider.
+ *
+ * <p> A provider is a factory for one or more {@link FileSystem} instances. Each
+ * file system is identified by a {@code URI} where the URI's scheme matches
+ * the provider's {@link #getScheme scheme}. The default file system, for example,
+ * is identified by the URI {@code "file:///"}. A memory-based file system,
+ * for example, may be identified by a URI such as {@code "memory:///?name=logfs"}.
+ * The {@link #newFileSystem newFileSystem} method may be used to create a file
+ * system, and the {@link #getFileSystem getFileSystem} method may be used to
+ * obtain a reference to an existing file system created by the provider. Where
+ * a provider is the factory for a single file system then it is provider dependent
+ * if the file system is created when the provider is initialized, or later when
+ * the {@code newFileSystem} method is invoked. In the case of the default
+ * provider, the {@code FileSystem} is created when the provider is initialized.
+ *
+ * <p> All of the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @since 1.7
+ */
+
+public abstract class FileSystemProvider {
+    // lock using when loading providers
+    private static final Object lock = new Object();
+
+    // installed providers
+    private static volatile List<FileSystemProvider> installedProviders;
+
+    // used to avoid recursive loading of instaled providers
+    private static boolean loadingProviders  = false;
+
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null)
+            sm.checkPermission(new RuntimePermission("fileSystemProvider"));
+        return null;
+    }
+    private FileSystemProvider(Void ignore) { }
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * <p> During construction a provider may safely access files associated
+     * with the default provider but care needs to be taken to avoid circular
+     * loading of other installed providers. If circular loading of installed
+     * providers is detected then an unspecified error is thrown.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     *          {@link RuntimePermission}<tt>("fileSystemProvider")</tt>
+     */
+    protected FileSystemProvider() {
+        this(checkPermission());
+    }
+
+    // loads all installed providers
+    private static List<FileSystemProvider> loadInstalledProviders() {
+        List<FileSystemProvider> list = new ArrayList<FileSystemProvider>();
+
+        ServiceLoader<FileSystemProvider> sl = ServiceLoader
+            .load(FileSystemProvider.class, ClassLoader.getSystemClassLoader());
+
+        // ServiceConfigurationError may be throw here
+        for (FileSystemProvider provider: sl) {
+            String scheme = provider.getScheme();
+
+            // add to list if the provider is not "file" and isn't a duplicate
+            if (!scheme.equalsIgnoreCase("file")) {
+                boolean found = false;
+                for (FileSystemProvider p: list) {
+                    if (p.getScheme().equalsIgnoreCase(scheme)) {
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found) {
+                    list.add(provider);
+                }
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Returns a list of the installed file system providers.
+     *
+     * <p> The first invocation of this method causes the default provider to be
+     * initialized (if not already initialized) and loads any other installed
+     * providers as described by the {@link FileSystems} class.
+     *
+     * @return  An unmodifiable list of the installed file system providers. The
+     *          list contains at least one element, that is the default file
+     *          system provider
+     *
+     * @throws  ServiceConfigurationError
+     *          When an error occurs while loading a service provider
+     */
+    public static List<FileSystemProvider> installedProviders() {
+        if (installedProviders == null) {
+            // ensure default provider is initialized
+            FileSystemProvider defaultProvider = FileSystems.getDefault().provider();
+
+            synchronized (lock) {
+                if (installedProviders == null) {
+                    if (loadingProviders) {
+                        throw new Error("Circular loading of installed providers detected");
+                    }
+                    loadingProviders = true;
+
+                    List<FileSystemProvider> list = AccessController
+                        .doPrivileged(new PrivilegedAction<List<FileSystemProvider>>() {
+                            @Override
+                            public List<FileSystemProvider> run() {
+                                return loadInstalledProviders();
+                        }});
+
+                    // insert the default provider at the start of the list
+                    list.add(0, defaultProvider);
+
+                    installedProviders = Collections.unmodifiableList(list);
+                }
+            }
+        }
+        return installedProviders;
+    }
+
+    /**
+     * Returns the URI scheme that identifies this provider.
+     *
+     * @return  The URI scheme
+     */
+    public abstract String getScheme();
+
+    /**
+     * Constructs a new {@code FileSystem} object identified by a URI. This
+     * method is invoked by the {@link FileSystems#newFileSystem(URI,Map)}
+     * method to open a new file system identified by a URI.
+     *
+     * <p> The {@code uri} parameter is an absolute, hierarchical URI, with a
+     * scheme equal (without regard to case) to the scheme supported by this
+     * provider. The exact form of the URI is highly provider dependent. The
+     * {@code env} parameter is a map of provider specific properties to configure
+     * the file system.
+     *
+     * <p> This method throws {@link FileSystemAlreadyExistsException} if the
+     * file system already exists because it was previously created by an
+     * invocation of this method. Once a file system is {@link
+     * java.nio.file.FileSystem#close closed} it is provider-dependent if the
+     * provider allows a new file system to be created with the same URI as a
+     * file system it previously created.
+     *
+     * @param   uri
+     *          URI reference
+     * @param   env
+     *          A map of provider specific properties to configure the file system;
+     *          may be empty
+     *
+     * @return  A new file system
+     *
+     * @throws  IllegalArgumentException
+     *          If the pre-conditions for the {@code uri} parameter aren't met,
+     *          or the {@code env} parameter does not contain properties required
+     *          by the provider, or a property value is invalid
+     * @throws  IOException
+     *          An I/O error occurs creating the file system
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an unspecified
+     *          permission required by the file system provider implementation
+     * @throws  FileSystemAlreadyExistsException
+     *          If the file system has already been created
+     */
+    public abstract FileSystem newFileSystem(URI uri, Map<String,?> env)
+        throws IOException;
+
+    /**
+     * Returns an existing {@code FileSystem} created by this provider.
+     *
+     * <p> This method returns a reference to a {@code FileSystem} that was
+     * created by invoking the {@link #newFileSystem(URI,Map) newFileSystem(URI,Map)}
+     * method. File systems created the {@link #newFileSystem(Path,Map)
+     * newFileSystem(Path,Map)} method are not returned by this method.
+     * The file system is identified by its {@code URI}. Its exact form
+     * is highly provider dependent. In the case of the default provider the URI's
+     * path component is {@code "/"} and the authority, query and fragment components
+     * are undefined (Undefined components are represented by {@code null}).
+     *
+     * <p> Once a file system created by this provider is {@link
+     * java.nio.file.FileSystem#close closed} it is provider-dependent if this
+     * method returns a reference to the closed file system or throws {@link
+     * FileSystemNotFoundException}. If the provider allows a new file system to
+     * be created with the same URI as a file system it previously created then
+     * this method throws the exception if invoked after the file system is
+     * closed (and before a new instance is created by the {@link #newFileSystem
+     * newFileSystem} method).
+     *
+     * <p> If a security manager is installed then a provider implementation
+     * may require to check a permission before returning a reference to an
+     * existing file system. In the case of the {@link FileSystems#getDefault
+     * default} file system, no permission check is required.
+     *
+     * @param   uri
+     *          URI reference
+     *
+     * @return  The file system
+     *
+     * @throws  IllegalArgumentException
+     *          If the pre-conditions for the {@code uri} parameter aren't met
+     * @throws  FileSystemNotFoundException
+     *          If the file system does not exist
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an unspecified
+     *          permission.
+     */
+    public abstract FileSystem getFileSystem(URI uri);
+
+    /**
+     * Return a {@code Path} object by converting the given {@link URI}. The
+     * resulting {@code Path} is associated with a {@link FileSystem} that
+     * already exists or is constructed automatically.
+     *
+     * <p> The exact form of the URI is file system provider dependent. In the
+     * case of the default provider, the URI scheme is {@code "file"} and the
+     * given URI has a non-empty path component, and undefined query, and
+     * fragment components. The resulting {@code Path} is associated with the
+     * default {@link FileSystems#getDefault default} {@code FileSystem}.
+     *
+     * <p> If a security manager is installed then a provider implementation
+     * may require to check a permission. In the case of the {@link
+     * FileSystems#getDefault default} file system, no permission check is
+     * required.
+     *
+     * @param   uri
+     *          The URI to convert
+     *
+     * @return  The resulting {@code Path}
+     *
+     * @throws  IllegalArgumentException
+     *          If the URI scheme does not identify this provider or other
+     *          preconditions on the uri parameter do not hold
+     * @throws  FileSystemNotFoundException
+     *          The file system, identified by the URI, does not exist and
+     *          cannot be created automatically
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an unspecified
+     *          permission.
+     */
+    public abstract Path getPath(URI uri);
+
+    /**
+     * Constructs a new {@code FileSystem} to access the contents of a file as a
+     * file system.
+     *
+     * <p> This method is intended for specialized providers of pseudo file
+     * systems where the contents of one or more files is treated as a file
+     * system. The {@code env} parameter is a map of provider specific properties
+     * to configure the file system.
+     *
+     * <p> If this provider does not support the creation of such file systems
+     * or if the provider does not recognize the file type of the given file then
+     * it throws {@code UnsupportedOperationException}. The default implementation
+     * of this method throws {@code UnsupportedOperationException}.
+     *
+     * @param   path
+     *          The path to the file
+     * @param   env
+     *          A map of provider specific properties to configure the file system;
+     *          may be empty
+     *
+     * @return  A new file system
+     *
+     * @throws  UnsupportedOperationException
+     *          If this provider does not support access to the contents as a
+     *          file system or it does not recognize the file type of the
+     *          given file
+     * @throws  IllegalArgumentException
+     *          If the {@code env} parameter does not contain properties required
+     *          by the provider, or a property value is invalid
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          If a security manager is installed and it denies an unspecified
+     *          permission.
+     */
+    public FileSystem newFileSystem(Path path, Map<String,?> env)
+        throws IOException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Opens a file, returning an input stream to read from the file. This
+     * method works in exactly the manner specified by the {@link
+     * Files#newInputStream} method.
+     *
+     * <p> The default implementation of this method opens a channel to the file
+     * as if by invoking the {@link #newByteChannel} method and constructs a
+     * stream that reads bytes from the channel. This method should be overridden
+     * where appropriate.
+     *
+     * @param   path
+     *          the path to the file to open
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new input stream
+     *
+     * @throws  IllegalArgumentException
+     *          if an invalid combination of options is specified
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    public InputStream newInputStream(Path path, OpenOption... options)
+        throws IOException
+    {
+        if (options.length > 0) {
+            for (OpenOption opt: options) {
+                // All OpenOption values except for APPEND and WRITE are allowed
+                if (opt == StandardOpenOption.APPEND ||
+                    opt == StandardOpenOption.WRITE)
+                    throw new UnsupportedOperationException("'" + opt + "' not allowed");
+            }
+        }
+        return Channels.newInputStream(Files.newByteChannel(path, options));
+    }
+
+    /**
+     * Opens or creates a file, returning an output stream that may be used to
+     * write bytes to the file. This method works in exactly the manner
+     * specified by the {@link Files#newOutputStream} method.
+     *
+     * <p> The default implementation of this method opens a channel to the file
+     * as if by invoking the {@link #newByteChannel} method and constructs a
+     * stream that writes bytes to the channel. This method should be overridden
+     * where appropriate.
+     *
+     * @param   path
+     *          the path to the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
+     *
+     * @return  a new output stream
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code options} contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported option is specified
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the file. The {@link
+     *          SecurityManager#checkDelete(String) checkDelete} method is
+     *          invoked to check delete access if the file is opened with the
+     *          {@code DELETE_ON_CLOSE} option.
+     */
+    public OutputStream newOutputStream(Path path, OpenOption... options)
+        throws IOException
+    {
+        int len = options.length;
+        Set<OpenOption> opts = new HashSet<OpenOption>(len + 3);
+        if (len == 0) {
+            opts.add(StandardOpenOption.CREATE);
+            opts.add(StandardOpenOption.TRUNCATE_EXISTING);
+        } else {
+            for (OpenOption opt: options) {
+                if (opt == StandardOpenOption.READ)
+                    throw new IllegalArgumentException("READ not allowed");
+                opts.add(opt);
+            }
+        }
+        opts.add(StandardOpenOption.WRITE);
+        return Channels.newOutputStream(newByteChannel(path, opts));
+    }
+
+    /**
+     * Opens or creates a file for reading and/or writing, returning a file
+     * channel to access the file. This method works in exactly the manner
+     * specified by the {@link FileChannel#open(Path,Set,FileAttribute[])
+     * FileChannel.open} method. A provider that does not support all the
+     * features required to construct a file channel throws {@code
+     * UnsupportedOperationException}. The default provider is required to
+     * support the creation of file channels. When not overridden, the default
+     * implementation throws {@code UnsupportedOperationException}.
+     *
+     * @param   path
+     *          the path of the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  a new file channel
+     *
+     * @throws  IllegalArgumentException
+     *          If the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          If this provider that does not support creating file channels,
+     *          or an unsupported open option or file attribute is specified
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default file system, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     */
+    public FileChannel newFileChannel(Path path,
+                                      Set<? extends OpenOption> options,
+                                      FileAttribute<?>... attrs)
+        throws IOException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Opens or creates a file for reading and/or writing, returning an
+     * asynchronous file channel to access the file. This method works in
+     * exactly the manner specified by the {@link
+     * AsynchronousFileChannel#open(Path,Set,ExecutorService,FileAttribute[])
+     * AsynchronousFileChannel.open} method.
+     * A provider that does not support all the features required to construct
+     * an asynchronous file channel throws {@code UnsupportedOperationException}.
+     * The default provider is required to support the creation of asynchronous
+     * file channels. When not overridden, the default implementation of this
+     * method throws {@code UnsupportedOperationException}.
+     *
+     * @param   path
+     *          the path of the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
+     * @param   executor
+     *          the thread pool or {@code null} to associate the channel with
+     *          the default thread pool
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  a new asynchronous file channel
+     *
+     * @throws  IllegalArgumentException
+     *          If the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          If this provider that does not support creating asynchronous file
+     *          channels, or an unsupported open option or file attribute is
+     *          specified
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default file system, the {@link
+     *          SecurityManager#checkRead(String)} method is invoked to check
+     *          read access if the file is opened for reading. The {@link
+     *          SecurityManager#checkWrite(String)} method is invoked to check
+     *          write access if the file is opened for writing
+     */
+    public AsynchronousFileChannel newAsynchronousFileChannel(Path path,
+                                                              Set<? extends OpenOption> options,
+                                                              ExecutorService executor,
+                                                              FileAttribute<?>... attrs)
+        throws IOException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Opens or creates a file, returning a seekable byte channel to access the
+     * file. This method works in exactly the manner specified by the {@link
+     * Files#newByteChannel(Path,Set,FileAttribute[])} method.
+     *
+     * @param   path
+     *          the path to the file to open or create
+     * @param   options
+     *          options specifying how the file is opened
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the file
+     *
+     * @return  a new seekable byte channel
+     *
+     * @throws  IllegalArgumentException
+     *          if the set contains an invalid combination of options
+     * @throws  UnsupportedOperationException
+     *          if an unsupported open option is specified or the array contains
+     *          attributes that cannot be set atomically when creating the file
+     * @throws  FileAlreadyExistsException
+     *          if a file of that name already exists and the {@link
+     *          StandardOpenOption#CREATE_NEW CREATE_NEW} option is specified
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the path if the file is
+     *          opened for reading. The {@link SecurityManager#checkWrite(String)
+     *          checkWrite} method is invoked to check write access to the path
+     *          if the file is opened for writing. The {@link
+     *          SecurityManager#checkDelete(String) checkDelete} method is
+     *          invoked to check delete access if the file is opened with the
+     *          {@code DELETE_ON_CLOSE} option.
+     */
+    public abstract SeekableByteChannel newByteChannel(Path path,
+        Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException;
+
+    /**
+     * Opens a directory, returning a {@code DirectoryStream} to iterate over
+     * the entries in the directory. This method works in exactly the manner
+     * specified by the {@link
+     * Files#newDirectoryStream(java.nio.file.Path, java.nio.file.DirectoryStream.Filter)}
+     * method.
+     *
+     * @param   dir
+     *          the path to the directory
+     * @param   filter
+     *          the directory stream filter
+     *
+     * @return  a new and open {@code DirectoryStream} object
+     *
+     * @throws  NotDirectoryException
+     *          if the file could not otherwise be opened because it is not
+     *          a directory <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the directory.
+     */
+    public abstract DirectoryStream<Path> newDirectoryStream(Path dir,
+         DirectoryStream.Filter<? super Path> filter) throws IOException;
+
+    /**
+     * Creates a new directory. This method works in exactly the manner
+     * specified by the {@link Files#createDirectory} method.
+     *
+     * @param   dir
+     *          the directory to create
+     * @param   attrs
+     *          an optional list of file attributes to set atomically when
+     *          creating the directory
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains an attribute that cannot be set atomically
+     *          when creating the directory
+     * @throws  FileAlreadyExistsException
+     *          if a directory could not otherwise be created because a file of
+     *          that name already exists <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs or the parent directory does not exist
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to the new directory.
+     */
+    public abstract void createDirectory(Path dir, FileAttribute<?>... attrs)
+        throws IOException;
+
+    /**
+     * Creates a symbolic link to a target. This method works in exactly the
+     * manner specified by the {@link Files#createSymbolicLink} method.
+     *
+     * <p> The default implementation of this method throws {@code
+     * UnsupportedOperationException}.
+     *
+     * @param   link
+     *          the path of the symbolic link to create
+     * @param   target
+     *          the target of the symbolic link
+     * @param   attrs
+     *          the array of attributes to set atomically when creating the
+     *          symbolic link
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support symbolic links or the
+     *          array contains an attribute that cannot be set atomically when
+     *          creating the symbolic link
+     * @throws  FileAlreadyExistsException
+     *          if a file with the name already exists <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it denies {@link LinkPermission}<tt>("symbolic")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the path of the symbolic link.
+     */
+    public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs)
+        throws IOException
+    {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Creates a new link (directory entry) for an existing file. This method
+     * works in exactly the manner specified by the {@link Files#createLink}
+     * method.
+     *
+     * <p> The default implementation of this method throws {@code
+     * UnsupportedOperationException}.
+     *
+     * @param   link
+     *          the link (directory entry) to create
+     * @param   existing
+     *          a path to an existing file
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support adding an existing file
+     *          to a directory
+     * @throws  FileAlreadyExistsException
+     *          if the entry could not otherwise be created because a file of
+     *          that name already exists <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it denies {@link LinkPermission}<tt>("hard")</tt>
+     *          or its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to either the  link or the
+     *          existing file.
+     */
+    public void createLink(Path link, Path existing) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Deletes a file. This method works in exactly the  manner specified by the
+     * {@link Files#delete} method.
+     *
+     * @param   path
+     *          the path to the file to delete
+     *
+     * @throws  NoSuchFileException
+     *          if the file does not exist <i>(optional specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          if the file is a directory and could not otherwise be deleted
+     *          because the directory is not empty <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkDelete(String)} method
+     *          is invoked to check delete access to the file
+     */
+    public abstract void delete(Path path) throws IOException;
+
+    /**
+     * Deletes a file if it exists. This method works in exactly the manner
+     * specified by the {@link Files#deleteIfExists} method.
+     *
+     * <p> The default implementation of this method simply invokes {@link
+     * #delete} ignoring the {@code NoSuchFileException} when the file does not
+     * exist. It may be overridden where appropriate.
+     *
+     * @param   path
+     *          the path to the file to delete
+     *
+     * @return  {@code true} if the file was deleted by this method; {@code
+     *          false} if the file could not be deleted because it did not
+     *          exist
+     *
+     * @throws  DirectoryNotEmptyException
+     *          if the file is a directory and could not otherwise be deleted
+     *          because the directory is not empty <i>(optional specific
+     *          exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkDelete(String)} method
+     *          is invoked to check delete access to the file
+     */
+    public boolean deleteIfExists(Path path) throws IOException {
+        try {
+            delete(path);
+            return true;
+        } catch (NoSuchFileException ignore) {
+            return false;
+        }
+    }
+
+    /**
+     * Reads the target of a symbolic link. This method works in exactly the
+     * manner specified by the {@link Files#readSymbolicLink} method.
+     *
+     * <p> The default implementation of this method throws {@code
+     * UnsupportedOperationException}.
+     *
+     * @param   link
+     *          the path to the symbolic link
+     *
+     * @return  The target of the symbolic link
+     *
+     * @throws  UnsupportedOperationException
+     *          if the implementation does not support symbolic links
+     * @throws  NotLinkException
+     *          if the target could otherwise not be read because the file
+     *          is not a symbolic link <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager
+     *          is installed, it checks that {@code FilePermission} has been
+     *          granted with the "{@code readlink}" action to read the link.
+     */
+    public Path readSymbolicLink(Path link) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Copy a file to a target file. This method works in exactly the manner
+     * specified by the {@link Files#copy(Path,Path,CopyOption[])} method
+     * except that both the source and target paths must be associated with
+     * this provider.
+     *
+     * @param   source
+     *          the path to the file to copy
+     * @param   target
+     *          the path to the target file
+     * @param   options
+     *          options specifying how the copy should be done
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains a copy option that is not supported
+     * @throws  FileAlreadyExistsException
+     *          if the target file exists but cannot be replaced because the
+     *          {@code REPLACE_EXISTING} option is not specified <i>(optional
+     *          specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          the {@code REPLACE_EXISTING} option is specified but the file
+     *          cannot be replaced because it is a non-empty directory
+     *          <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the source file, the
+     *          {@link SecurityManager#checkWrite(String) checkWrite} is invoked
+     *          to check write access to the target file. If a symbolic link is
+     *          copied the security manager is invoked to check {@link
+     *          LinkPermission}{@code ("symbolic")}.
+     */
+    public abstract void copy(Path source, Path target, CopyOption... options)
+        throws IOException;
+
+    /**
+     * Move or rename a file to a target file. This method works in exactly the
+     * manner specified by the {@link Files#move} method except that both the
+     * source and target paths must be associated with this provider.
+     *
+     * @param   source
+     *          the path to the file to move
+     * @param   target
+     *          the path to the target file
+     * @param   options
+     *          options specifying how the move should be done
+     *
+     * @throws  UnsupportedOperationException
+     *          if the array contains a copy option that is not supported
+     * @throws  FileAlreadyExistsException
+     *          if the target file exists but cannot be replaced because the
+     *          {@code REPLACE_EXISTING} option is not specified <i>(optional
+     *          specific exception)</i>
+     * @throws  DirectoryNotEmptyException
+     *          the {@code REPLACE_EXISTING} option is specified but the file
+     *          cannot be replaced because it is a non-empty directory
+     *          <i>(optional specific exception)</i>
+     * @throws  AtomicMoveNotSupportedException
+     *          if the options array contains the {@code ATOMIC_MOVE} option but
+     *          the file cannot be moved as an atomic file system operation.
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method is invoked to check write access to both the source and
+     *          target file.
+     */
+    public abstract void move(Path source, Path target, CopyOption... options)
+        throws IOException;
+
+    /**
+     * Tests if two paths locate the same file. This method works in exactly the
+     * manner specified by the {@link Files#isSameFile} method.
+     *
+     * @param   path
+     *          one path to the file
+     * @param   path2
+     *          the other path
+     *
+     * @return  {@code true} if, and only if, the two paths locate the same file
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to both files.
+     */
+    public abstract boolean isSameFile(Path path, Path path2)
+        throws IOException;
+
+    /**
+     * Tells whether or not a file is considered <em>hidden</em>. This method
+     * works in exactly the manner specified by the {@link Files#isHidden}
+     * method.
+     *
+     * <p> This method is invoked by the {@link Files#isHidden isHidden} method.
+     *
+     * @param   path
+     *          the path to the file to test
+     *
+     * @return  {@code true} if the file is considered hidden
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file.
+     */
+    public abstract boolean isHidden(Path path) throws IOException;
+
+    /**
+     * Returns the {@link FileStore} representing the file store where a file
+     * is located. This method works in exactly the manner specified by the
+     * {@link Files#getFileStore} method.
+     *
+     * @param   path
+     *          the path to the file
+     *
+     * @return  the file store where the file is stored
+     *
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file, and in
+     *          addition it checks {@link RuntimePermission}<tt>
+     *          ("getFileStoreAttributes")</tt>
+     */
+    public abstract FileStore getFileStore(Path path) throws IOException;
+
+    /**
+     * Checks the existence, and optionally the accessibility, of a file.
+     *
+     * <p> This method may be used by the {@link Files#isReadable isReadable},
+     * {@link Files#isWritable isWritable} and {@link Files#isExecutable
+     * isExecutable} methods to check the accessibility of a file.
+     *
+     * <p> This method checks the existence of a file and that this Java virtual
+     * machine has appropriate privileges that would allow it access the file
+     * according to all of access modes specified in the {@code modes} parameter
+     * as follows:
+     *
+     * <table border=1 cellpadding=5 summary="">
+     * <tr> <th>Value</th> <th>Description</th> </tr>
+     * <tr>
+     *   <td> {@link AccessMode#READ READ} </td>
+     *   <td> Checks that the file exists and that the Java virtual machine has
+     *     permission to read the file. </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link AccessMode#WRITE WRITE} </td>
+     *   <td> Checks that the file exists and that the Java virtual machine has
+     *     permission to write to the file, </td>
+     * </tr>
+     * <tr>
+     *   <td> {@link AccessMode#EXECUTE EXECUTE} </td>
+     *   <td> Checks that the file exists and that the Java virtual machine has
+     *     permission to {@link Runtime#exec execute} the file. The semantics
+     *     may differ when checking access to a directory. For example, on UNIX
+     *     systems, checking for {@code EXECUTE} access checks that the Java
+     *     virtual machine has permission to search the directory in order to
+     *     access file or subdirectories. </td>
+     * </tr>
+     * </table>
+     *
+     * <p> If the {@code modes} parameter is of length zero, then the existence
+     * of the file is checked.
+     *
+     * <p> This method follows symbolic links if the file referenced by this
+     * object is a symbolic link. Depending on the implementation, this method
+     * may require to read file permissions, access control lists, or other
+     * file attributes in order to check the effective access to the file. To
+     * determine the effective access to a file may require access to several
+     * attributes and so in some implementations this method may not be atomic
+     * with respect to other file system operations.
+     *
+     * @param   path
+     *          the path to the file to check
+     * @param   modes
+     *          The access modes to check; may have zero elements
+     *
+     * @throws  UnsupportedOperationException
+     *          an implementation is required to support checking for
+     *          {@code READ}, {@code WRITE}, and {@code EXECUTE} access. This
+     *          exception is specified to allow for the {@code Access} enum to
+     *          be extended in future releases.
+     * @throws  NoSuchFileException
+     *          if a file does not exist <i>(optional specific exception)</i>
+     * @throws  AccessDeniedException
+     *          the requested access would be denied or the access cannot be
+     *          determined because the Java virtual machine has insufficient
+     *          privileges or other reasons. <i>(optional specific exception)</i>
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, the {@link SecurityManager#checkRead(String) checkRead}
+     *          is invoked when checking read access to the file or only the
+     *          existence of the file, the {@link SecurityManager#checkWrite(String)
+     *          checkWrite} is invoked when checking write access to the file,
+     *          and {@link SecurityManager#checkExec(String) checkExec} is invoked
+     *          when checking execute access.
+     */
+    public abstract void checkAccess(Path path, AccessMode... modes)
+        throws IOException;
+
+    /**
+     * Returns a file attribute view of a given type. This method works in
+     * exactly the manner specified by the {@link Files#getFileAttributeView}
+     * method.
+     *
+     * @param   <V>
+     *          The {@code FileAttributeView} type
+     * @param   path
+     *          the path to the file
+     * @param   type
+     *          the {@code Class} object corresponding to the file attribute view
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a file attribute view of the specified type, or {@code null} if
+     *          the attribute view type is not available
+     */
+    public abstract <V extends FileAttributeView> V
+        getFileAttributeView(Path path, Class<V> type, LinkOption... options);
+
+    /**
+     * Reads a file's attributes as a bulk operation. This method works in
+     * exactly the manner specified by the {@link
+     * Files#readAttributes(Path,Class,LinkOption[])} method.
+     *
+     * @param   <A>
+     *          The {@code BasicFileAttributes} type
+     * @param   path
+     *          the path to the file
+     * @param   type
+     *          the {@code Class} of the file attributes required
+     *          to read
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  the file attributes
+     *
+     * @throws  UnsupportedOperationException
+     *          if an attributes of the given type are not supported
+     * @throws  IOException
+     *          if an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method is invoked to check read access to the file
+     */
+    public abstract <A extends BasicFileAttributes> A
+        readAttributes(Path path, Class<A> type, LinkOption... options) throws IOException;
+
+    /**
+     * Reads a set of file attributes as a bulk operation. This method works in
+     * exactly the manner specified by the {@link
+     * Files#readAttributes(Path,String,LinkOption[])} method.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   attributes
+     *          the attributes to read
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @return  a map of the attributes returned; may be empty. The map's keys
+     *          are the attribute names, its values are the attribute values
+     *
+     * @throws  UnsupportedOperationException
+     *          if the attribute view is not available
+     * @throws  IllegalArgumentException
+     *          if no attributes are specified or an unrecognized attributes is
+     *          specified
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkRead(String) checkRead}
+     *          method denies read access to the file. If this method is invoked
+     *          to read security sensitive attributes then the security manager
+     *          may be invoke to check for additional permissions.
+     */
+    public abstract Map<String,Object> readAttributes(Path path, String attributes,
+                                                      LinkOption... options)
+        throws IOException;
+
+    /**
+     * Sets the value of a file attribute. This method works in exactly the
+     * manner specified by the {@link Files#setAttribute} method.
+     *
+     * @param   path
+     *          the path to the file
+     * @param   attribute
+     *          the attribute to set
+     * @param   value
+     *          the attribute value
+     * @param   options
+     *          options indicating how symbolic links are handled
+     *
+     * @throws  UnsupportedOperationException
+     *          if the attribute view is not available
+     * @throws  IllegalArgumentException
+     *          if the attribute name is not specified, or is not recognized, or
+     *          the attribute value is of the correct type but has an
+     *          inappropriate value
+     * @throws  ClassCastException
+     *          If the attribute value is not of the expected type or is a
+     *          collection containing elements that are not of the expected
+     *          type
+     * @throws  IOException
+     *          If an I/O error occurs
+     * @throws  SecurityException
+     *          In the case of the default provider, and a security manager is
+     *          installed, its {@link SecurityManager#checkWrite(String) checkWrite}
+     *          method denies write access to the file. If this method is invoked
+     *          to set security sensitive attributes then the security manager
+     *          may be invoked to check for additional permissions.
+     */
+    public abstract void setAttribute(Path path, String attribute,
+                                      Object value, LinkOption... options)
+        throws IOException;
+}
diff --git a/java/nio/file/spi/FileTypeDetector.java b/java/nio/file/spi/FileTypeDetector.java
new file mode 100644
index 0000000..ee118d6
--- /dev/null
+++ b/java/nio/file/spi/FileTypeDetector.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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.nio.file.spi;
+
+import java.nio.file.Path;
+import java.io.IOException;
+
+/**
+ * A file type detector for probing a file to guess its file type.
+ *
+ * <p> A file type detector is a concrete implementation of this class, has a
+ * zero-argument constructor, and implements the abstract methods specified
+ * below.
+ *
+ * <p> The means by which a file type detector determines the file type is
+ * highly implementation specific. A simple implementation might examine the
+ * <em>file extension</em> (a convention used in some platforms) and map it to
+ * a file type. In other cases, the file type may be stored as a file <a
+ * href="../attribute/package-summary.html"> attribute</a> or the bytes in a
+ * file may be examined to guess its file type.
+ *
+ * @see java.nio.file.Files#probeContentType(Path)
+ *
+ * @since 1.7
+ */
+
+public abstract class FileTypeDetector {
+
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null)
+            sm.checkPermission(new RuntimePermission("fileTypeDetector"));
+        return null;
+    }
+    private FileTypeDetector(Void ignore) { }
+
+    /**
+     * Initializes a new instance of this class.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     *          {@link RuntimePermission}<tt>("fileTypeDetector")</tt>
+     */
+    protected FileTypeDetector() {
+        this(checkPermission());
+    }
+
+    /**
+     * Probes the given file to guess its content type.
+     *
+     * <p> The means by which this method determines the file type is highly
+     * implementation specific. It may simply examine the file name, it may use
+     * a file <a href="../attribute/package-summary.html">attribute</a>,
+     * or it may examines bytes in the file.
+     *
+     * <p> The probe result is the string form of the value of a
+     * Multipurpose Internet Mail Extension (MIME) content type as
+     * defined by <a href="http://www.ietf.org/rfc/rfc2045.txt"><i>RFC&nbsp;2045:
+     * Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet
+     * Message Bodies</i></a>. The string must be parsable according to the
+     * grammar in the RFC 2045.
+     *
+     * @param   path
+     *          the path to the file to probe
+     *
+     * @return  The content type or {@code null} if the file type is not
+     *          recognized
+     *
+     * @throws  IOException
+     *          An I/O error occurs
+     * @throws  SecurityException
+     *          If the implementation requires to access the file, and a
+     *          security manager is installed, and it denies an unspecified
+     *          permission required by a file system provider implementation.
+     *          If the file reference is associated with the default file system
+     *          provider then the {@link SecurityManager#checkRead(String)} method
+     *          is invoked to check read access to the file.
+     *
+     * @see java.nio.file.Files#probeContentType
+     */
+    public abstract String probeContentType(Path path)
+        throws IOException;
+}
diff --git a/java/nio/package-info.java b/java/nio/package-info.java
new file mode 100644
index 0000000..b466dc4
--- /dev/null
+++ b/java/nio/package-info.java
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+/**
+ * Defines buffers, which are containers for data, and provides an overview of the
+ * other NIO packages.
+ *
+ *
+ * <p> The central abstractions of the NIO APIs are: </p>
+ *
+ * <ul>
+ *
+ *   <li><p> <a href="#buffers"><i>Buffers</i></a>, which are containers for data;
+ *   </p></li>
+ *
+ *   <li><p> <a href="charset/package-summary.html"><i>Charsets</i></a> and their
+ *   associated <i>decoders</i> and <i>encoders</i>, <br> which translate between
+ *   bytes and Unicode characters; </p></li>
+ *
+ *   <li><p> <a href="channels/package-summary.html"><i>Channels</i></a> of
+ *   various types, which represent connections <br> to entities capable of
+ *   performing I/O operations; and </p></li>
+ *
+ *   <li><p> <i>Selectors</i> and <i>selection keys</i>, which together with <br>
+ *   <i>selectable channels</i> define a <a
+ *   href="channels/package-summary.html#multiplex">multiplexed, non-blocking <br>
+ *   I/O</a>&nbsp;facility.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> The <tt>java.nio</tt> package defines the buffer classes, which are used
+ * throughout the NIO APIs.  The charset API is defined in the {@link
+ * java.nio.charset} package, and the channel and selector APIs are defined in the
+ * {@link java.nio.channels} package.  Each of these subpackages has its own
+ * service-provider (SPI) subpackage, the contents of which can be used to extend
+ * the platform's default implementations or to construct alternative
+ * implementations.
+ *
+ *
+ * <a name="buffers">
+ *
+ * <blockquote><table cellspacing=1 cellpadding=0 summary="Description of the various buffers">
+ *   <tr><th><p align="left">Buffers</p></th><th><p align="left">Description</p></th></tr>
+ *   <tr><td valign=top><tt>{@link java.nio.Buffer}</tt></td>
+ *       <td>Position, limit, and capacity;
+ *           <br>clear, flip, rewind, and mark/reset</td></tr>
+ *   <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.ByteBuffer}</tt></td>
+ *       <td>Get/put, compact, views; allocate,&nbsp;wrap</td></tr>
+ *   <tr><td valign=top><tt>&nbsp;&nbsp;&nbsp;&nbsp;{@link java.nio.MappedByteBuffer}&nbsp;&nbsp;</tt></td>
+ *       <td>A byte buffer mapped to a file</td></tr>
+ *   <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.CharBuffer}</tt></td>
+ *       <td>Get/put, compact; allocate,&nbsp;wrap</td></tr>
+ *   <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.DoubleBuffer}</tt></td>
+ *       <td>&nbsp;&nbsp;&nbsp;&nbsp;'&nbsp;'</td></tr>
+ *   <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.FloatBuffer}</tt></td>
+ *       <td>&nbsp;&nbsp;&nbsp;&nbsp;'&nbsp;'</td></tr>
+ *   <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.IntBuffer}</tt></td>
+ *       <td>&nbsp;&nbsp;&nbsp;&nbsp;'&nbsp;'</td></tr>
+ *   <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.LongBuffer}</tt></td>
+ *       <td>&nbsp;&nbsp;&nbsp;&nbsp;'&nbsp;'</td></tr>
+ *   <tr><td valign=top><tt>&nbsp;&nbsp;{@link java.nio.ShortBuffer}</tt></td>
+ *       <td>&nbsp;&nbsp;&nbsp;&nbsp;'&nbsp;'</td></tr>
+ *   <tr><td valign=top><tt>{@link java.nio.ByteOrder}</tt></td>
+ *       <td>Typesafe enumeration for&nbsp;byte&nbsp;orders</td></tr>
+ * </table></blockquote>
+ *
+ * <p> A <i>buffer</i> is a container for a fixed amount of data of a specific
+ * primitive type.  In addition to its content a buffer has a <i>position</i>,
+ * which is the index of the next element to be read or written, and a
+ * <i>limit</i>, which is the index of the first element that should not be read
+ * or written.  The base {@link java.nio.Buffer} class defines these properties as
+ * well as methods for <i>clearing</i>, <i>flipping</i>, and <i>rewinding</i>, for
+ * <i>marking</i> the current position, and for <i>resetting</i> the position to
+ * the previous mark.
+ *
+ * <p> There is a buffer class for each non-boolean primitive type.  Each class
+ * defines a family of <i>get</i> and <i>put</i> methods for moving data out of
+ * and in to a buffer, methods for <i>compacting</i>, <i>duplicating</i>, and
+ * <i>slicing</i> a buffer, and static methods for <i>allocating</i> a new buffer
+ * as well as for <i>wrapping</i> an existing array into a buffer.
+ *
+ * <p> Byte buffers are distinguished in that they can be used as the sources and
+ * targets of I/O operations.  They also support several features not found in the
+ * other buffer classes:
+ *
+ * <ul>
+ *
+ *   <li><p> A byte buffer can be allocated as a <a href="ByteBuffer.html#direct">
+ *   <i>direct</i></a> buffer, in which case the Java virtual machine will make a
+ *   best effort to perform native I/O operations directly upon it.  </p></li>
+ *
+ *   <li><p> A byte buffer can be created by {@link
+ *   java.nio.channels.FileChannel#map </code><i>mapping</i><code>} a region of a
+ *   file directly into memory, in which case a few additional file-related
+ *   operations defined in the {@link java.nio.MappedByteBuffer} class are
+ *   available.  </p></li>
+ *
+ *   <li><p> A byte buffer provides access to its content as either a heterogeneous
+ *   or homogeneous sequence of <a href="ByteBuffer.html#bin">binary data</i></a>
+ *   of any non-boolean primitive type, in either big-endian or little-endian <a
+ *   href="ByteOrder.html">byte order</a>.  </p></li>
+ *
+ * </ul>
+ *
+ * <p> Unless otherwise noted, passing a <tt>null</tt> argument to a constructor
+ * or method in any class or interface in this package will cause a {@link
+ * java.lang.NullPointerException NullPointerException} to be thrown.
+ *
+ * @since 1.4
+ * @author Mark Reinhold
+ * @author JSR-51 Expert Group
+ */
+
+package java.nio;