Merge "Add Java 6's java.io.Console." into dalvik-dev
diff --git a/json/src/main/java/org/json/JSONException.java b/json/src/main/java/org/json/JSONException.java
index e1efd9f..ddd1016 100644
--- a/json/src/main/java/org/json/JSONException.java
+++ b/json/src/main/java/org/json/JSONException.java
@@ -23,8 +23,8 @@
  * <ul>
  *   <li>Attempts to parse or construct malformed documents
  *   <li>Use of null as a name
- *   <li>Use of numeric types not available to JSON, such as {@link Double#NaN
- *       NaN} or {@link Double#POSITIVE_INFINITY infinity}.
+ *   <li>Use of numeric types not available to JSON, such as {@link
+ *       Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
  *   <li>Lookups using an out of range index or nonexistant name
  *   <li>Type mismatches on lookups
  * </ul>
diff --git a/json/src/main/java/org/json/JSONStringer.java b/json/src/main/java/org/json/JSONStringer.java
index fb60bd1..fa22397 100644
--- a/json/src/main/java/org/json/JSONStringer.java
+++ b/json/src/main/java/org/json/JSONStringer.java
@@ -23,7 +23,40 @@
 // Note: this class was written without inspecting the non-free org.json sourcecode.
 
 /**
+ * Implements {@link JSONObject#toString()} and {@link JSONArray#toString}. Most
+ * application developers should use those methods directly and disregard this
+ * API. For example:<pre>
+ * JSONObject object = ...
+ * String json = object.toString();</pre>
  *
+ * <p>Stringers only encode well-formed JSON strings. In particular:
+ * <ul>
+ *   <li>The stringer must have exactly one top-level array or object.
+ *   <li>Lexical scopes must be balanced: every call to {@link #array()} must
+ *       have a matching call to {@link #endArray()} and every call to {@link
+ *       #object()} must have a matching call to {@link #endObject()}.
+ *   <li>Arrays may not contain keys (property names).
+ *   <li>Objects must alternate keys (property names) and values.
+ *   <li>Values are inserted with either literal {@link #value(Object) value}
+ *       calls, or by nesting arrays or objects.
+ * </ul>
+ * Calls that would result in a malformed JSON string will fail with a
+ * {@link JSONException}.
+ *
+ * <p>This class provides no facility for pretty-printing (ie. indenting)
+ * output. To encode indented output, use {@link JSONObject#toString(int)} or
+ * {@link JSONArray#toString(int)}.
+ *
+ * <p>Some implementations of the API support at most 20 levels of nesting.
+ * Attempts to create more than 20 levels of nesting may fail with a {@link
+ * JSONException}.
+ *
+ * <p>Each stringer may be used to encode a single top level value. Instances of
+ * this class are not thread safe. Although this class is nonfinal, it was not
+ * designed for inheritance and should not be subclassed. In particular,
+ * self-use by overridable methods is not specified. See <i>Effective Java</i>
+ * Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * information.
  */
 public class JSONStringer {
 
@@ -96,18 +129,40 @@
         indent = new String(indentChars);
     }
 
+    /**
+     * Begins encoding a new array. Each call to this method must be paired with
+     * a call to {@link #endArray()}.
+     *
+     * @return this stringer.
+     */
     public JSONStringer array() throws JSONException {
         return open(Scope.EMPTY_ARRAY, "[");
     }
 
+    /**
+     * Ends encoding the current array.
+     *
+     * @return this stringer.
+     */
     public JSONStringer endArray() throws JSONException {
         return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]");
     }
 
+    /**
+     * Begins encoding a new object. Each call to this method must be paired
+     * with a call to {@link #endObject()}.
+     *
+     * @return this stringer.
+     */
     public JSONStringer object() throws JSONException {
         return open(Scope.EMPTY_OBJECT, "{");
     }
 
+    /**
+     * Ends encoding the current object.
+     *
+     * @return this stringer.
+     */
     public JSONStringer endObject() throws JSONException {
         return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}");
     }
@@ -161,6 +216,14 @@
         stack.set(stack.size() - 1, topOfStack);
     }
 
+    /**
+     * Encodes {@code value}.
+     *
+     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     *     Integer, Long, Double or null. May not be {@link Double#isNaN() NaNs}
+     *     or {@link Double#isInfinite() infinities}.
+     * @return this stringer.
+     */
     public JSONStringer value(Object value) throws JSONException {
         if (stack.isEmpty()) {
             throw new JSONException("Nesting problem");
@@ -192,6 +255,11 @@
         return this;
     }
 
+    /**
+     * Encodes {@code value} to this stringer.
+     *
+     * @return this stringer.
+     */
     public JSONStringer value(boolean value) throws JSONException {
         if (stack.isEmpty()) {
             throw new JSONException("Nesting problem");
@@ -201,6 +269,13 @@
         return this;
     }
 
+    /**
+     * Encodes {@code value} to this stringer.
+     *
+     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+     *     {@link Double#isInfinite() infinities}.
+     * @return this stringer.
+     */
     public JSONStringer value(double value) throws JSONException {
         if (stack.isEmpty()) {
             throw new JSONException("Nesting problem");
@@ -210,6 +285,11 @@
         return this;
     }
 
+    /**
+     * Encodes {@code value} to this stringer.
+     *
+     * @return this stringer.
+     */
     public JSONStringer value(long value) throws JSONException {
         if (stack.isEmpty()) {
             throw new JSONException("Nesting problem");
@@ -281,6 +361,12 @@
         }
     }
 
+    /**
+     * Encodes the key (property name) to this stringer.
+     *
+     * @param name the name of the forthcoming value. May not be null.
+     * @return this stringer.
+     */
     public JSONStringer key(String name) throws JSONException {
         if (name == null) {
             throw new JSONException("Names must be non-null");
@@ -331,8 +417,14 @@
     }
 
     /**
-     * Although it contradicts the general contract of {@link Object#toString},
-     * this method returns null if the stringer contains no data.
+     * Returns the encoded JSON string.
+     *
+     * <p>If invoked with unterminated arrays or unclosed objects, this method's
+     * return value is undefined.
+     *
+     * <p><strong>Warning:</strong> although it contradicts the general contract
+     * of {@link Object#toString}, this method returns null if the stringer
+     * contains no data.
      */
     @Override public String toString() {
         return out.length() == 0 ? null : out.toString();
diff --git a/json/src/main/java/org/json/JSONTokener.java b/json/src/main/java/org/json/JSONTokener.java
index e249c74..3b0f593 100644
--- a/json/src/main/java/org/json/JSONTokener.java
+++ b/json/src/main/java/org/json/JSONTokener.java
@@ -19,7 +19,28 @@
 // Note: this class was written without inspecting the non-free org.json sourcecode.
 
 /**
+ * Parses a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>)
+ * encoded string into the corresponding object. Most clients of
+ * this class will use only need the {@link #JSONTokener(String) constructor}
+ * and {@link #nextValue} method. Example usage: <pre>
+ * String json = "{"
+ *         + "  \"query\": \"Pizza\", "
+ *         + "  \"locations\": [ 94043, 90210 ] "
+ *         + "}";
  *
+ * JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
+ * String query = object.getString("query");
+ * JSONArray locations = object.getJSONArray("locations");</pre>
+ *
+ * <p>This parser is lenient. A successful parse does not necessarily indicate
+ * that the input string is valid JSON.
+ *
+ * <p>Each tokener may be used to parse a single JSON string. Instances of this
+ * class are not thread safe. Although this class is nonfinal, it was not
+ * designed for inheritance and should not be subclassed. In particular,
+ * self-use by overridable methods is not specified. See <i>Effective Java</i>
+ * Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * information.
  */
 public class JSONTokener {
 
@@ -32,10 +53,22 @@
      */
     private int pos;
 
+    /**
+     * @param in JSON encoded string. Null is not permitted and will yield a
+     *     tokener that throws {@code NullPointerExceptions} when methods are
+     *     called.
+     */
     public JSONTokener(String in) {
         this.in = in;
     }
 
+    /**
+     * Returns the next value from the input.
+     *
+     * @return a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     *     Integer, Long, Double or {@link JSONObject#NULL}.
+     * @throws JSONException if the input is malformed.
+     */
     public Object nextValue() throws JSONException {
         int c = nextCleanInternal();
         switch (c) {
@@ -121,8 +154,12 @@
     }
 
     /**
+     * Returns the string up to but not including {@code quote}, unescaping any
+     * character escape sequences encountered along the way. The opening quote
+     * should have already been read. This consumes the closing quote, but does
+     * not include it in the returned string.
      *
-     *
+     * @param quote either ' or ".
      * @throws NumberFormatException if any unicode escape sequences are
      *     malformed.
      */
@@ -264,9 +301,8 @@
     }
 
     /**
-     * Returns text from the current position until the first of any of the
-     * given characters or a newline character, excluding that character. The
-     * position is advanced to the excluded character.
+     * Returns the string up to but not including any of the given characters or
+     * a newline character. This does not consume the excluded character.
      */
     private String nextToInternal(String excluded) {
         int start = pos;
@@ -378,10 +414,17 @@
         }
     }
 
-    public JSONException syntaxError(String text) {
-        return new JSONException(text + this);
+    /**
+     * Returns an exception containing the given message plus the current
+     * position and the entire input string.
+     */
+    public JSONException syntaxError(String message) {
+        return new JSONException(message + this);
     }
 
+    /**
+     * Returns the current position and the entire input string.
+     */
     @Override public String toString() {
         // consistent with the original implementation
         return " at character " + pos + " of " + in;
@@ -395,14 +438,26 @@
      * implementation and may be used by some clients.
      */
 
+    /**
+     * Returns true until the input has been exhausted.
+     */
     public boolean more() {
         return pos < in.length();
     }
 
+    /**
+     * Returns the next available character, or the null character '\0' if all
+     * input has been exhausted. The return value of this method is ambiguous
+     * for JSON strings that contain the character '\0'.
+     */
     public char next() {
         return pos < in.length() ? in.charAt(pos++) : '\0';
     }
 
+    /**
+     * Returns the next available character if it equals {@code c}. Otherwise an
+     * exception is thrown.
+     */
     public char next(char c) throws JSONException {
         char result = next();
         if (result != c) {
@@ -411,13 +466,27 @@
         return result;
     }
 
+    /**
+     * Returns the next character that is not whitespace and does not belong to
+     * a comment. If the input is exhausted before such a character can be
+     * found, the null character '\0' is returned. The return value of this
+     * method is ambiguous for JSON strings that contain the character '\0'.
+     */
     public char nextClean() throws JSONException {
         int nextCleanInt = nextCleanInternal();
         return nextCleanInt == -1 ? '\0' : (char) nextCleanInt;
     }
 
     /**
-     * TODO: note about how this method returns a substring, and could cause a memory leak
+     * Returns the next {@code length} characters of the input.
+     *
+     * <p>The returned string shares its backing character array with this
+     * tokener's input string. If a reference to the returned string may be held
+     * indefinitely, you should use {@code new String(result)} to copy it first
+     * to avoid memory leaks.
+     *
+     * @throws JSONException if the remaining input is not long enough to
+     *     satisfy this request.
      */
     public String next(int length) throws JSONException {
         if (pos + length > in.length()) {
@@ -429,7 +498,20 @@
     }
 
     /**
-     * TODO: note about how this method returns a substring, and could cause a memory leak
+     * Returns the {@link String#trim trimmed} string holding the characters up
+     * to but not including the first of:
+     * <ul>
+     *   <li>any character in {@code excluded}
+     *   <li>a newline character '\n'
+     *   <li>a carriage return '\r'
+     * </ul>
+     *
+     * <p>The returned string shares its backing character array with this
+     * tokener's input string. If a reference to the returned string may be held
+     * indefinitely, you should use {@code new String(result)} to copy it first
+     * to avoid memory leaks.
+     *
+     * @return a possibly-empty string
      */
     public String nextTo(String excluded) {
         if (excluded == null) {
@@ -439,33 +521,54 @@
     }
 
     /**
-     * TODO: note about how this method returns a substring, and could cause a memory leak
+     * Equivalent to {@code nextTo(String.valueOf(excluded))}.
      */
     public String nextTo(char excluded) {
         return nextToInternal(String.valueOf(excluded)).trim();
     }
 
+    /**
+     * Advances past all input up to and including the next occurrence of
+     * {@code thru}. If the remaining input doesn't contain {@code thru}, the
+     * input is exhausted.
+     */
     public void skipPast(String thru) {
         int thruStart = in.indexOf(thru, pos);
         pos = thruStart == -1 ? in.length() : (thruStart + thru.length());
     }
 
+    /**
+     * Advances past all input up to but not including the next occurrence of
+     * {@code to}. If the remaining input doesn't contain {@code to}, the input
+     * is unchanged.
+     */
     public char skipTo(char to) {
-        for (int i = pos, length = in.length(); i < length; i++) {
-            if (in.charAt(i) == to) {
-                pos = i;
-                return to;
-            }
+        int index = in.indexOf(to, pos);
+        if (index != -1) {
+            pos = index;
+            return to;
+        } else {
+            return '\0';
         }
-        return '\0';
     }
 
+    /**
+     * Unreads the most recent character of input. If no input characters have
+     * been read, the input is unchanged.
+     */
     public void back() {
         if (--pos == -1) {
             pos = 0;
         }
     }
 
+    /**
+     * Returns the integer [0..15] value for the given hex character, or -1
+     * for non-hex input.
+     *
+     * @param hex a character in the ranges [0-9], [A-F] or [a-f]. Any other
+     *     character will yield a -1 result.
+     */
     public static int dehexchar(char hex) {
         if (hex >= '0' && hex <= '9') {
             return hex - '0';
diff --git a/luni/src/main/java/java/net/Socket.java b/luni/src/main/java/java/net/Socket.java
index 2962b62..208bc09 100644
--- a/luni/src/main/java/java/net/Socket.java
+++ b/luni/src/main/java/java/net/Socket.java
@@ -61,14 +61,8 @@
 
     private Proxy proxy;
 
-    static final int MULTICAST_IF = 1;
-
-    static final int MULTICAST_TTL = 2;
-
     static final int TCP_NODELAY = 4;
 
-    static final int FLAG_SHUTDOWN = 8;
-
     static private Logger logger;
 
     static private Logger getLogger() {
diff --git a/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java b/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
index e2ea82c..7721cbb 100644
--- a/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
+++ b/luni/src/main/java/org/apache/harmony/luni/net/PlainDatagramSocketImpl.java
@@ -44,14 +44,8 @@
  */
 public class PlainDatagramSocketImpl extends DatagramSocketImpl {
 
-    static final int MULTICAST_IF = 1;
-
-    static final int MULTICAST_TTL = 2;
-
     static final int TCP_NODELAY = 4;
 
-    static final int FLAG_SHUTDOWN = 8;
-
     private final static int SO_BROADCAST = 32;
 
     final static int IP_MULTICAST_ADD = 19;
diff --git a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
index 876ad78..8d7ce58 100644
--- a/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
+++ b/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
@@ -17,9 +17,6 @@
 
 // BEGIN android-note
 // Address length was changed from long to int for performance reasons.
-// Harmony implements INetworkSystem's methods with native methods; Android
-// implements them with Java that call through to native wrappers.
-// TODO: change the native code to eliminate the wrappers
 // END android-note
 
 package org.apache.harmony.luni.platform;
@@ -44,152 +41,56 @@
     private static final int ERRORCODE_SOCKET_TIMEOUT = -209;
     private static final int ERRORCODE_SOCKET_INTERRUPTED = -208;
 
-    private static final int INETADDR_REACHABLE = 0;
-
-    // private static boolean isNetworkInited = false; android-removed
-
     private static OSNetworkSystem singleton = new OSNetworkSystem();
 
-    /**
-     * Answers the unique instance of the OSNetworkSystem.
-     *
-     * @return the network system interface instance
-     */
     public static OSNetworkSystem getOSNetworkSystem() {
         return singleton;
     }
 
-    // Can not be instantiated.
     private OSNetworkSystem() {
-        super();
     }
 
-    public void accept(FileDescriptor fdServer, SocketImpl newSocket,
-            FileDescriptor fdnewSocket, int timeout) throws IOException {
-        acceptSocketImpl(fdServer, newSocket, fdnewSocket, timeout);
-    }
+    public native void accept(FileDescriptor fdServer, SocketImpl newSocket,
+            FileDescriptor fdnewSocket, int timeout) throws IOException;
 
-    static native void acceptSocketImpl(FileDescriptor fdServer,
-            SocketImpl newSocket, FileDescriptor fdnewSocket, int timeout)
-            throws IOException;
-
-    /**
-     * Associates a local address with a socket.
-     *
-     * @param fd
-     *            the socket descriptor
-     * @param port
-     *            the port number
-     * @param inetAddress
-     *            address to bind
-     * @throws SocketException
-     *             thrown if bind operation fails
-     */
-    public void bind(FileDescriptor fd, InetAddress inetAddress, int port) throws SocketException {
-        socketBindImpl(fd, port, inetAddress);
-    }
-
-    static native void socketBindImpl(FileDescriptor aFD, int port, InetAddress inetAddress) throws SocketException;
+    public native void bind(FileDescriptor fd, InetAddress inetAddress, int port) throws SocketException;
 
     // BEGIN android-changed (removed unused return value and useless native method)
     public void connect(FileDescriptor fd, int trafficClass,
             InetAddress inetAddress, int port) throws IOException{
-        connectStreamWithTimeoutSocketImpl(fd, port, 0, trafficClass, inetAddress);
+        connectStreamWithTimeoutSocket(fd, port, 0, trafficClass, inetAddress);
     }
     // END android-changed
 
-    public void connectDatagram(FileDescriptor fd, int port,
-            int trafficClass, InetAddress inetAddress) throws SocketException {
-        connectDatagramImpl2(fd, port, trafficClass, inetAddress);
-    }
-
-    static native void connectDatagramImpl2(FileDescriptor aFD, int port,
+    public native void connectDatagram(FileDescriptor fd, int port,
             int trafficClass, InetAddress inetAddress) throws SocketException;
 
-    public void connectStreamWithTimeoutSocket(FileDescriptor aFD,
-            int aport, int timeout, int trafficClass, InetAddress inetAddress)
-            throws IOException {
-        connectStreamWithTimeoutSocketImpl(aFD, aport, timeout, trafficClass,
-                inetAddress);
-    }
-
-    static native void connectStreamWithTimeoutSocketImpl(FileDescriptor aFD,
-            int aport, int timeout, int trafficClass, InetAddress inetAddress)
+    public native void connectStreamWithTimeoutSocket(FileDescriptor fd,
+            int port, int timeout, int trafficClass, InetAddress inetAddress)
             throws IOException;
 
-    // BEGIN android-changed
-    // changed context from Long to byte[]
-    public int connectWithTimeout(FileDescriptor fd, int timeout,
+    // BEGIN android-changed: changed context from Long to byte[]
+    public native int connectWithTimeout(FileDescriptor fd, int timeout,
             int trafficClass, InetAddress inetAddress, int port, int step,
-            byte[] context) throws IOException {
-        return connectWithTimeoutSocketImpl(fd, timeout, trafficClass,
-                inetAddress, port, step, context);
-    }
-
-    static native int connectWithTimeoutSocketImpl(FileDescriptor aFD,
-            int timeout, int trafficClass, InetAddress hostname, int port, int step,
-            byte[] context);
+            byte[] context) throws IOException;
     // END android-changed
 
-    public void createDatagramSocket(FileDescriptor fd,
-            boolean preferIPv4Stack) throws SocketException {
-        createDatagramSocketImpl(fd, preferIPv4Stack);
-    }
-
-    /*
-    * Allocate a datagram socket in the IP stack. The socket is associated with
-    * the <code>aFD</code>.
-    *
-    * @param aFD the FileDescriptor to associate with the socket @param
-    * preferIPv4Stack IP stack preference if underlying platform is V4/V6
-    * @exception SocketException upon an allocation error
-    */
-    static native void createDatagramSocketImpl(FileDescriptor aFD,
-            boolean preferIPv4Stack) throws SocketException;
-
-    public void createServerStreamSocket(FileDescriptor fd,
-            boolean preferIPv4Stack) throws SocketException {
-        createServerStreamSocketImpl(fd, preferIPv4Stack);
-    }
-
-    /*
-     * Answer the result of attempting to create a server stream socket in the
-     * IP stack. Any special options required for server sockets will be set by
-     * this method.
-     *
-     * @param aFD the socket FileDescriptor @param preferIPv4Stack if use IPV4
-     * @exception SocketException if an error occurs while creating the socket
-     */
-    static native void createServerStreamSocketImpl(FileDescriptor aFD,
-            boolean preferIPv4Stack) throws SocketException;
-
-    public void createStreamSocket(FileDescriptor fd,
-            boolean preferIPv4Stack) throws SocketException {
-        createStreamSocketImpl(fd, preferIPv4Stack);
-    }
-
-    static native void createStreamSocketImpl(FileDescriptor aFD,
-            boolean preferIPv4Stack) throws SocketException;
-
-    /**
-     * Disconnect the socket to a port and address
-     *a
-     * @param fd
-     *            the FileDescriptor associated with the socket
-     *
-     * @throws SocketException
-     *             if the disconnect fails
-     */
-    public void disconnectDatagram(FileDescriptor fd)
-            throws SocketException {
-        disconnectDatagramImpl(fd);
-    }
-
-    static native void disconnectDatagramImpl(FileDescriptor aFD)
+    // TODO: preferIPv4Stack is ignored.
+    public native void createDatagramSocket(FileDescriptor fd, boolean preferIPv4Stack)
             throws SocketException;
 
-    public InetAddress getHostByAddr(byte[] ipAddress)
-            throws UnknownHostException {
+    // TODO: preferIPv4Stack is ignored.
+    public native void createServerStreamSocket(FileDescriptor fd, boolean preferIPv4Stack)
+            throws SocketException;
+
+    // TODO: preferIPv4Stack is ignored.
+    public native void createStreamSocket(FileDescriptor fd, boolean preferIPv4Stack)
+            throws SocketException;
+
+    public native void disconnectDatagram(FileDescriptor fd) throws SocketException;
+
+    // TODO: rewrite callers to skip the middleman.
+    public InetAddress getHostByAddr(byte[] ipAddress) throws UnknownHostException {
         // BEGIN android-changed
         // Wallpaper fix for http://b/1851257. This  is a layering violation,
         // but at least the method has the right return type.
@@ -197,20 +98,11 @@
         return InetAddress.getByAddress(ipAddress);
         // END android-changed
     }
-    // BEGIN android-removed
-    // static native InetAddress getHostByAddrImpl(byte[] addr)
-    //         throws UnknownHostException;
-    // END android-removed
 
-    // BEGIN android-changed: remove useless IPv6 check.
+    // TODO: rewrite callers to skip the middleman.
     public InetAddress getHostByName(String hostName) throws UnknownHostException {
         return InetAddress.getByName(hostName);
     }
-    // END android-changed
-
-    // BEGIN android-removed
-    // static native InetAddress getHostByNameImpl(String addr) throws UnknownHostException;
-    // END android-removed
 
     public native String byteArrayToIpString(byte[] address)
             throws UnknownHostException;
@@ -218,111 +110,22 @@
     public native byte[] ipStringToByteArray(String address)
             throws UnknownHostException;
 
-    public InetAddress getSocketLocalAddress(FileDescriptor fd) {
-        return getSocketLocalAddressImpl(fd);
-    }
-    static native InetAddress getSocketLocalAddressImpl(FileDescriptor aFD);
+    public native InetAddress getSocketLocalAddress(FileDescriptor fd);
 
-    public int getSocketLocalPort(FileDescriptor aFD) {
-        return getSocketLocalPortImpl(aFD);
-    }
-    static native int getSocketLocalPortImpl(FileDescriptor aFD);
+    public native int getSocketLocalPort(FileDescriptor fd);
 
-    /**
-     * Query the IP stack for the nominated socket option.
-     *
-     * @param fd
-     *            the socket descriptor
-     * @param opt
-     *            the socket option type
-     * @return the nominated socket option value
-     * @throws SocketException
-     *             if the option is invalid
-     */
-    public Object getSocketOption(FileDescriptor fd, int opt)
-            throws SocketException {
-        return getSocketOptionImpl(fd, opt);
+    public native Object getSocketOption(FileDescriptor fd, int opt) throws SocketException;
+
+    public Channel inheritedChannel() {
+        // Android never has stdin/stdout connected to a socket.
+        return null;
     }
 
-    static native Object getSocketOptionImpl(FileDescriptor aFD, int opt)
-            throws SocketException;
+    public native void listenStreamSocket(FileDescriptor fd, int backlog) throws SocketException;
 
-    public native Channel inheritedChannel();
+    public native int peekDatagram(FileDescriptor fd, InetAddress sender, int receiveTimeout)
+            throws IOException;
 
-    // BEGIN android-removed
-    // public boolean isReachableByICMP(final InetAddress dest,
-    //         InetAddress source, final int ttl, final int timeout) {
-    //     return INETADDR_REACHABLE == isReachableByICMPImpl(dest, source, ttl,
-    //     timeout);
-    // }
-
-    // native int isReachableByICMPImpl(InetAddress addr,
-    //         InetAddress local, int ttl, int timeout);
-    // END android-removed
-
-    public void listenStreamSocket(FileDescriptor aFD, int backlog)
-            throws SocketException {
-        listenStreamSocketImpl(aFD, backlog);
-    }
-
-    static native void listenStreamSocketImpl(FileDescriptor aFD, int backlog)
-            throws SocketException;
-
-    // BEGIN android-removed: we do this statically, when we start the VM.
-    // public void oneTimeInitialization(boolean jcl_supports_ipv6);
-    // native void oneTimeInitializationImpl(boolean jcl_supports_ipv6);
-    // END android-removed
-
-    /**
-     * Peek on the socket, update <code>sender</code> address and answer the
-     * sender port.
-     *
-     * @param fd
-     *            the socket FileDescriptor
-     * @param sender
-     *            an InetAddress, to be updated with the sender's address
-     * @param receiveTimeout
-     *            the maximum length of time the socket should block, reading
-     * @return the sender port
-     *
-     * @throws IOException
-     *             upon an read error or timeout
-     */
-    public int peekDatagram(FileDescriptor fd, InetAddress sender,
-            int receiveTimeout) throws IOException {
-        return peekDatagramImpl(fd, sender, receiveTimeout);
-    }
-
-    static native int peekDatagramImpl(FileDescriptor aFD,
-            InetAddress sender, int receiveTimeout) throws IOException;
-
-    /**
-     * Read available bytes from the given file descriptor into a byte array.
-     *
-     * The read has an optional timeout parameter, which if non-zero is the
-     * length of time that the read will wait on a select call to see if any
-     * bytes are available for reading. If the timeout expires the method
-     * returns zero to indicate no bytes were read.
-     *
-     * @param fd
-     *            the socket file descriptor to read
-     * @param data
-     *            the byte array in which to store the results
-     * @param offset
-     *            the offset into the byte array in which to start reading the
-     *            results
-     * @param count
-     *            the maximum number of bytes to read
-     * @param timeout
-     *            the length of time to wait for the bytes, in milliseconds; or
-     *            zero to indicate no timeout applied. When there is no timeout
-     *            applied the read may block based upon socket options.
-     * @return number of bytes read, or zero if there were no bytes available
-     *         before the timeout occurred, or -1 to indicate the socket is
-     *         closed
-     * @throws IOException
-     *             if an underlying socket exception occurred
-     */
     public int read(FileDescriptor fd, byte[] data, int offset, int count,
             int timeout) throws IOException {
         // BEGIN android-added safety!
@@ -337,74 +140,14 @@
     static native int readSocketImpl(FileDescriptor aFD, byte[] data,
             int offset, int count, int timeout) throws IOException;
 
-    /**
-     * Read available bytes from the given file descriptor into OS memory at a
-     * given address.
-     *
-     * @param fd
-     *            the socket file descriptor to read
-     * @param address
-     *            the address of the memory in which to store the results
-     * @param count
-     *            the maximum number of bytes to read
-     * @param timeout
-     *            the length of time to wait for the bytes, in milliseconds
-     * @return number of bytes read, or zero if there were no bytes available
-     *         before the timeout occurred, or -1 to indicate the socket is
-     *         closed
-     * @throws IOException
-     *             if an underlying socket exception occurred
-     */
-    public int readDirect(FileDescriptor fd, int address, int count,
-            int timeout) throws IOException {
-        return readSocketDirectImpl(fd, address, count, timeout);
-    }
+    public native int readDirect(FileDescriptor fd, int address, int count, int timeout)
+            throws IOException;
 
-    static native int readSocketDirectImpl(FileDescriptor aFD, int address, int count,
-            int timeout) throws IOException;
-
-    /**
-     * Receive data on the socket into the specified buffer. The packet fields
-     * <code>data</code> & <code>length</code> are passed in addition to
-     * <code>packet</code> to eliminate the JNI field access calls.
-     *
-     * @param fd
-     *            the socket FileDescriptor
-     * @param packet
-     *            the DatagramPacket to receive into
-     * @param data
-     *            the data buffer of the packet
-     * @param offset
-     *            the offset in the data buffer
-     * @param length
-     *            the length of the data buffer in the packet
-     * @param receiveTimeout
-     *            the maximum length of time the socket should block, reading
-     * @param peek
-     *            indicates to peek at the data
-     * @return number of data received
-     * @throws IOException
-     *             upon an read error or timeout
-     */
-    public int receiveDatagram(FileDescriptor fd, DatagramPacket packet,
+    public native int receiveDatagram(FileDescriptor fd, DatagramPacket packet,
             byte[] data, int offset, int length, int receiveTimeout,
-            boolean peek) throws IOException {
-        return receiveDatagramImpl(fd, packet, data, offset, length,
-                receiveTimeout, peek);
-    }
+            boolean peek) throws IOException;
 
-    static native int receiveDatagramImpl(FileDescriptor aFD,
-            DatagramPacket packet, byte[] data, int offset, int length,
-            int receiveTimeout, boolean peek) throws IOException;
-
-    public int receiveDatagramDirect(FileDescriptor fd,
-            DatagramPacket packet, int address, int offset, int length,
-            int receiveTimeout, boolean peek) throws IOException {
-        return receiveDatagramDirectImpl(fd, packet, address, offset, length,
-                receiveTimeout, peek);
-    }
-
-    static native int receiveDatagramDirectImpl(FileDescriptor aFD,
+    public native int receiveDatagramDirect(FileDescriptor fd,
             DatagramPacket packet, int address, int offset, int length,
             int receiveTimeout, boolean peek) throws IOException;
 
@@ -431,28 +174,14 @@
      * @throws IOException
      *             upon an read error or timeout
      */
-    public int recvConnectedDatagram(FileDescriptor fd,
-            DatagramPacket packet, byte[] data, int offset, int length,
-            int receiveTimeout, boolean peek) throws IOException {
-        return recvConnectedDatagramImpl(fd, packet, data, offset, length,
-                receiveTimeout, peek);
-    }
-
-    static native int recvConnectedDatagramImpl(FileDescriptor aFD,
+    public native int recvConnectedDatagram(FileDescriptor fd,
             DatagramPacket packet, byte[] data, int offset, int length,
             int receiveTimeout, boolean peek) throws IOException;
 
-    public int recvConnectedDatagramDirect(FileDescriptor aFD, DatagramPacket packet, int address,
-            int offset, int length, int receiveTimeout, boolean peek)
-            throws IOException {
-        return recvConnectedDatagramDirectImpl(aFD, packet, address, offset, length, receiveTimeout, peek);
-    }
-
-    static native int recvConnectedDatagramDirectImpl(FileDescriptor aFD,
+    public native int recvConnectedDatagramDirect(FileDescriptor fd,
             DatagramPacket packet, int address, int offset, int length,
             int receiveTimeout, boolean peek) throws IOException;
 
-
     public boolean select(FileDescriptor[] readFDs, FileDescriptor[] writeFDs,
             int numReadable, int numWritable, long timeout, int[] flags)
             throws SocketException {
@@ -465,8 +194,6 @@
             return true;
         }
 
-        assert validateFDs(readFDs, writeFDs, numReadable, numWritable) : "Invalid file descriptor arrays"; //$NON-NLS-1$
-
         // BEGIN android-changed: handle errors in native code
         return selectImpl(readFDs, writeFDs, numReadable, numWritable, flags, timeout);
         // END android-changed
@@ -478,274 +205,48 @@
             long timeout);
     // END android-changed
 
-    /**
-     * Send the <code>data</code> to the address and port to which the was
-     * connected and <code>port</code>.
-     *
-     * @param fd
-     *            the socket FileDescriptor
-     * @param data
-     *            the data buffer of the packet
-     * @param offset
-     *            the offset in the data buffer
-     * @param length
-     *            the length of the data buffer in the packet
-     * @param bindToDevice
-     *            not used, current kept in case needed as was the case for
-     *            sendDatagramImpl
-     * @return number of data send
-     * @throws IOException
-     *             upon an read error or timeout
-     */
-    public int sendConnectedDatagram(FileDescriptor fd, byte[] data,
-            int offset, int length, boolean bindToDevice) throws IOException {
-        return sendConnectedDatagramImpl(fd, data, offset, length, bindToDevice);
-    }
+    // TODO: bindToDevice is unused.
+    public native int sendConnectedDatagram(FileDescriptor fd, byte[] data,
+            int offset, int length, boolean bindToDevice) throws IOException;
 
-    static native int sendConnectedDatagramImpl(FileDescriptor fd,
-            byte[] data, int offset, int length, boolean bindToDevice)
-            throws IOException;
-
-    public int sendConnectedDatagramDirect(FileDescriptor fd,
-            int address, int offset, int length, boolean bindToDevice)
-            throws IOException {
-        return sendConnectedDatagramDirectImpl(fd, address, offset, length, bindToDevice);
-    }
-    static native int sendConnectedDatagramDirectImpl(FileDescriptor fd,
+    // TODO: bindToDevice is unused.
+    public native int sendConnectedDatagramDirect(FileDescriptor fd,
             int address, int offset, int length, boolean bindToDevice)
             throws IOException;
 
-    /**
-     * Send the <code>data</code> to the nominated target <code>address</code>
-     * and <code>port</code>. These values are derived from the DatagramPacket
-     * to reduce the field calls within JNI.
-     *
-     * @param fd
-     *            the socket FileDescriptor
-     * @param data
-     *            the data buffer of the packet
-     * @param offset
-     *            the offset in the data buffer
-     * @param length
-     *            the length of the data buffer in the packet
-     * @param port
-     *            the target host port
-     * @param bindToDevice
-     *            if bind to device
-     * @param trafficClass
-     *            the traffic class to be used when the datagram is sent
-     * @param inetAddress
-     *            address to connect to.
-     * @return number of data send
-     *
-     * @throws IOException
-     *             upon an read error or timeout
-     */
-    public int sendDatagram(FileDescriptor fd, byte[] data, int offset,
-            int length, int port, boolean bindToDevice, int trafficClass,
-            InetAddress inetAddress) throws IOException {
-        return sendDatagramImpl(fd, data, offset, length, port, bindToDevice,
-                trafficClass, inetAddress);
-    }
-
-    static native int sendDatagramImpl(FileDescriptor fd, byte[] data, int offset,
+    // TODO: bindToDevice is unused.
+    public native int sendDatagram(FileDescriptor fd, byte[] data, int offset,
             int length, int port, boolean bindToDevice, int trafficClass,
             InetAddress inetAddress) throws IOException;
 
-    public int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
-            int length, int port, InetAddress inetAddress) throws IOException {
-        return sendDatagramImpl2(fd, data, offset, length, port, inetAddress);
-    }
+    public native int sendDatagram2(FileDescriptor fd, byte[] data, int offset,
+            int length, int port, InetAddress inetAddress) throws IOException;
 
-    static native int sendDatagramImpl2(FileDescriptor fd, byte[] data,
-            int offset, int length, int port, InetAddress inetAddress) throws IOException;
-
-
-    public int sendDatagramDirect(FileDescriptor fd, int address,
-            int offset, int length, int port, boolean bindToDevice,
-            int trafficClass, InetAddress inetAddress) throws IOException {
-        return sendDatagramDirectImpl(fd, address, offset, length, port, bindToDevice,
-                trafficClass, inetAddress);
-    }
-
-    static native int sendDatagramDirectImpl(FileDescriptor fd, int address,
+    // TODO: bindToDevice is unused.
+    public native int sendDatagramDirect(FileDescriptor fd, int address,
             int offset, int length, int port, boolean bindToDevice,
             int trafficClass, InetAddress inetAddress) throws IOException;
 
-    public void sendUrgentData(FileDescriptor fd, byte value) {
-        sendUrgentDataImpl(fd, value);
-    }
+    public native void sendUrgentData(FileDescriptor fd, byte value);
 
-    static native void sendUrgentDataImpl(FileDescriptor fd, byte value);
+    public native void setInetAddress(InetAddress sender, byte[] address);
 
-    public void setInetAddress(InetAddress sender, byte[] address) {
-        setInetAddressImpl(sender, address);
-    }
+    public native void setNonBlocking(FileDescriptor fd, boolean block) throws IOException;
 
-    native void setInetAddressImpl(InetAddress sender, byte[] address);
+    public native void setSocketOption(FileDescriptor fd, int opt, Object optVal)
+            throws SocketException;
 
-    public void setNonBlocking(FileDescriptor fd, boolean block)
-            throws IOException {
-        setNonBlockingImpl(fd, block);
-    }
+    public native void shutdownInput(FileDescriptor fd) throws IOException;
 
-    static native void setNonBlockingImpl(FileDescriptor aFD, boolean block);
+    public native void shutdownOutput(FileDescriptor fd) throws IOException;
 
-    /**
-     * Set the nominated socket option in the IP stack.
-     *
-     * @param aFD
-     *            the socket descriptor @param opt the option selector @param
-     *            optVal the nominated option value
-     *
-     * @throws SocketException
-     *             if the option is invalid or cannot be set
-     */
-    public void setSocketOption(FileDescriptor aFD, int opt,
-            Object optVal) throws SocketException {
-        setSocketOptionImpl(aFD, opt, optVal);
-    }
+    public native void socketClose(FileDescriptor fd) throws IOException;
 
-    static native void setSocketOptionImpl(FileDescriptor aFD, int opt,
-            Object optVal) throws SocketException;
+    public native boolean supportsUrgentData(FileDescriptor fd);
 
-    public void shutdownInput(FileDescriptor descriptor) throws IOException {
-        shutdownInputImpl(descriptor);
-    }
-
-    private native void shutdownInputImpl(FileDescriptor descriptor)
+    public native int write(FileDescriptor fd, byte[] data, int offset, int count)
             throws IOException;
 
-    public void shutdownOutput(FileDescriptor fd) throws IOException {
-        shutdownOutputImpl(fd);
-    }
-
-    private native void shutdownOutputImpl(FileDescriptor descriptor)
+    public native int writeDirect(FileDescriptor fd, int address, int offset, int count)
             throws IOException;
-    /**
-     * Close the socket in the IP stack.
-     *
-     * @param fd
-     *            the socket descriptor
-     */
-    public void socketClose(FileDescriptor fd) throws IOException {
-        socketCloseImpl(fd);
-    }
-
-    static native void socketCloseImpl(FileDescriptor fD);
-
-    public boolean supportsUrgentData(FileDescriptor fd) {
-        return supportsUrgentDataImpl(fd);
-    }
-
-    static native boolean supportsUrgentDataImpl(FileDescriptor fd);
-
-    /*
-    * Used to check if the file descriptor arrays are valid before passing them
-    * into the select native call.
-    */
-    private boolean validateFDs(FileDescriptor[] readFDs,
-            FileDescriptor[] writeFDs) {
-        for (FileDescriptor fd : readFDs) {
-            // Also checks fd not null
-            if (!fd.valid()) {
-                return false;
-            }
-        }
-        for (FileDescriptor fd : writeFDs) {
-            if (!fd.valid()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private boolean validateFDs(FileDescriptor[] readFDs,
-            FileDescriptor[] writeFDs, int countRead, int countWrite) {
-        for (int i = 0; i < countRead; ++i) {
-            // Also checks fd not null
-            if (!readFDs[i].valid()) {
-                return false;
-            }
-        }
-        for (int i = 0; i < countWrite; ++i) {
-            if (!writeFDs[i].valid()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Write bytes from a byte array to a socket.
-     *
-     * @param fd
-     *            the socket on which to write the bytes
-     * @param data
-     *            the array containing the bytes to be written
-     * @param offset
-     *            the offset in the byte array from which to take the bytes
-     * @param count
-     *            the maximum number of bytes to be written. Callers are trusted
-     *            not to send values of length+count that are larger than
-     *            data.length
-     * @return the actual number of bytes written, which will be between zero
-     *         and count
-     * @throws IOException
-     *             if there is an underlying socket problem
-     */
-    public int write(FileDescriptor fd, byte[] data, int offset, int count)
-            throws IOException {
-        return writeSocketImpl(fd, data, offset, count);
-    }
-
-    static native int writeSocketImpl(FileDescriptor fd, byte[] data, int offset,
-            int count) throws IOException;
-
-
-    /**
-     * Write bytes from the given address to a socket.
-     *
-     * @param fd
-     *            the socket on which to write the bytes
-     * @param address
-     *            the start address of the bytes to be written
-     * @param count
-     *            the maximum number of bytes to be written
-     * @return the actual number of bytes written, which will be between zero
-     *         and count
-     * @throws IOException
-     *             if there is an underlying socket problem
-     */
-    public int writeDirect(FileDescriptor fd, int address, int offset, int count)
-            throws IOException {
-        return writeSocketDirectImpl(fd, address, offset, count);
-    }
-
-    static native int writeSocketDirectImpl(FileDescriptor fd, int address, int offset, int count)
-            throws IOException;
-
-    // BEGIN android-removed
-    // /**
-    //  * Write given buffers to a socket. The given buffers is a Object array, the
-    //  * element of array must be direct buffer or a byte array to be written.
-    //  *
-    //  * @param fd
-    //  *            the socket on which to write the bytes
-    //  * @param buffers
-    //  *            the element of array must be direct buffer or a byte array to
-    //  *            be written
-    //  * @param offsets
-    //  *            the index of the first byte to be write
-    //  * @param counts
-    //  *            the maximum number of bytes to be written
-    //  * @param length
-    //  *            the size of buffer array
-    //  * @return the actual number of bytes written
-    //  * @throws IOException
-    //  *             if there is an underlying socket problem
-    //  */
-    // public native int writev(FileDescriptor fd, Object[] buffers,
-    //         int[] offsets, int[] counts, int length) throws IOException;
-    // END android-removed
 }
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
index a9b040e..f38f29c 100644
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
@@ -456,7 +456,7 @@
  *
  * @return a string with the textual representation of the address.
  */
-static jstring osNetworkSystem_byteArrayToIpString(JNIEnv* env, jclass,
+static jstring osNetworkSystem_byteArrayToIpString(JNIEnv* env, jobject,
         jbyteArray byteArray) {
     if (byteArray == NULL) {
         jniThrowNullPointerException(env, NULL);
@@ -510,7 +510,7 @@
  *
  * @throws UnknownHostException the IP address was invalid.
  */
-static jbyteArray osNetworkSystem_ipStringToByteArray(JNIEnv* env, jclass,
+static jbyteArray osNetworkSystem_ipStringToByteArray(JNIEnv* env, jobject,
         jstring javaString) {
     if (javaString == NULL) {
         jniThrowNullPointerException(env, NULL);
@@ -525,7 +525,7 @@
 
     // Accept IPv6 addresses (only) in square brackets for compatibility.
     if (ipString[0] == '[' && ipString[byteCount - 1] == ']' &&
-            index(ipString, ':') != NULL) {
+            strchr(ipString, ':') != NULL) {
         memmove(ipString, ipString + 1, byteCount - 2);
         ipString[byteCount - 2] = '\0';
     }
@@ -1486,22 +1486,16 @@
     return sock;
 }
 
-static void osNetworkSystem_createStreamSocketImpl(JNIEnv* env, jclass clazz,
-        jobject fileDescriptor, jboolean preferIPv4Stack) {
-    // LOGD("ENTER createSocketImpl");
+static void osNetworkSystem_createStreamSocket(JNIEnv* env, jobject, jobject fileDescriptor, jboolean) {
     createSocketFileDescriptor(env, fileDescriptor, SOCK_STREAM);
 }
 
-static void osNetworkSystem_createDatagramSocketImpl(JNIEnv* env, jclass clazz,
-        jobject fileDescriptor, jboolean preferIPv4Stack) {
-    // LOGD("ENTER createDatagramSocketImpl");
-    createSocketFileDescriptor(env, fileDescriptor, SOCK_DGRAM);
+static void osNetworkSystem_createDatagramSocket(JNIEnv* env, jobject, jobject fd, jboolean) {
+    createSocketFileDescriptor(env, fd, SOCK_DGRAM);
 }
 
-static jint osNetworkSystem_readSocketDirectImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_readDirect(JNIEnv* env, jobject,
         jobject fileDescriptor, jint address, jint count, jint timeout) {
-    // LOGD("ENTER readSocketDirectImpl");
-
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return 0;
@@ -1543,16 +1537,14 @@
     }
     jint address =
             static_cast<jint>(reinterpret_cast<uintptr_t>(bytes + offset));
-    int result = osNetworkSystem_readSocketDirectImpl(env, clazz,
+    int result = osNetworkSystem_readDirect(env, NULL,
             fileDescriptor, address, count, timeout);
     env->ReleaseByteArrayElements(byteArray, bytes, 0);
     return result;
 }
 
-static jint osNetworkSystem_writeSocketDirectImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_writeDirect(JNIEnv* env, jobject,
         jobject fileDescriptor, jint address, jint offset, jint count) {
-    // LOGD("ENTER writeSocketDirectImpl");
-
     if (count <= 0) {
         return 0;
     }
@@ -1577,25 +1569,21 @@
     return bytesSent;
 }
 
-static jint osNetworkSystem_writeSocketImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_write(JNIEnv* env, jobject,
         jobject fileDescriptor, jbyteArray byteArray, jint offset, jint count) {
-    // LOGD("ENTER writeSocketImpl");
-
     jbyte* bytes = env->GetByteArrayElements(byteArray, NULL);
     if (bytes == NULL) {
         return -1;
     }
     jint address = static_cast<jint>(reinterpret_cast<uintptr_t>(bytes));
-    int result = osNetworkSystem_writeSocketDirectImpl(env, clazz,
+    int result = osNetworkSystem_writeDirect(env, NULL,
             fileDescriptor, address, offset, count);
     env->ReleaseByteArrayElements(byteArray, bytes, 0);
     return result;
 }
 
-static void osNetworkSystem_setNonBlockingImpl(JNIEnv* env, jclass clazz,
+static void osNetworkSystem_setNonBlocking(JNIEnv* env, jobject,
         jobject fileDescriptor, jboolean nonblocking) {
-    // LOGD("ENTER setNonBlockingImpl");
-
     int handle;
     if (!jniGetFd(env, fileDescriptor, handle)) {
         return;
@@ -1608,11 +1596,9 @@
     }
 }
 
-static jint osNetworkSystem_connectWithTimeoutSocketImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor, jint timeout, jint trafficClass,
+static jint osNetworkSystem_connectWithTimeout(JNIEnv* env,
+        jobject, jobject fileDescriptor, jint timeout, jint trafficClass,
         jobject inetAddr, jint port, jint step, jbyteArray passContext) {
-    // LOGD("ENTER connectWithTimeoutSocketImpl");
-
     sockaddr_storage address;
     if (!inetAddressToSocketAddress(env, inetAddr, port, &address)) {
         return -1;
@@ -1657,11 +1643,9 @@
     return result;
 }
 
-static void osNetworkSystem_connectStreamWithTimeoutSocketImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor, jint remotePort, jint timeout,
+static void osNetworkSystem_connectStreamWithTimeoutSocket(JNIEnv* env,
+        jobject, jobject fileDescriptor, jint remotePort, jint timeout,
         jint trafficClass, jobject inetAddr) {
-    // LOGD("ENTER connectStreamWithTimeoutSocketImpl");
-
     int result = 0;
     struct sockaddr_storage address;
     jbyte *context = NULL;
@@ -1791,10 +1775,8 @@
     }
 }
 
-static void osNetworkSystem_socketBindImpl(JNIEnv* env, jclass clazz,
-        jobject fileDescriptor, jint port, jobject inetAddress) {
-    // LOGD("ENTER socketBindImpl");
-
+static void osNetworkSystem_bind(JNIEnv* env, jobject, jobject fileDescriptor,
+        jobject inetAddress, jint port) {
     sockaddr_storage socketAddress;
     if (!inetAddressToSocketAddress(env, inetAddress, port, &socketAddress)) {
         return;
@@ -1812,10 +1794,8 @@
     }
 }
 
-static void osNetworkSystem_listenStreamSocketImpl(JNIEnv* env, jclass clazz,
+static void osNetworkSystem_listenStreamSocket(JNIEnv* env, jobject,
         jobject fileDescriptor, jint backlog) {
-    // LOGD("ENTER listenStreamSocketImpl");
-
     int handle;
     if (!jniGetFd(env, fileDescriptor, handle)) {
         return;
@@ -1828,7 +1808,7 @@
     }
 }
 
-static void osNetworkSystem_acceptSocketImpl(JNIEnv* env, jclass,
+static void osNetworkSystem_accept(JNIEnv* env, jobject,
         jobject serverFileDescriptor,
         jobject newSocket, jobject clientFileDescriptor, jint timeout) {
     // LOGD("ENTER acceptSocketImpl");
@@ -1879,19 +1859,15 @@
     jniSetFileDescriptorOfFD(env, clientFileDescriptor, clientFd);
 }
 
-static jboolean osNetworkSystem_supportsUrgentDataImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor) {
-    // LOGD("ENTER supportsUrgentDataImpl");
-
+static jboolean osNetworkSystem_supportsUrgentData(JNIEnv* env,
+        jobject, jobject fileDescriptor) {
     // TODO(enh): do we really need to exclude the invalid file descriptor case?
     int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
     return (fd == -1) ? JNI_FALSE : JNI_TRUE;
 }
 
-static void osNetworkSystem_sendUrgentDataImpl(JNIEnv* env, jclass clazz,
+static void osNetworkSystem_sendUrgentData(JNIEnv* env, jobject,
         jobject fileDescriptor, jbyte value) {
-    // LOGD("ENTER sendUrgentDataImpl");
-
     int handle;
     if (!jniGetFd(env, fileDescriptor, handle)) {
         return;
@@ -1903,10 +1879,8 @@
     }
 }
 
-static void osNetworkSystem_connectDatagramImpl2(JNIEnv* env, jclass,
+static void osNetworkSystem_connectDatagram(JNIEnv* env, jobject,
         jobject fileDescriptor, jint port, jint trafficClass, jobject inetAddress) {
-    // LOGD("ENTER connectDatagramImpl2");
-
     sockaddr_storage sockAddr;
     if (!inetAddressToSocketAddress(env, inetAddress, port, &sockAddr)) {
         return;
@@ -1923,10 +1897,8 @@
     }
 }
 
-static void osNetworkSystem_disconnectDatagramImpl(JNIEnv* env, jclass,
+static void osNetworkSystem_disconnectDatagram(JNIEnv* env, jobject,
         jobject fileDescriptor) {
-    // LOGD("ENTER disconnectDatagramImpl");
-
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return;
@@ -1944,17 +1916,13 @@
     }
 }
 
-static void osNetworkSystem_setInetAddressImpl(JNIEnv* env, jobject,
+static void osNetworkSystem_setInetAddress(JNIEnv* env, jobject,
         jobject sender, jbyteArray address) {
-    // LOGD("ENTER setInetAddressImpl");
-    
     env->SetObjectField(sender, gCachedFields.iaddr_ipaddress, address);
 }
 
-static jint osNetworkSystem_peekDatagramImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_peekDatagram(JNIEnv* env, jobject,
         jobject fileDescriptor, jobject sender, jint receiveTimeout) {
-    // LOGD("ENTER peekDatagramImpl");
-
     int result = pollSelectWait(env, fileDescriptor, receiveTimeout);
     if (result < 0) {
         return 0;
@@ -1981,15 +1949,13 @@
     if (sender == NULL) {
         return -1;
     }
-    osNetworkSystem_setInetAddressImpl(env, NULL, sender, senderAddressArray);
+    osNetworkSystem_setInetAddress(env, NULL, sender, senderAddressArray);
     return getSocketAddressPort(&sockAddr);
 }
 
-static jint osNetworkSystem_receiveDatagramDirectImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_receiveDatagramDirect(JNIEnv* env, jobject,
         jobject fileDescriptor, jobject packet, jint address, jint offset,
         jint length, jint receiveTimeout, jboolean peek) {
-    // LOGD("ENTER receiveDatagramDirectImpl");
-
     int result = pollSelectWait(env, fileDescriptor, receiveTimeout);
     if (result < 0) {
         return 0;
@@ -2029,11 +1995,9 @@
     return (jint) actualLength;
 }
 
-static jint osNetworkSystem_receiveDatagramImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_receiveDatagram(JNIEnv* env, jobject,
         jobject fd, jobject packet, jbyteArray data, jint offset, jint length,
         jint receiveTimeout, jboolean peek) {
-    // LOGD("ENTER receiveDatagramImpl");
-
     int localLength = (length < 65536) ? length : 65536;
     jbyte *bytes = (jbyte*) malloc(localLength);
     if (bytes == NULL) {
@@ -2042,7 +2006,7 @@
         return 0;
     }
 
-    int actualLength = osNetworkSystem_receiveDatagramDirectImpl(env, clazz, fd,
+    int actualLength = osNetworkSystem_receiveDatagramDirect(env, NULL, fd,
             packet, (jint)bytes, 0, localLength, receiveTimeout, peek);
 
     if (actualLength > 0) {
@@ -2053,11 +2017,10 @@
     return actualLength;
 }
 
-static jint osNetworkSystem_recvConnectedDatagramDirectImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor, jobject packet,
+static jint osNetworkSystem_recvConnectedDatagramDirect(JNIEnv* env,
+        jobject, jobject fileDescriptor, jobject packet,
         jint address, jint offset, jint length,
         jint receiveTimeout, jboolean peek) {
-    // LOGD("ENTER receiveConnectedDatagramDirectImpl");
 
     int result = pollSelectWait(env, fileDescriptor, receiveTimeout);
     if (result < 0) {
@@ -2083,11 +2046,9 @@
     return actualLength;
 }
 
-static jint osNetworkSystem_recvConnectedDatagramImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_recvConnectedDatagram(JNIEnv* env, jobject,
         jobject fd, jobject packet, jbyteArray data, jint offset, jint length,
         jint receiveTimeout, jboolean peek) {
-    // LOGD("ENTER receiveConnectedDatagramImpl");
-
     int localLength = (length < 65536) ? length : 65536;
     jbyte *bytes = (jbyte*) malloc(localLength);
     if (bytes == NULL) {
@@ -2096,8 +2057,8 @@
         return 0;
     }
 
-    int actualLength = osNetworkSystem_recvConnectedDatagramDirectImpl(env,
-            clazz, fd, packet, (jint)bytes, 0, localLength,
+    int actualLength = osNetworkSystem_recvConnectedDatagramDirect(env,
+            NULL, fd, packet, (jint)bytes, 0, localLength,
             receiveTimeout, peek);
 
     if (actualLength > 0) {
@@ -2108,12 +2069,10 @@
     return actualLength;
 }
 
-static jint osNetworkSystem_sendDatagramDirectImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_sendDatagramDirect(JNIEnv* env, jobject,
         jobject fileDescriptor, jint address, jint offset, jint length,
         jint port,
         jboolean bindToDevice, jint trafficClass, jobject inetAddress) {
-    // LOGD("ENTER sendDatagramDirectImpl");
-
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return -1;
@@ -2139,26 +2098,21 @@
     return bytesSent;
 }
 
-static jint osNetworkSystem_sendDatagramImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_sendDatagram(JNIEnv* env, jobject,
         jobject fd, jbyteArray data, jint offset, jint length, jint port,
         jboolean bindToDevice, jint trafficClass, jobject inetAddress) {
-    // LOGD("ENTER sendDatagramImpl");
-
     jbyte *bytes = env->GetByteArrayElements(data, NULL);
-    int actualLength = osNetworkSystem_sendDatagramDirectImpl(env, clazz, fd,
+    int actualLength = osNetworkSystem_sendDatagramDirect(env, NULL, fd,
             (jint)bytes, offset, length, port, bindToDevice, trafficClass,
             inetAddress);
     env->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
-
     return actualLength;
 }
 
-static jint osNetworkSystem_sendConnectedDatagramDirectImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor,
+static jint osNetworkSystem_sendConnectedDatagramDirect(JNIEnv* env,
+        jobject, jobject fileDescriptor,
         jint address, jint offset, jint length,
         jboolean bindToDevice) {
-    // LOGD("ENTER sendConnectedDatagramDirectImpl");
-
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return 0;
@@ -2177,30 +2131,25 @@
     return bytesSent;
 }
 
-static jint osNetworkSystem_sendConnectedDatagramImpl(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_sendConnectedDatagram(JNIEnv* env, jobject,
         jobject fd, jbyteArray data, jint offset, jint length,
         jboolean bindToDevice) {
-    // LOGD("ENTER sendConnectedDatagramImpl");
-
     jbyte *bytes = env->GetByteArrayElements(data, NULL);
-    int actualLength = osNetworkSystem_sendConnectedDatagramDirectImpl(env,
-            clazz, fd, (jint)bytes, offset, length, bindToDevice);
+    int actualLength = osNetworkSystem_sendConnectedDatagramDirect(env,
+            NULL, fd, (jint)bytes, offset, length, bindToDevice);
     env->ReleaseByteArrayElements(data, bytes, JNI_ABORT);
 
     return actualLength;
 }
 
-static void osNetworkSystem_createServerStreamSocketImpl(JNIEnv* env,
-        jclass clazz, jobject fileDescriptor, jboolean preferIPv4Stack) {
-    // LOGD("ENTER createServerStreamSocketImpl");
-
-    int handle = createSocketFileDescriptor(env, fileDescriptor, SOCK_STREAM);
-    if (handle < 0) {
-        return;
+static void osNetworkSystem_createServerStreamSocket(JNIEnv* env, jobject,
+        jobject fileDescriptor, jboolean) {
+    int fd = createSocketFileDescriptor(env, fileDescriptor, SOCK_STREAM);
+    if (fd != -1) {
+        // TODO: we could actually do this in Java. (and check for errors!)
+        int value = 1;
+        setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int));
     }
-
-    int value = 1;
-    setsockopt(handle, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(int));
 }
 
 static void doShutdown(JNIEnv* env, jobject fileDescriptor, int how) {
@@ -2214,21 +2163,17 @@
     }
 }
 
-static void osNetworkSystem_shutdownInputImpl(JNIEnv* env, jobject,
-        jobject fileDescriptor) {
-    doShutdown(env, fileDescriptor, SHUT_RD);
+static void osNetworkSystem_shutdownInput(JNIEnv* env, jobject, jobject fd) {
+    doShutdown(env, fd, SHUT_RD);
 }
 
-static void osNetworkSystem_shutdownOutputImpl(JNIEnv* env, jobject,
-        jobject fileDescriptor) {
-    doShutdown(env, fileDescriptor, SHUT_WR);
+static void osNetworkSystem_shutdownOutput(JNIEnv* env, jobject, jobject fd) {
+    doShutdown(env, fd, SHUT_WR);
 }
 
-static jint osNetworkSystem_sendDatagramImpl2(JNIEnv* env, jclass clazz,
+static jint osNetworkSystem_sendDatagram2(JNIEnv* env, jobject,
         jobject fileDescriptor, jbyteArray data, jint offset, jint length,
         jint port, jobject inetAddress) {
-    // LOGD("ENTER sendDatagramImpl2");
-
     sockaddr_storage sockAddr;
     if (inetAddress != NULL) {
         if (!inetAddressToSocketAddress(env, inetAddress, port, &sockAddr)) {
@@ -2316,7 +2261,7 @@
     return true;
 }
 
-static jboolean osNetworkSystem_selectImpl(JNIEnv* env, jclass clazz,
+static jboolean osNetworkSystem_selectImpl(JNIEnv* env, jclass,
         jobjectArray readFDArray, jobjectArray writeFDArray, jint countReadC,
         jint countWriteC, jintArray outFlags, jlong timeoutMs) {
     // LOGD("ENTER selectImpl");
@@ -2367,10 +2312,8 @@
     return okay;
 }
 
-static jobject osNetworkSystem_getSocketLocalAddressImpl(JNIEnv* env,
-        jclass, jobject fileDescriptor) {
-    // LOGD("ENTER getSocketLocalAddressImpl");
-
+static jobject osNetworkSystem_getSocketLocalAddress(JNIEnv* env,
+        jobject, jobject fileDescriptor) {
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return NULL;
@@ -2390,10 +2333,8 @@
     return socketAddressToInetAddress(env, &addr);
 }
 
-static jint osNetworkSystem_getSocketLocalPortImpl(JNIEnv* env, jclass,
+static jint osNetworkSystem_getSocketLocalPort(JNIEnv* env, jobject,
         jobject fileDescriptor) {
-    // LOGD("ENTER getSocketLocalPortImpl");
-
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return 0;
@@ -2413,10 +2354,8 @@
     return getSocketAddressPort(&addr);
 }
 
-static jobject osNetworkSystem_getSocketOptionImpl(JNIEnv* env, jclass clazz,
+static jobject osNetworkSystem_getSocketOption(JNIEnv* env, jobject,
         jobject fileDescriptor, jint anOption) {
-    // LOGD("ENTER getSocketOptionImpl");
-
     int intValue = 0;
     socklen_t intSize = sizeof(int);
     int result;
@@ -2628,10 +2567,8 @@
 
 }
 
-static void osNetworkSystem_setSocketOptionImpl(JNIEnv* env, jclass clazz,
+static void osNetworkSystem_setSocketOption(JNIEnv* env, jobject,
         jobject fileDescriptor, jint anOption, jobject optVal) {
-    // LOGD("ENTER setSocketOptionImpl");
-
     int result;
     int intVal;
     socklen_t intSize = sizeof(int);
@@ -2886,10 +2823,7 @@
     }
 }
 
-static void osNetworkSystem_socketCloseImpl(JNIEnv* env, jclass clazz,
-        jobject fileDescriptor) {
-    // LOGD("ENTER socketCloseImpl");
-
+static void osNetworkSystem_socketClose(JNIEnv* env, jobject, jobject fileDescriptor) {
     int fd;
     if (!jniGetFd(env, fileDescriptor, fd)) {
         return;
@@ -2900,55 +2834,49 @@
     close(fd);
 }
 
-static jobject osNetworkSystem_inheritedChannel(JNIEnv* env, jobject obj) {
-    // Android never has stdin/stdout connected to a socket.
-    return NULL;
-}
-
 /*
  * JNI registration.
  */
 static JNINativeMethod gMethods[] = {
     /* name, signature, funcPtr */
-    { "createStreamSocketImpl",            "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createStreamSocketImpl             },
-    { "createDatagramSocketImpl",          "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createDatagramSocketImpl           },
-    { "readSocketImpl",                    "(Ljava/io/FileDescriptor;[BIII)I",                                         (void*) osNetworkSystem_readSocketImpl                     },
-    { "readSocketDirectImpl",              "(Ljava/io/FileDescriptor;III)I",                                           (void*) osNetworkSystem_readSocketDirectImpl               },
-    { "writeSocketImpl",                   "(Ljava/io/FileDescriptor;[BII)I",                                          (void*) osNetworkSystem_writeSocketImpl                    },
-    { "writeSocketDirectImpl",             "(Ljava/io/FileDescriptor;III)I",                                           (void*) osNetworkSystem_writeSocketDirectImpl              },
-    { "setNonBlockingImpl",                "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_setNonBlockingImpl                 },
-    { "connectWithTimeoutSocketImpl",      "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;II[B)I",                  (void*) osNetworkSystem_connectWithTimeoutSocketImpl       },
-    { "connectStreamWithTimeoutSocketImpl","(Ljava/io/FileDescriptor;IIILjava/net/InetAddress;)V",                     (void*) osNetworkSystem_connectStreamWithTimeoutSocketImpl },
-    { "socketBindImpl",                    "(Ljava/io/FileDescriptor;ILjava/net/InetAddress;)V",                       (void*) osNetworkSystem_socketBindImpl                     },
-    { "listenStreamSocketImpl",            "(Ljava/io/FileDescriptor;I)V",                                             (void*) osNetworkSystem_listenStreamSocketImpl             },
-    { "acceptSocketImpl",                  "(Ljava/io/FileDescriptor;Ljava/net/SocketImpl;Ljava/io/FileDescriptor;I)V",(void*) osNetworkSystem_acceptSocketImpl                   },
-    { "supportsUrgentDataImpl",            "(Ljava/io/FileDescriptor;)Z",                                              (void*) osNetworkSystem_supportsUrgentDataImpl             },
-    { "sendUrgentDataImpl",                "(Ljava/io/FileDescriptor;B)V",                                             (void*) osNetworkSystem_sendUrgentDataImpl                 },
-    { "connectDatagramImpl2",              "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;)V",                      (void*) osNetworkSystem_connectDatagramImpl2               },
-    { "disconnectDatagramImpl",            "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_disconnectDatagramImpl             },
-    { "peekDatagramImpl",                  "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)I",                       (void*) osNetworkSystem_peekDatagramImpl                   },
-    { "receiveDatagramImpl",               "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I",               (void*) osNetworkSystem_receiveDatagramImpl                },
-    { "receiveDatagramDirectImpl",         "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I",                (void*) osNetworkSystem_receiveDatagramDirectImpl          },
-    { "recvConnectedDatagramImpl",         "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I",               (void*) osNetworkSystem_recvConnectedDatagramImpl          },
-    { "recvConnectedDatagramDirectImpl",   "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I",                (void*) osNetworkSystem_recvConnectedDatagramDirectImpl    },
-    { "sendDatagramImpl",                  "(Ljava/io/FileDescriptor;[BIIIZILjava/net/InetAddress;)I",                 (void*) osNetworkSystem_sendDatagramImpl                   },
-    { "sendDatagramDirectImpl",            "(Ljava/io/FileDescriptor;IIIIZILjava/net/InetAddress;)I",                  (void*) osNetworkSystem_sendDatagramDirectImpl             },
-    { "sendConnectedDatagramImpl",         "(Ljava/io/FileDescriptor;[BIIZ)I",                                         (void*) osNetworkSystem_sendConnectedDatagramImpl          },
-    { "sendConnectedDatagramDirectImpl",   "(Ljava/io/FileDescriptor;IIIZ)I",                                          (void*) osNetworkSystem_sendConnectedDatagramDirectImpl    },
-    { "createServerStreamSocketImpl",      "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createServerStreamSocketImpl       },
-    { "shutdownInputImpl",                 "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_shutdownInputImpl                  },
-    { "shutdownOutputImpl",                "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_shutdownOutputImpl                 },
-    { "sendDatagramImpl2",                 "(Ljava/io/FileDescriptor;[BIIILjava/net/InetAddress;)I",                   (void*) osNetworkSystem_sendDatagramImpl2                  },
-    { "selectImpl",                        "([Ljava/io/FileDescriptor;[Ljava/io/FileDescriptor;II[IJ)Z",               (void*) osNetworkSystem_selectImpl                         },
-    { "getSocketLocalAddressImpl",         "(Ljava/io/FileDescriptor;)Ljava/net/InetAddress;",                         (void*) osNetworkSystem_getSocketLocalAddressImpl          },
-    { "getSocketLocalPortImpl",            "(Ljava/io/FileDescriptor;)I",                                              (void*) osNetworkSystem_getSocketLocalPortImpl             },
-    { "getSocketOptionImpl",               "(Ljava/io/FileDescriptor;I)Ljava/lang/Object;",                            (void*) osNetworkSystem_getSocketOptionImpl                },
-    { "setSocketOptionImpl",               "(Ljava/io/FileDescriptor;ILjava/lang/Object;)V",                           (void*) osNetworkSystem_setSocketOptionImpl                },
-    { "socketCloseImpl",                   "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_socketCloseImpl                    },
-    { "setInetAddressImpl",                "(Ljava/net/InetAddress;[B)V",                                              (void*) osNetworkSystem_setInetAddressImpl                 },
-    { "inheritedChannel",                  "()Ljava/nio/channels/Channel;",                                            (void*) osNetworkSystem_inheritedChannel                   },
-    { "byteArrayToIpString",               "([B)Ljava/lang/String;",                                                   (void*) osNetworkSystem_byteArrayToIpString                },
-    { "ipStringToByteArray",               "(Ljava/lang/String;)[B",                                                   (void*) osNetworkSystem_ipStringToByteArray                },
+    { "accept",                            "(Ljava/io/FileDescriptor;Ljava/net/SocketImpl;Ljava/io/FileDescriptor;I)V",(void*) osNetworkSystem_accept },
+    { "bind",                              "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V",                       (void*) osNetworkSystem_bind },
+    { "byteArrayToIpString",               "([B)Ljava/lang/String;",                                                   (void*) osNetworkSystem_byteArrayToIpString },
+    { "connectDatagram",                   "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;)V",                      (void*) osNetworkSystem_connectDatagram },
+    { "connectStreamWithTimeoutSocket",    "(Ljava/io/FileDescriptor;IIILjava/net/InetAddress;)V",                     (void*) osNetworkSystem_connectStreamWithTimeoutSocket },
+    { "connectWithTimeout",                "(Ljava/io/FileDescriptor;IILjava/net/InetAddress;II[B)I",                  (void*) osNetworkSystem_connectWithTimeout },
+    { "createDatagramSocket",              "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createDatagramSocket },
+    { "createServerStreamSocket",          "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createServerStreamSocket },
+    { "createStreamSocket",                "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_createStreamSocket },
+    { "disconnectDatagram",                "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_disconnectDatagram },
+    { "getSocketLocalAddress",             "(Ljava/io/FileDescriptor;)Ljava/net/InetAddress;",                         (void*) osNetworkSystem_getSocketLocalAddress },
+    { "getSocketLocalPort",                "(Ljava/io/FileDescriptor;)I",                                              (void*) osNetworkSystem_getSocketLocalPort },
+    { "getSocketOption",                   "(Ljava/io/FileDescriptor;I)Ljava/lang/Object;",                            (void*) osNetworkSystem_getSocketOption },
+    { "ipStringToByteArray",               "(Ljava/lang/String;)[B",                                                   (void*) osNetworkSystem_ipStringToByteArray },
+    { "listenStreamSocket",                "(Ljava/io/FileDescriptor;I)V",                                             (void*) osNetworkSystem_listenStreamSocket },
+    { "peekDatagram",                      "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)I",                       (void*) osNetworkSystem_peekDatagram },
+    { "readDirect",                        "(Ljava/io/FileDescriptor;III)I",                                           (void*) osNetworkSystem_readDirect },
+    { "readSocketImpl",                    "(Ljava/io/FileDescriptor;[BIII)I",                                         (void*) osNetworkSystem_readSocketImpl },
+    { "receiveDatagramDirect",             "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I",                (void*) osNetworkSystem_receiveDatagramDirect },
+    { "receiveDatagram",                   "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I",               (void*) osNetworkSystem_receiveDatagram },
+    { "recvConnectedDatagramDirect",       "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;IIIIZ)I",                (void*) osNetworkSystem_recvConnectedDatagramDirect },
+    { "recvConnectedDatagram",             "(Ljava/io/FileDescriptor;Ljava/net/DatagramPacket;[BIIIZ)I",               (void*) osNetworkSystem_recvConnectedDatagram },
+    { "selectImpl",                        "([Ljava/io/FileDescriptor;[Ljava/io/FileDescriptor;II[IJ)Z",               (void*) osNetworkSystem_selectImpl },
+    { "sendConnectedDatagramDirect",       "(Ljava/io/FileDescriptor;IIIZ)I",                                          (void*) osNetworkSystem_sendConnectedDatagramDirect },
+    { "sendConnectedDatagram",             "(Ljava/io/FileDescriptor;[BIIZ)I",                                         (void*) osNetworkSystem_sendConnectedDatagram },
+    { "sendDatagramDirect",                "(Ljava/io/FileDescriptor;IIIIZILjava/net/InetAddress;)I",                  (void*) osNetworkSystem_sendDatagramDirect },
+    { "sendDatagram",                      "(Ljava/io/FileDescriptor;[BIIIZILjava/net/InetAddress;)I",                 (void*) osNetworkSystem_sendDatagram },
+    { "sendDatagram2",                     "(Ljava/io/FileDescriptor;[BIIILjava/net/InetAddress;)I",                   (void*) osNetworkSystem_sendDatagram2 },
+    { "sendUrgentData",                    "(Ljava/io/FileDescriptor;B)V",                                             (void*) osNetworkSystem_sendUrgentData },
+    { "setInetAddress",                    "(Ljava/net/InetAddress;[B)V",                                              (void*) osNetworkSystem_setInetAddress },
+    { "setNonBlocking",                    "(Ljava/io/FileDescriptor;Z)V",                                             (void*) osNetworkSystem_setNonBlocking },
+    { "setSocketOption",                   "(Ljava/io/FileDescriptor;ILjava/lang/Object;)V",                           (void*) osNetworkSystem_setSocketOption },
+    { "shutdownInput",                     "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_shutdownInput },
+    { "shutdownOutput",                    "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_shutdownOutput },
+    { "socketClose",                       "(Ljava/io/FileDescriptor;)V",                                              (void*) osNetworkSystem_socketClose },
+    { "supportsUrgentData",                "(Ljava/io/FileDescriptor;)Z",                                              (void*) osNetworkSystem_supportsUrgentData },
+    { "writeDirect",                       "(Ljava/io/FileDescriptor;III)I",                                           (void*) osNetworkSystem_writeDirect },
+    { "write",                             "(Ljava/io/FileDescriptor;[BII)I",                                          (void*) osNetworkSystem_write },
 };
 
 int register_org_apache_harmony_luni_platform_OSNetworkSystem(JNIEnv* env) {
diff --git a/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java b/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
index 22d1b4a..3aa063c 100644
--- a/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
+++ b/nio/src/main/java/org/apache/harmony/nio/internal/ServerSocketChannelImpl.java
@@ -46,15 +46,6 @@
 public class ServerSocketChannelImpl extends ServerSocketChannel implements
         FileDescriptorHandler {
 
-    // status un-init, not initialized.
-    private static final int SERVER_STATUS_UNINIT = -1;
-
-    // status after open and before closed.
-    private static final int SERVER_STATUS_OPEN = 0;
-
-    // status closed.
-    private static final int SERVER_STATUS_CLOSED = 1;
-
     // The fd to interact with native code
     private final FileDescriptor fd;
 
@@ -63,8 +54,6 @@
 
     private final SocketImpl impl;
 
-    int status = SERVER_STATUS_UNINIT;
-
     // whether the socket is bound
     boolean isBound = false;
 
@@ -77,7 +66,6 @@
      */
     public ServerSocketChannelImpl(SelectorProvider sp) throws IOException {
         super(sp);
-        status = SERVER_STATUS_OPEN;
         fd = new FileDescriptor();
         Platform.getNetworkSystem().createStreamSocket(fd,
                 NetUtil.preferIPv4Stack());
@@ -89,7 +77,6 @@
     @SuppressWarnings("unused")
     private ServerSocketChannelImpl() throws IOException {
         super(SelectorProvider.provider());
-        status = SERVER_STATUS_OPEN;
         fd = new FileDescriptor();
         impl = new PlainServerSocketImpl(fd);
         socket = new ServerSocketAdapter(impl, this);
@@ -175,7 +162,6 @@
      * @see java.nio.channels.spi.AbstractSelectableChannel#implCloseSelectableChannel()
      */
     synchronized protected void implCloseSelectableChannel() throws IOException {
-        status = SERVER_STATUS_CLOSED;
         if (!socket.isClosed()) {
             socket.close();
         }
@@ -296,7 +282,6 @@
                 } else {
                     super.close();
                 }
-                channelImpl.status = SERVER_STATUS_CLOSED;
             }
         }
     }
diff --git a/security/src/main/files/certimport.sh b/security/src/main/files/certimport.sh
index ca36a70..1f489e6 100755
--- a/security/src/main/files/certimport.sh
+++ b/security/src/main/files/certimport.sh
@@ -1,6 +1,39 @@
 #!/bin/bash
+#
+# Copyright (C) 2009 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.
+
+#
+# certimport.sh recreates the cacerts.bks file from the x509 CA
+# certificates in the cacerts directory.
+# 
+# By convention, the filenames in the cacerts directory are in the
+# format of <hash>.<n> where "hash" is the subject hash produced by:
+# 
+#     openssl x509 -subject_hash -in filename
+#
+# and the "n" is the the depth of the certificate along a chain, i.e.
+# .0 for roots, .1 for an intermediate one level deep, etc.
+#
+# The filename itself is not important, and is around just for convention sake.
+#
+# usage is simply running ./certimport.sh from the scripts directory
+# 
 # java version >= 1.6 is required for this script.
+# 
 # This script was tested to work with bouncycastle 1.32.
+#
 
 set -x
 set -e
diff --git a/tools/runner/java/dalvik/runner/CaliperFinder.java b/tools/runner/java/dalvik/runner/CaliperFinder.java
index 3609471..1facf88 100644
--- a/tools/runner/java/dalvik/runner/CaliperFinder.java
+++ b/tools/runner/java/dalvik/runner/CaliperFinder.java
@@ -25,7 +25,7 @@
 class CaliperFinder extends NamingPatternCodeFinder {
 
     @Override protected boolean matches(File file) {
-        return file.getName().endsWith("Benchmark.java");
+        return super.matches(file) && file.getName().endsWith("Benchmark.java");
     }
 
     @Override protected String testName(File file) {
diff --git a/tools/runner/java/dalvik/runner/JUnitFinder.java b/tools/runner/java/dalvik/runner/JUnitFinder.java
index 131a8cf..ba80ac1 100644
--- a/tools/runner/java/dalvik/runner/JUnitFinder.java
+++ b/tools/runner/java/dalvik/runner/JUnitFinder.java
@@ -24,7 +24,7 @@
 class JUnitFinder extends NamingPatternCodeFinder {
 
     @Override protected boolean matches(File file) {
-        return file.getName().endsWith("Test.java");
+        return super.matches(file) && file.getName().endsWith("Test.java");
     }
 
     // TODO: try to get names for each method?
diff --git a/tools/runner/java/dalvik/runner/MainFinder.java b/tools/runner/java/dalvik/runner/MainFinder.java
index 282969f..0923f53 100644
--- a/tools/runner/java/dalvik/runner/MainFinder.java
+++ b/tools/runner/java/dalvik/runner/MainFinder.java
@@ -23,10 +23,6 @@
  */
 class MainFinder extends NamingPatternCodeFinder {
 
-    @Override protected boolean matches(File file) {
-        return file.getName().endsWith(".java");
-    }
-
     @Override protected String testName(File file) {
         return "main";
     }
diff --git a/tools/runner/java/dalvik/runner/NamingPatternCodeFinder.java b/tools/runner/java/dalvik/runner/NamingPatternCodeFinder.java
index 19c9df2..ae8309f 100644
--- a/tools/runner/java/dalvik/runner/NamingPatternCodeFinder.java
+++ b/tools/runner/java/dalvik/runner/NamingPatternCodeFinder.java
@@ -44,7 +44,8 @@
      * Returns true if {@code file} contains a test class of this type.
      */
     protected boolean matches(File file) {
-        return file.getName().endsWith(".java");
+        return (!file.getName().startsWith(".")
+                && file.getName().endsWith(".java"));
     }
 
     protected abstract String testName(File file);
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
index 56a4817..c601de6 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/AttrImpl.java
@@ -36,49 +36,19 @@
 
     // Maintained by ElementImpl.
     ElementImpl ownerElement;
-
-    private boolean namespaceAware;
-
     boolean isId;
-    
-    private String namespaceURI;
 
-    private String localName;
+    boolean namespaceAware;
+    String namespaceURI;
+    String prefix;
+    String localName;
 
-    private String prefix;
-    
     private String value;
 
     AttrImpl(DocumentImpl document, String namespaceURI, String qualifiedName) {
         super(document);
 
-        namespaceAware = true;
-        this.namespaceURI = namespaceURI;
-
-        if (qualifiedName == null || "".equals(qualifiedName)) {
-            throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
-        }
-        
-        int prefixSeparator = qualifiedName.lastIndexOf(":");
-        if (prefixSeparator != -1) {
-            setPrefix(qualifiedName.substring(0, prefixSeparator));
-            qualifiedName = qualifiedName.substring(prefixSeparator + 1);
-        }
-
-        localName = qualifiedName;
-        
-        if ("".equals(localName)) {
-            throw new DOMException(DOMException.NAMESPACE_ERR, localName);
-        }
-        
-        if ("xmlns".equals(localName) && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI)) {
-            throw new DOMException(DOMException.NAMESPACE_ERR, localName);
-        }
-            
-        if (!DocumentImpl.isXMLIdentifier(localName)) {
-            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, localName);
-        }
-            
+        setNameNS(this, namespaceURI, qualifiedName);
         value = "";
     }
 
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
index b662a13..3106c3f 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DOMImplementationImpl.java
@@ -85,6 +85,6 @@
     }
 
     public Object getFeature(String feature, String version) {
-        throw new UnsupportedOperationException(); // TODO
+        return hasFeature(feature, version) ? this : null;
     }
 }
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
index c677e58..56283a8 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/DocumentImpl.java
@@ -299,6 +299,16 @@
         }
     }
 
+    public Node renameNode(Node node, String namespaceURI, String qualifiedName) {
+        if (node.getOwnerDocument() != this) {
+            throw new DOMException(DOMException.WRONG_DOCUMENT_ERR, null);
+        }
+
+        setNameNS((NodeImpl) node, namespaceURI, qualifiedName);
+        notifyUserDataHandlers(UserDataHandler.NODE_RENAMED, node, null);
+        return node;
+    }
+
     public AttrImpl createAttribute(String name) {
         return new AttrImpl(this, name);
     }
@@ -467,11 +477,6 @@
         ((DOMConfigurationImpl) getDomConfig()).normalize(root);
     }
 
-    public Node renameNode(Node n, String namespaceURI, String qualifiedName) {
-        // TODO: callback the UserDataHandler with a NODE_RENAMED event
-        throw new UnsupportedOperationException(); // TODO
-    }
-
     /**
      * Returns a map with the user data objects attached to the specified node.
      * This map is readable and writable.
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
index c3e5a2e..cbc4570 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/ElementImpl.java
@@ -39,37 +39,16 @@
  */
 public class ElementImpl extends InnerNodeImpl implements Element {
 
-    private boolean namespaceAware;
-    
-    private String namespaceURI;
-
-    private String prefix;
-    
-    private String localName;
+    boolean namespaceAware;
+    String namespaceURI;
+    String prefix;
+    String localName;
 
     private List<AttrImpl> attributes = new ArrayList<AttrImpl>();
 
     ElementImpl(DocumentImpl document, String namespaceURI, String qualifiedName) {
         super(document);
-
-        this.namespaceAware = true;
-        this.namespaceURI = namespaceURI;
-
-        if (qualifiedName == null || "".equals(qualifiedName)) {
-            throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
-        }
-        
-        int p = qualifiedName.lastIndexOf(":");
-        if (p != -1) {
-            setPrefix(qualifiedName.substring(0, p));
-            qualifiedName = qualifiedName.substring(p + 1);
-        }
-        
-        if (!DocumentImpl.isXMLIdentifier(qualifiedName)) {
-            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName);
-        }
-            
-        this.localName = qualifiedName;
+        setNameNS(this, namespaceURI, qualifiedName);
     }
 
     ElementImpl(DocumentImpl document, String name) {
@@ -383,7 +362,7 @@
     public void setPrefix(String prefix) {
         this.prefix = validatePrefix(prefix, namespaceAware, namespaceURI);
     }
-    
+
     public class ElementAttrNamedNodeMapImpl implements NamedNodeMap {
 
         public int getLength() {
diff --git a/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
index 359a042..8beb18c 100644
--- a/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
+++ b/xml/src/main/java/org/apache/harmony/xml/dom/NodeImpl.java
@@ -198,7 +198,7 @@
      * @param namespaceAware whether this node is namespace aware
      * @param namespaceURI this node's namespace URI
      */
-    protected String validatePrefix(String prefix, boolean namespaceAware, String namespaceURI) {
+    static String validatePrefix(String prefix, boolean namespaceAware, String namespaceURI) {
         if (!namespaceAware) {
             throw new DOMException(DOMException.NAMESPACE_ERR, prefix);
         }
@@ -216,6 +216,58 @@
     }
 
     /**
+     * Sets the element or attribute node to be namespace-aware and assign it
+     * the specified name and namespace URI.
+     *
+     * @param node an AttrImpl or ElementImpl node.
+     * @param namespaceURI this node's namespace URI. May be null.
+     * @param qualifiedName a possibly-prefixed name like "img" or "html:img".
+     */
+    static void setNameNS(NodeImpl node, String namespaceURI, String qualifiedName) {
+        if (qualifiedName == null) {
+            throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+        }
+
+        String prefix = null;
+        int p = qualifiedName.lastIndexOf(":");
+        if (p != -1) {
+            prefix = validatePrefix(qualifiedName.substring(0, p), true, namespaceURI);
+            qualifiedName = qualifiedName.substring(p + 1);
+        }
+
+        if (!DocumentImpl.isXMLIdentifier(qualifiedName)) {
+            throw new DOMException(DOMException.INVALID_CHARACTER_ERR, qualifiedName);
+        }
+
+        switch (node.getNodeType()) {
+            case ATTRIBUTE_NODE:
+                if ("xmlns".equals(qualifiedName)
+                        && !"http://www.w3.org/2000/xmlns/".equals(namespaceURI)) {
+                    throw new DOMException(DOMException.NAMESPACE_ERR, qualifiedName);
+                }
+
+                AttrImpl attr = (AttrImpl) node;
+                attr.namespaceAware = true;
+                attr.namespaceURI = namespaceURI;
+                attr.prefix = prefix;
+                attr.localName = qualifiedName;
+                break;
+
+            case ELEMENT_NODE:
+                ElementImpl element = (ElementImpl) node;
+                element.namespaceAware = true;
+                element.namespaceURI = namespaceURI;
+                element.prefix = prefix;
+                element.localName = qualifiedName;
+                break;
+
+            default:
+                throw new DOMException(DOMException.NOT_SUPPORTED_ERR,
+                        "Cannot rename nodes of type " + node.getNodeType());
+        }
+    }
+
+    /**
      * Checks whether a required string matches an actual string. This utility
      * method is used for comparing namespaces and such. It takes into account
      * null arguments and the "*" special case.
diff --git a/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java b/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java
index 3f0d2cb..0438e98 100644
--- a/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java
+++ b/xml/src/test/java/org/apache/harmony/xml/XsltXPathConformanceTestSuite.java
@@ -73,7 +73,7 @@
  *         suite zip file from the OASIS project site.</li>
  *     <li>Unzip.
  *     <li>Copy the files to a device: <code>adb shell mkdir /data/oasis ;
- *         adb push ./XSLT-Conformance-TC /data/oasis</code>.
+ *         adb push ./XSLT-Conformance-TC/data/oasis</code>.
  *     <li>Invoke this class' main method, passing the on-device path to the test
  *         suite's <code>catalog.xml</code> file as an argument.
  * </ul>
diff --git a/xml/src/test/java/tests/xml/DomTest.java b/xml/src/test/java/tests/xml/DomTest.java
index 3bafb78..2f364d0 100644
--- a/xml/src/test/java/tests/xml/DomTest.java
+++ b/xml/src/test/java/tests/xml/DomTest.java
@@ -61,6 +61,7 @@
 import static org.w3c.dom.UserDataHandler.NODE_ADOPTED;
 import static org.w3c.dom.UserDataHandler.NODE_CLONED;
 import static org.w3c.dom.UserDataHandler.NODE_IMPORTED;
+import static org.w3c.dom.UserDataHandler.NODE_RENAMED;
 
 /**
  * Construct a DOM and then interrogate it.
@@ -512,25 +513,25 @@
     }
 
     public void testCoreFeature() {
-        assertTrue(domImplementation.hasFeature("Core", null));
-        assertTrue(domImplementation.hasFeature("Core", ""));
-        assertTrue(domImplementation.hasFeature("Core", "1.0"));
-        assertTrue(domImplementation.hasFeature("Core", "2.0"));
-        assertTrue(domImplementation.hasFeature("Core", "3.0"));
-        assertTrue(domImplementation.hasFeature("CORE", "3.0"));
-        assertTrue(domImplementation.hasFeature("+Core", "3.0"));
-        assertFalse(domImplementation.hasFeature("Core", "4.0"));
+        assertFeature("Core", null);
+        assertFeature("Core", "");
+        assertFeature("Core", "1.0");
+        assertFeature("Core", "2.0");
+        assertFeature("Core", "3.0");
+        assertFeature("CORE", "3.0");
+        assertFeature("+Core", "3.0");
+        assertNoFeature("Core", "4.0");
     }
 
     public void testXmlFeature() {
-        assertTrue(domImplementation.hasFeature("XML", null));
-        assertTrue(domImplementation.hasFeature("XML", ""));
-        assertTrue(domImplementation.hasFeature("XML", "1.0"));
-        assertTrue(domImplementation.hasFeature("XML", "2.0"));
-        assertTrue(domImplementation.hasFeature("XML", "3.0"));
-        assertTrue(domImplementation.hasFeature("Xml", "3.0"));
-        assertTrue(domImplementation.hasFeature("+XML", "3.0"));
-        assertFalse(domImplementation.hasFeature("XML", "4.0"));
+        assertFeature("XML", null);
+        assertFeature("XML", "");
+        assertFeature("XML", "1.0");
+        assertFeature("XML", "2.0");
+        assertFeature("XML", "3.0");
+        assertFeature("Xml", "3.0");
+        assertFeature("+XML", "3.0");
+        assertNoFeature("XML", "4.0");
     }
 
     /**
@@ -538,26 +539,35 @@
      * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Document3-version
      */
     public void testXmlVersionFeature() {
-        String message = "This implementation does not support the XMLVersion feature";
-        assertTrue(message, domImplementation.hasFeature("XMLVersion", null));
-        assertTrue(message, domImplementation.hasFeature("XMLVersion", ""));
-        assertTrue(message, domImplementation.hasFeature("XMLVersion", "1.0"));
-        assertTrue(message, domImplementation.hasFeature("XMLVersion", "1.1"));
-        assertTrue(message, domImplementation.hasFeature("XMLVERSION", "1.1"));
-        assertTrue(message, domImplementation.hasFeature("+XMLVersion", "1.1"));
-        assertFalse(domImplementation.hasFeature("XMLVersion", "1.2"));
-        assertFalse(domImplementation.hasFeature("XMLVersion", "2.0"));
-        assertFalse(domImplementation.hasFeature("XMLVersion", "2.0"));
+        assertFeature("XMLVersion", null);
+        assertFeature("XMLVersion", "");
+        assertFeature("XMLVersion", "1.0");
+        assertFeature("XMLVersion", "1.1");
+        assertFeature("XMLVERSION", "1.1");
+        assertFeature("+XMLVersion", "1.1");
+        assertNoFeature("XMLVersion", "1.2");
+        assertNoFeature("XMLVersion", "2.0");
+        assertNoFeature("XMLVersion", "2.0");
     }
 
     public void testLsFeature() {
-        assertTrue("This implementation does not support the LS feature",
-                domImplementation.hasFeature("LS", "3.0"));
+        assertFeature("LS", "3.0");
     }
 
     public void testElementTraversalFeature() {
-        assertTrue("This implementation does not support the ElementTraversal feature",
-                domImplementation.hasFeature("ElementTraversal", "1.0"));
+        assertFeature("ElementTraversal", "1.0");
+    }
+
+    private void assertFeature(String feature, String version) {
+        String message = "This implementation is expected to support "
+                + feature + " v. " + version + " but does not.";
+        assertTrue(message, domImplementation.hasFeature(feature, version));
+        assertNotNull(message, domImplementation.getFeature(feature, version));
+    }
+
+    private void assertNoFeature(String feature, String version) {
+        assertFalse(domImplementation.hasFeature(feature, version));
+        assertNull(domImplementation.getFeature(feature, version));
     }
 
     public void testIsSupported() {
@@ -1189,6 +1199,118 @@
         assertFalse(typeInfo.isDerivedFrom("x", "y", TypeInfo.DERIVATION_UNION));
     }
 
+    public void testRenameElement() {
+        document.renameNode(description, null, "desc");
+        assertEquals("desc", description.getTagName());
+        assertEquals("desc", description.getLocalName());
+        assertEquals(null, description.getPrefix());
+        assertEquals(null, description.getNamespaceURI());
+    }
+
+    public void testRenameElementWithPrefix() {
+        try {
+            document.renameNode(description, null, "a:desc");
+            fail();
+        } catch (DOMException e) {
+        }
+    }
+
+    public void testRenameElementWithNamespace() {
+        document.renameNode(description, "http://sales", "desc");
+        assertEquals("desc", description.getTagName());
+        assertEquals("desc", description.getLocalName());
+        assertEquals(null, description.getPrefix());
+        assertEquals("http://sales", description.getNamespaceURI());
+    }
+
+    public void testRenameElementWithPrefixAndNamespace() {
+        document.renameNode(description, "http://sales", "a:desc");
+        assertEquals("a:desc", description.getTagName());
+        assertEquals("desc", description.getLocalName());
+        assertEquals("a", description.getPrefix());
+        assertEquals("http://sales", description.getNamespaceURI());
+    }
+
+    public void testRenameAttribute() {
+        document.renameNode(deluxe, null, "special");
+        assertEquals("special", deluxe.getName());
+        assertEquals("special", deluxe.getLocalName());
+        assertEquals(null, deluxe.getPrefix());
+        assertEquals(null, deluxe.getNamespaceURI());
+    }
+
+    public void testRenameAttributeWithPrefix() {
+        try {
+            document.renameNode(deluxe, null, "a:special");
+            fail();
+        } catch (DOMException e) {
+        }
+    }
+
+    public void testRenameAttributeWithNamespace() {
+        document.renameNode(deluxe, "http://sales", "special");
+        assertEquals("special", deluxe.getName());
+        assertEquals("special", deluxe.getLocalName());
+        assertEquals(null, deluxe.getPrefix());
+        assertEquals("http://sales", deluxe.getNamespaceURI());
+    }
+
+    public void testRenameAttributeWithPrefixAndNamespace() {
+        document.renameNode(deluxe, "http://sales", "a:special");
+        assertEquals("a:special", deluxe.getName());
+        assertEquals("special", deluxe.getLocalName());
+        assertEquals("a", deluxe.getPrefix());
+        assertEquals("http://sales", deluxe.getNamespaceURI());
+    }
+
+    public void testUserDataHandlerNotifiedOfRenames() {
+        RecordingHandler handler = new RecordingHandler();
+        description.setUserData("a", "apple", handler);
+        deluxe.setUserData("b", "banana", handler);
+        standard.setUserData("c", "cat", handler);
+
+        document.renameNode(deluxe, null, "special");
+        document.renameNode(description, null, "desc");
+
+        Set<String> expected = new HashSet<String>();
+        expected.add(notification(NODE_RENAMED, "a", "apple", description, null));
+        expected.add(notification(NODE_RENAMED, "b", "banana", deluxe, null));
+        assertEquals(expected, handler.calls);
+    }
+
+    public void testRenameToInvalid() {
+        try {
+            document.renameNode(description, null, "xmlns:foo");
+            fail();
+        } catch (DOMException e) {
+        }
+        try {
+            document.renameNode(description, null, "xml:foo");
+            fail();
+        } catch (DOMException e) {
+        }
+        try {
+            document.renameNode(deluxe, null, "xmlns");
+            fail();
+        } catch (DOMException e) {
+        }
+    }
+
+    public void testRenameNodeOtherThanElementOrAttribute() {
+        for (Node node : allNodes) {
+            if (node.getNodeType() == Node.ATTRIBUTE_NODE
+                    || node.getNodeType() == Node.ELEMENT_NODE) {
+                continue;
+            }
+
+            try {
+                document.renameNode(node, null, "foo");
+                fail();
+            } catch (DOMException e) {
+            }
+        }
+    }
+
     private class RecordingHandler implements UserDataHandler {
         final Set<String> calls = new HashSet<String>();
         public void handle(short operation, String key, Object data, Node src, Node dst) {