merge in oc-release history after reset to master
diff --git a/dalvik/src/main/java/dalvik/system/EmulatedStackFrame.java b/dalvik/src/main/java/dalvik/system/EmulatedStackFrame.java
index 48363ce..83777b0 100644
--- a/dalvik/src/main/java/dalvik/system/EmulatedStackFrame.java
+++ b/dalvik/src/main/java/dalvik/system/EmulatedStackFrame.java
@@ -198,7 +198,7 @@
     public <T> T getReference(int idx, Class<T> referenceType) {
         if (referenceType != type.ptypes()[idx]) {
             throw new IllegalArgumentException("Argument: " + idx +
-                    " is not of type " + referenceType);
+                    " is of type " + type.ptypes()[idx] + " expected " + referenceType + "");
         }
 
         return (T) references[idx];
@@ -327,12 +327,21 @@
          * values to it. Also resets all state associated with the current accessor.
          */
         public StackFrameAccessor attach(EmulatedStackFrame stackFrame) {
+            return attach(stackFrame, 0 /* argumentIdx */, 0 /* referencesOffset */,
+                    0 /* frameOffset */);
+        }
+
+        public StackFrameAccessor attach(EmulatedStackFrame stackFrame, int argumentIdx,
+                                         int referencesOffset, int frameOffset) {
             frame = stackFrame;
             frameBuf = ByteBuffer.wrap(frame.stackFrame).order(ByteOrder.LITTLE_ENDIAN);
             numArgs = frame.type.ptypes().length;
+            if (frameOffset != 0) {
+                frameBuf.position(frameOffset);
+            }
 
-            referencesOffset = 0;
-            argumentIdx = 0;
+            this.referencesOffset = referencesOffset;
+            this.argumentIdx = argumentIdx;
 
             return this;
         }
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandle.java b/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
index 2882686..07ecf5f 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandle.java
@@ -864,8 +864,12 @@
     public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
         MethodType postSpreadType = asSpreaderChecks(arrayType, arrayLength);
 
-        // Android-changed, TODO(narayan): Implement asSpreader, remove @hide.
-        throw new UnsupportedOperationException("asSpreader(Class<?>, int)");
+        final int targetParamCount = postSpreadType.parameterCount();
+        MethodType dropArrayArgs = postSpreadType.dropParameterTypes(
+                (targetParamCount - arrayLength), targetParamCount);
+        MethodType adapterType = dropArrayArgs.appendParameterTypes(arrayType);
+
+        return new Transformers.Spreader(this, adapterType, arrayLength);
     }
 
     /**
diff --git a/ojluni/src/main/java/java/lang/invoke/MethodHandles.java b/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
index 9ef4cae..175203f 100644
--- a/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
+++ b/ojluni/src/main/java/java/lang/invoke/MethodHandles.java
@@ -1802,11 +1802,11 @@
     MethodHandle spreadInvoker(MethodType type, int leadingArgCount) {
         if (leadingArgCount < 0 || leadingArgCount > type.parameterCount())
             throw newIllegalArgumentException("bad argument count", leadingArgCount);
-        type = type.asSpreaderType(Object[].class, type.parameterCount() - leadingArgCount);
-        // return type.invokers().spreadInvoker(leadingArgCount);
 
-        // TODO(narayan): Implement spreadInvoker, remove @hide.
-        throw new UnsupportedOperationException("MethodHandles.spreadInvoker is not implemented");
+        MethodHandle invoker = MethodHandles.invoker(type);
+        int spreadArgCount = type.parameterCount() - leadingArgCount;
+        invoker = invoker.asSpreader(Object[].class, spreadArgCount);
+        return invoker;
     }
 
     /**
diff --git a/ojluni/src/main/java/java/lang/invoke/Transformers.java b/ojluni/src/main/java/java/lang/invoke/Transformers.java
index 1e7c58b..98948f5 100644
--- a/ojluni/src/main/java/java/lang/invoke/Transformers.java
+++ b/ojluni/src/main/java/java/lang/invoke/Transformers.java
@@ -21,6 +21,7 @@
 package java.lang.invoke;
 
 import dalvik.system.EmulatedStackFrame;
+import dalvik.system.EmulatedStackFrame.Range;
 import dalvik.system.EmulatedStackFrame.StackFrameReader;
 import dalvik.system.EmulatedStackFrame.StackFrameWriter;
 import java.lang.reflect.Array;
@@ -1030,4 +1031,272 @@
             targetFrame.copyReturnValueTo(emulatedStackFrame);
         }
     }
+
+
+    /**
+     * Implements MethodHandle.asSpreader / MethodHandles.spreadInvoker.
+     */
+    static class Spreader extends Transformer {
+        /** The method handle we're delegating to. */
+        private final MethodHandle target;
+
+        /**
+         * The offset of the trailing array argument in the list of arguments to
+         * this transformer. The array argument is always the last argument.
+         */
+        private final int arrayOffset;
+
+        /**
+         * The type char of the component type of the array.
+         */
+        private final char arrayTypeChar;
+
+        /**
+         * The number of input arguments that will be present in the array. In other words,
+         * this is the expected array length.
+         */
+        private final int numArrayArgs;
+
+        /**
+         * Range of arguments to copy verbatim from the input frame, This will cover all
+         * arguments that aren't a part of the trailing array.
+         */
+        private final Range copyRange;
+        private final StackFrameWriter writer;
+
+        Spreader(MethodHandle target, MethodType spreaderType, int numArrayArgs) {
+            super(spreaderType);
+            this.target = target;
+            // Copy all arguments except the last argument (which is the trailing array argument
+            // that needs to be spread).
+            arrayOffset = spreaderType.parameterCount() - 1;
+
+            // Get and cache the component type of the input array.
+            final Class<?> componentType = spreaderType.ptypes()[arrayOffset].getComponentType();
+            if (componentType == null) {
+                throw new AssertionError("Trailing argument must be an array.");
+            }
+            arrayTypeChar = Wrapper.basicTypeChar(componentType);
+
+            this.numArrayArgs = numArrayArgs;
+            // Copy all args except for the last argument.
+            this.copyRange = EmulatedStackFrame.Range.of(spreaderType, 0, arrayOffset);
+            this.writer = new StackFrameWriter();
+        }
+
+        @Override
+        public void transform(EmulatedStackFrame callerFrame) throws Throwable {
+            // Create a new stack frame for the callee.
+            EmulatedStackFrame targetFrame = EmulatedStackFrame.create(target.type());
+
+            // Copy all arguments except for the trailing array argument.
+            callerFrame.copyRangeTo(targetFrame, copyRange, 0, 0);
+
+            // Attach the writer, prepare to spread the trailing array arguments into
+            // the callee frame.
+            writer.attach(targetFrame,
+                    arrayOffset,
+                    copyRange.numReferences,
+                    copyRange.numBytes);
+
+            // Get the array reference and check that its length is as expected.
+            Object arrayObj = callerFrame.getReference(
+                    copyRange.numReferences, this.type().ptypes()[arrayOffset]);
+            final int arrayLength = Array.getLength(arrayObj);
+            if (arrayLength != numArrayArgs) {
+                throw new IllegalArgumentException("Invalid array length: " + arrayLength);
+            }
+
+            final MethodType type = target.type();
+            switch (arrayTypeChar) {
+                case 'L':
+                    spreadArray((Object[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'I':
+                    spreadArray((int[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'J':
+                    spreadArray((long[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'B':
+                    spreadArray((byte[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'S':
+                    spreadArray((short[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'C':
+                    spreadArray((char[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'Z':
+                    spreadArray((boolean[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'F':
+                    spreadArray((float[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+                case 'D':
+                    spreadArray((double[]) arrayObj, writer, type, numArrayArgs, arrayOffset);
+                    break;
+
+            }
+
+            target.invoke(targetFrame);
+            targetFrame.copyReturnValueTo(callerFrame);
+        }
+
+        public static void spreadArray(Object[] array, StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                Object o = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(o, argumentType); break; }
+                    case 'I': { writer.putNextInt((int) o); break; }
+                    case 'J': { writer.putNextLong((long) o); break; }
+                    case 'B': { writer.putNextByte((byte) o); break; }
+                    case 'S': { writer.putNextShort((short) o); break; }
+                    case 'C': { writer.putNextChar((char) o); break; }
+                    case 'Z': { writer.putNextBoolean((boolean) o); break; }
+                    case 'F': { writer.putNextFloat((float) o); break; }
+                    case 'D': { writer.putNextDouble((double) o); break; }
+                }
+            }
+        }
+
+        public static void spreadArray(int[] array, StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                int j = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(j, argumentType); break; }
+                    case 'I': { writer.putNextInt(j); break; }
+                    case 'J': { writer.putNextLong(j); break; }
+                    case 'F': { writer.putNextFloat(j); break; }
+                    case 'D': { writer.putNextDouble(j); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(long[] array, StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                long l = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(l, argumentType); break; }
+                    case 'J': { writer.putNextLong(l); break; }
+                    case 'F': { writer.putNextFloat((float) l); break; }
+                    case 'D': { writer.putNextDouble((double) l); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(byte[] array,
+                                       StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                byte b = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(b, argumentType); break; }
+                    case 'I': { writer.putNextInt(b); break; }
+                    case 'J': { writer.putNextLong(b); break; }
+                    case 'B': { writer.putNextByte(b); break; }
+                    case 'S': { writer.putNextShort(b); break; }
+                    case 'F': { writer.putNextFloat(b); break; }
+                    case 'D': { writer.putNextDouble(b); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(short[] array,
+                                       StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                short s = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(s, argumentType); break; }
+                    case 'I': { writer.putNextInt(s); break; }
+                    case 'J': { writer.putNextLong(s); break; }
+                    case 'S': { writer.putNextShort(s); break; }
+                    case 'F': { writer.putNextFloat(s); break; }
+                    case 'D': { writer.putNextDouble(s); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(char[] array,
+                                       StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                char c = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(c, argumentType); break; }
+                    case 'I': { writer.putNextInt(c); break; }
+                    case 'J': { writer.putNextLong(c); break; }
+                    case 'C': { writer.putNextChar(c); break; }
+                    case 'F': { writer.putNextFloat(c); break; }
+                    case 'D': { writer.putNextDouble(c); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(boolean[] array,
+                                       StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                boolean z = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(z, argumentType); break; }
+                    case 'Z': { writer.putNextBoolean(z); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(double[] array,
+                                       StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                double d = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(d, argumentType); break; }
+                    case 'D': { writer.putNextDouble(d); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+
+        public static void spreadArray(float[] array, StackFrameWriter writer, MethodType type,
+                                       int numArgs, int offset) {
+            final Class<?>[] ptypes = type.ptypes();
+            for (int i = 0; i < numArgs; ++i) {
+                Class<?> argumentType = ptypes[i + offset];
+                float f = array[i];
+                switch (Wrapper.basicTypeChar(argumentType)) {
+                    case 'L': { writer.putNextReference(f, argumentType); break; }
+                    case 'D': { writer.putNextDouble((double) f); break; }
+                    case 'F': { writer.putNextFloat(f); break; }
+                    default : { throw new AssertionError(); }
+                }
+            }
+        }
+    }
 }
diff --git a/ojluni/src/main/java/java/nio/DirectByteBuffer.java b/ojluni/src/main/java/java/nio/DirectByteBuffer.java
index 5ea6ab0..7007e15 100644
--- a/ojluni/src/main/java/java/nio/DirectByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/DirectByteBuffer.java
@@ -35,6 +35,7 @@
 import sun.nio.ch.DirectBuffer;
 
 /** @hide */
+// Not final because it is extended in tests.
 public class DirectByteBuffer extends MappedByteBuffer implements DirectBuffer {
 
     /**
@@ -47,7 +48,7 @@
      *
      * A single MemoryRef instance is shared across all slices and duplicates of a given buffer.
      */
-    static class MemoryRef {
+    final static class MemoryRef {
         byte[] buffer;
         long allocatedAddress;
         final int offset;
@@ -90,7 +91,7 @@
     }
 
     // Invoked only by JNI: NewDirectByteBuffer(void*, long)
-    //
+    @SuppressWarnings("unused")
     private DirectByteBuffer(long addr, int cap) {
         super(-1, 0, cap, cap);
         memoryRef = new MemoryRef(addr);
@@ -111,7 +112,6 @@
     }
 
     // For duplicates and slices
-    //
     DirectByteBuffer(MemoryRef memoryRef,         // package-private
                      int mark, int pos, int lim, int cap,
                      int off) {
@@ -129,16 +129,17 @@
     }
 
     @Override
-    public Object attachment() {
+    public final Object attachment() {
         return memoryRef;
     }
 
     @Override
-    public Cleaner cleaner() {
+    public final Cleaner cleaner() {
         return cleaner;
     }
 
-    public ByteBuffer slice() {
+    @Override
+    public final ByteBuffer slice() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
@@ -151,7 +152,8 @@
         return new DirectByteBuffer(memoryRef, -1, 0, rem, rem, off, isReadOnly);
     }
 
-    public ByteBuffer duplicate() {
+    @Override
+    public final ByteBuffer duplicate() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
@@ -164,7 +166,8 @@
                 isReadOnly);
     }
 
-    public ByteBuffer asReadOnlyBuffer() {
+    @Override
+    public final ByteBuffer asReadOnlyBuffer() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
@@ -178,7 +181,7 @@
     }
 
     @Override
-    public long address() {
+    public final long address() {
         return address;
     }
 
@@ -190,20 +193,24 @@
         return Memory.peekByte(a);
     }
 
-    public byte get() {
+    @Override
+    public final byte get() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
         return get(ix(nextGetIndex()));
     }
 
-    public byte get(int i) {
+    @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");
@@ -221,12 +228,13 @@
         return this;
     }
 
-    public ByteBuffer put(long a, byte x) {
+    private ByteBuffer put(long a, byte x) {
         Memory.pokeByte(a, x);
         return this;
     }
 
-    public ByteBuffer put(byte x) {
+    @Override
+    public final ByteBuffer put(byte x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -237,7 +245,8 @@
         return this;
     }
 
-    public ByteBuffer put(int i, byte x) {
+    @Override
+    public final ByteBuffer put(int i, byte x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -248,6 +257,8 @@
         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 (isReadOnly) {
             throw new ReadOnlyBufferException();
@@ -268,7 +279,8 @@
         return this;
     }
 
-    public ByteBuffer compact() {
+    @Override
+    public final ByteBuffer compact() {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -286,30 +298,30 @@
         return this;
     }
 
-    public boolean isDirect() {
+    @Override
+    public final boolean isDirect() {
         return true;
     }
 
-    public boolean isReadOnly() {
+    @Override
+    public final boolean isReadOnly() {
         return isReadOnly;
     }
 
-    byte _get(int i) {                          // package-private
+    // Used by java.nio.Bits
+    @Override
+    final byte _get(int i) {                          // package-private
         return get(i);
     }
 
-    void _put(int i, byte b) {                  // package-private
+    // Used by java.nio.Bits
+    @Override
+    final void _put(int i, byte b) {                  // package-private
         put(i, b);
     }
 
-    private char getChar(long a) {
-        if (!memoryRef.isAccessible) {
-            throw new IllegalStateException("buffer is inaccessible");
-        }
-        return (char) Memory.peekShort(position, !nativeByteOrder);
-    }
-
-    public char getChar() {
+    @Override
+    public final char getChar() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
@@ -322,31 +334,33 @@
         return x;
     }
 
-    public char getChar(int i) {
+    @Override
+    public final char getChar(int i) {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
         checkIndex(i, SizeOf.CHAR);
-        char x = (char) Memory.peekShort(ix(i), !nativeByteOrder);
-        return x;
+        return (char) Memory.peekShort(ix(i), !nativeByteOrder);
     }
 
+    @Override
     char getCharUnchecked(int i) {
         return (char) Memory.peekShort(ix(i), !nativeByteOrder);
     }
 
+    @Override
     void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
         Memory.peekCharArray(ix(pos),
                 dst, dstOffset, length, !nativeByteOrder);
     }
 
-
     private ByteBuffer putChar(long a, char x) {
         Memory.pokeShort(a, (short) x, !nativeByteOrder);
         return this;
     }
 
-    public ByteBuffer putChar(char x) {
+    @Override
+    public final ByteBuffer putChar(char x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -357,7 +371,8 @@
         return this;
     }
 
-    public ByteBuffer putChar(int i, char x) {
+    @Override
+    public final ByteBuffer putChar(int i, char x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -368,16 +383,19 @@
         return this;
     }
 
+    @Override
     void putCharUnchecked(int i, char x) {
         putChar(ix(i), x);
     }
 
+    @Override
     void putUnchecked(int pos, char[] src, int srcOffset, int length) {
         Memory.pokeCharArray(ix(pos),
                 src, srcOffset, length, !nativeByteOrder);
     }
 
-    public CharBuffer asCharBuffer() {
+    @Override
+    public final CharBuffer asCharBuffer() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
@@ -386,49 +404,53 @@
         assert (off <= lim);
         int rem = (off <= lim ? lim - off : 0);
         int size = rem >> 1;
-        return (CharBuffer) (new ByteBufferAsCharBuffer(this,
+        return new ByteBufferAsCharBuffer(this,
                 -1,
                 0,
                 size,
                 size,
                 off,
-                order()));
+                order());
     }
 
     private short getShort(long a) {
         return Memory.peekShort(a, !nativeByteOrder);
     }
 
-    public short getShort() {
+    @Override
+    public final short getShort() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
         return getShort(ix(nextGetIndex(SizeOf.SHORT)));
     }
 
-    public short getShort(int i) {
+    @Override
+    public final short getShort(int i) {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
         return getShort(ix(checkIndex(i, SizeOf.SHORT)));
     }
 
+    @Override
     short getShortUnchecked(int i) {
         return getShort(ix(i));
     }
 
+    @Override
     void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
         Memory.peekShortArray(ix(pos),
                 dst, dstOffset, length, !nativeByteOrder);
     }
 
-
     private ByteBuffer putShort(long a, short x) {
         Memory.pokeShort(a, x, !nativeByteOrder);
         return this;
     }
 
-    public ByteBuffer putShort(short x) {
+    @Override
+    public final ByteBuffer putShort(short x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -439,7 +461,8 @@
         return this;
     }
 
-    public ByteBuffer putShort(int i, short x) {
+    @Override
+    public final ByteBuffer putShort(int i, short x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -450,16 +473,19 @@
         return this;
     }
 
+    @Override
     void putShortUnchecked(int i, short x) {
         putShort(ix(i), x);
     }
 
+    @Override
     void putUnchecked(int pos, short[] src, int srcOffset, int length) {
         Memory.pokeShortArray(ix(pos),
                 src, srcOffset, length, !nativeByteOrder);
     }
 
-    public ShortBuffer asShortBuffer() {
+    @Override
+    public final ShortBuffer asShortBuffer() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
@@ -468,19 +494,20 @@
         assert (off <= lim);
         int rem = (off <= lim ? lim - off : 0);
         int size = rem >> 1;
-        return (ShortBuffer) (new ByteBufferAsShortBuffer(this,
+        return new ByteBufferAsShortBuffer(this,
                 -1,
                 0,
                 size,
                 size,
                 off,
-                order()));
+                order());
     }
 
     private int getInt(long a) {
         return Memory.peekInt(a, !nativeByteOrder);
     }
 
+    @Override
     public int getInt() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
@@ -488,6 +515,7 @@
         return getInt(ix(nextGetIndex(SizeOf.INT)));
     }
 
+    @Override
     public int getInt(int i) {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
@@ -495,11 +523,13 @@
         return getInt(ix(checkIndex(i, (SizeOf.INT))));
     }
 
-    int getIntUnchecked(int i) {
+    @Override
+    final int getIntUnchecked(int i) {
         return getInt(ix(i));
     }
 
-    void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
+    @Override
+    final void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
         Memory.peekIntArray(ix(pos),
                 dst, dstOffset, length, !nativeByteOrder);
     }
@@ -509,7 +539,8 @@
         return this;
     }
 
-    public ByteBuffer putInt(int x) {
+    @Override
+    public final ByteBuffer putInt(int x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -520,7 +551,8 @@
         return this;
     }
 
-    public ByteBuffer putInt(int i, int x) {
+    @Override
+    public final ByteBuffer putInt(int i, int x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -531,17 +563,19 @@
         return this;
     }
 
-    void putIntUnchecked(int i, int x) {
+    @Override
+    final void putIntUnchecked(int i, int x) {
         putInt(ix(i), x);
     }
 
-    void putUnchecked(int pos, int[] src, int srcOffset, int length) {
+    @Override
+    final void putUnchecked(int pos, int[] src, int srcOffset, int length) {
         Memory.pokeIntArray(ix(pos),
                 src, srcOffset, length, !nativeByteOrder);
     }
 
-
-    public IntBuffer asIntBuffer() {
+    @Override
+    public final IntBuffer asIntBuffer() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
@@ -550,38 +584,42 @@
         assert (off <= lim);
         int rem = (off <= lim ? lim - off : 0);
         int size = rem >> 2;
-        return (IntBuffer) (new ByteBufferAsIntBuffer(this,
+        return new ByteBufferAsIntBuffer(this,
                 -1,
                 0,
                 size,
                 size,
                 off,
-                order()));
+                order());
     }
 
     private long getLong(long a) {
         return Memory.peekLong(a, !nativeByteOrder);
     }
 
-    public long getLong() {
+    @Override
+    public final long getLong() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
         return getLong(ix(nextGetIndex(SizeOf.LONG)));
     }
 
-    public long getLong(int i) {
+    @Override
+    public final long getLong(int i) {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
         return getLong(ix(checkIndex(i, SizeOf.LONG)));
     }
 
-    long getLongUnchecked(int i) {
+    @Override
+    final long getLongUnchecked(int i) {
         return getLong(ix(i));
     }
 
-    void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
+    @Override
+    final void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
         Memory.peekLongArray(ix(pos),
                 dst, dstOffset, length, !nativeByteOrder);
     }
@@ -591,7 +629,8 @@
         return this;
     }
 
-    public ByteBuffer putLong(long x) {
+    @Override
+    public final ByteBuffer putLong(long x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -602,7 +641,8 @@
         return this;
     }
 
-    public ByteBuffer putLong(int i, long x) {
+    @Override
+    public final ByteBuffer putLong(int i, long x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -613,17 +653,19 @@
         return this;
     }
 
-    void putLongUnchecked(int i, long x) {
+    @Override
+    final void putLongUnchecked(int i, long x) {
         putLong(ix(i), x);
     }
 
-    void putUnchecked(int pos, long[] src, int srcOffset, int length) {
+    @Override
+    final void putUnchecked(int pos, long[] src, int srcOffset, int length) {
         Memory.pokeLongArray(ix(pos),
                 src, srcOffset, length, !nativeByteOrder);
     }
 
-
-    public LongBuffer asLongBuffer() {
+    @Override
+    public final LongBuffer asLongBuffer() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
@@ -632,13 +674,13 @@
         assert (off <= lim);
         int rem = (off <= lim ? lim - off : 0);
         int size = rem >> 3;
-        return (LongBuffer) (new ByteBufferAsLongBuffer(this,
+        return new ByteBufferAsLongBuffer(this,
                 -1,
                 0,
                 size,
                 size,
                 off,
-                order()));
+                order());
     }
 
     private float getFloat(long a) {
@@ -646,25 +688,29 @@
         return Float.intBitsToFloat(x);
     }
 
-    public float getFloat() {
+    @Override
+    public final float getFloat() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
         return getFloat(ix(nextGetIndex(SizeOf.FLOAT)));
     }
 
-    public float getFloat(int i) {
+    @Override
+    public final float getFloat(int i) {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
         return getFloat(ix(checkIndex(i, SizeOf.FLOAT)));
     }
 
-    float getFloatUnchecked(int i) {
+    @Override
+    final float getFloatUnchecked(int i) {
         return getFloat(ix(i));
     }
 
-    void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
+    @Override
+    final void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
         Memory.peekFloatArray(ix(pos),
                 dst, dstOffset, length, !nativeByteOrder);
     }
@@ -675,7 +721,8 @@
         return this;
     }
 
-    public ByteBuffer putFloat(float x) {
+    @Override
+    public final ByteBuffer putFloat(float x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -686,7 +733,8 @@
         return this;
     }
 
-    public ByteBuffer putFloat(int i, float x) {
+    @Override
+    public final ByteBuffer putFloat(int i, float x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -697,16 +745,19 @@
         return this;
     }
 
-    void putFloatUnchecked(int i, float x) {
+    @Override
+    final void putFloatUnchecked(int i, float x) {
         putFloat(ix(i), x);
     }
 
-    void putUnchecked(int pos, float[] src, int srcOffset, int length) {
+    @Override
+    final void putUnchecked(int pos, float[] src, int srcOffset, int length) {
         Memory.pokeFloatArray(ix(pos),
                 src, srcOffset, length, !nativeByteOrder);
     }
 
-    public FloatBuffer asFloatBuffer() {
+    @Override
+    public final FloatBuffer asFloatBuffer() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
@@ -715,13 +766,13 @@
         assert (off <= lim);
         int rem = (off <= lim ? lim - off : 0);
         int size = rem >> 2;
-        return (FloatBuffer) (new ByteBufferAsFloatBuffer(this,
+        return new ByteBufferAsFloatBuffer(this,
                 -1,
                 0,
                 size,
                 size,
                 off,
-                order()));
+                order());
     }
 
     private double getDouble(long a) {
@@ -729,25 +780,29 @@
         return Double.longBitsToDouble(x);
     }
 
-    public double getDouble() {
+    @Override
+    public final double getDouble() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
         return getDouble(ix(nextGetIndex(SizeOf.DOUBLE)));
     }
 
-    public double getDouble(int i) {
+    @Override
+    public final double getDouble(int i) {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
         return getDouble(ix(checkIndex(i, SizeOf.DOUBLE)));
     }
 
-    double getDoubleUnchecked(int i) {
+    @Override
+    final double getDoubleUnchecked(int i) {
         return getDouble(ix(i));
     }
 
-    void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
+    @Override
+    final void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
         Memory.peekDoubleArray(ix(pos),
                 dst, dstOffset, length, !nativeByteOrder);
     }
@@ -758,7 +813,8 @@
         return this;
     }
 
-    public ByteBuffer putDouble(double x) {
+    @Override
+    public final ByteBuffer putDouble(double x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -769,7 +825,8 @@
         return this;
     }
 
-    public ByteBuffer putDouble(int i, double x) {
+    @Override
+    public final ByteBuffer putDouble(int i, double x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
         }
@@ -780,16 +837,19 @@
         return this;
     }
 
-    void putDoubleUnchecked(int i, double x) {
+    @Override
+    final void putDoubleUnchecked(int i, double x) {
         putDouble(ix(i), x);
     }
 
-    void putUnchecked(int pos, double[] src, int srcOffset, int length) {
+    @Override
+    final void putUnchecked(int pos, double[] src, int srcOffset, int length) {
         Memory.pokeDoubleArray(ix(pos),
                 src, srcOffset, length, !nativeByteOrder);
     }
 
-    public DoubleBuffer asDoubleBuffer() {
+    @Override
+    public final DoubleBuffer asDoubleBuffer() {
         if (!memoryRef.isAccessible) {
             throw new IllegalStateException("buffer is inaccessible");
         }
@@ -799,20 +859,22 @@
         int rem = (off <= lim ? lim - off : 0);
 
         int size = rem >> 3;
-        return (DoubleBuffer) (new ByteBufferAsDoubleBuffer(this,
+        return new ByteBufferAsDoubleBuffer(this,
                 -1,
                 0,
                 size,
                 size,
                 off,
-                order()));
+                order());
     }
 
-    public boolean isAccessible() {
+    @Override
+    public final boolean isAccessible() {
         return memoryRef.isAccessible;
     }
 
-    public void setAccessible(boolean value) {
+    @Override
+    public final void setAccessible(boolean value) {
         memoryRef.isAccessible = value;
     }
 }
diff --git a/ojluni/src/main/java/java/nio/HeapByteBuffer.java b/ojluni/src/main/java/java/nio/HeapByteBuffer.java
index 7e4ec7e..46666382 100644
--- a/ojluni/src/main/java/java/nio/HeapByteBuffer.java
+++ b/ojluni/src/main/java/java/nio/HeapByteBuffer.java
@@ -34,7 +34,7 @@
  * A read/write HeapByteBuffer.
  */
 
-class HeapByteBuffer extends ByteBuffer {
+final class HeapByteBuffer extends ByteBuffer {
 
     // For speed these fields are actually declared in X-Buffer;
     // these declarations are here as documentation
@@ -50,7 +50,7 @@
     }
 
 
-    HeapByteBuffer(int cap, int lim, boolean isReadOnly) {            // package-private
+    private HeapByteBuffer(int cap, int lim, boolean isReadOnly) {
         super(-1, 0, lim, cap, new byte[cap], 0);
         this.isReadOnly = isReadOnly;
     }
@@ -59,24 +59,18 @@
         this(buf, off, len, false);
     }
 
-    HeapByteBuffer(byte[] buf, int off, int len, boolean isReadOnly) { // package-private
+    private HeapByteBuffer(byte[] buf, int off, int len, boolean isReadOnly) {
         super(-1, off, off + len, buf.length, buf, 0);
         this.isReadOnly = isReadOnly;
     }
 
-    protected HeapByteBuffer(byte[] buf,
-                             int mark, int pos, int lim, int cap,
-                             int off) {
-        this(buf, mark, pos, lim, cap, off, false);
-    }
-
-    protected HeapByteBuffer(byte[] buf,
-                             int mark, int pos, int lim, int cap,
-                             int off, boolean 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,
@@ -87,6 +81,7 @@
                 isReadOnly);
     }
 
+    @Override
     public ByteBuffer duplicate() {
         return new HeapByteBuffer(hb,
                 markValue(),
@@ -97,6 +92,7 @@
                 isReadOnly);
     }
 
+    @Override
     public ByteBuffer asReadOnlyBuffer() {
         return new HeapByteBuffer(hb,
                 this.markValue(),
@@ -110,14 +106,17 @@
         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())
@@ -127,14 +126,17 @@
         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();
@@ -143,6 +145,7 @@
         return this;
     }
 
+    @Override
     public ByteBuffer put(int i, byte x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
@@ -151,6 +154,7 @@
         return this;
     }
 
+    @Override
     public ByteBuffer put(byte[] src, int offset, int length) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
@@ -163,6 +167,7 @@
         return this;
     }
 
+    @Override
     public ByteBuffer compact() {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
@@ -174,10 +179,12 @@
         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();
@@ -185,22 +192,27 @@
         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();
@@ -209,6 +221,7 @@
         return this;
     }
 
+    @Override
     public ByteBuffer putChar(int i, char x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
@@ -217,42 +230,50 @@
         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 (CharBuffer) (new ByteBufferAsCharBuffer(this,
+        return new ByteBufferAsCharBuffer(this,
                 -1,
                 0,
                 size,
                 size,
                 off,
-                order()));
+                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();
@@ -261,6 +282,7 @@
         return this;
     }
 
+    @Override
     public ByteBuffer putShort(int i, short x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
@@ -269,14 +291,17 @@
         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();
@@ -289,22 +314,27 @@
                 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();
@@ -313,6 +343,7 @@
         return this;
     }
 
+    @Override
     public ByteBuffer putInt(int i, int x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
@@ -321,43 +352,51 @@
         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 (IntBuffer) (new ByteBufferAsIntBuffer(this,
+        return new ByteBufferAsIntBuffer(this,
                 -1,
                 0,
                 size,
                 size,
                 off,
-                order()));
+                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();
@@ -366,6 +405,7 @@
         return this;
     }
 
+    @Override
     public ByteBuffer putLong(int i, long x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
@@ -374,42 +414,50 @@
         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 (LongBuffer) (new ByteBufferAsLongBuffer(this,
+        return new ByteBufferAsLongBuffer(this,
                 -1,
                 0,
                 size,
                 size,
                 off,
-                order()));
+                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();
@@ -418,6 +466,7 @@
         return this;
     }
 
+    @Override
     public ByteBuffer putFloat(int i, float x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
@@ -426,42 +475,50 @@
         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 (FloatBuffer) (new ByteBufferAsFloatBuffer(this,
+        return new ByteBufferAsFloatBuffer(this,
                 -1,
                 0,
                 size,
                 size,
                 off,
-                order()));
+                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();
@@ -470,6 +527,7 @@
         return this;
     }
 
+    @Override
     public ByteBuffer putDouble(int i, double x) {
         if (isReadOnly) {
             throw new ReadOnlyBufferException();
@@ -478,23 +536,26 @@
         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 (DoubleBuffer) (new ByteBufferAsDoubleBuffer(this,
+        return new ByteBufferAsDoubleBuffer(this,
                 -1,
                 0,
                 size,
                 size,
                 off,
-                order()));
+                order());
     }
 }